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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 11238016: Consolidated all the key store/load classes in the Hydrogen and Lithium (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Last batch of comment response, formatting issues. Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/elements-kind.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2900 matching lines...) Expand 10 before | Expand all | Expand 10 after
2911 Register index = ToRegister(instr->index()); 2911 Register index = ToRegister(instr->index());
2912 Register result = ToRegister(instr->result()); 2912 Register result = ToRegister(instr->result());
2913 // There are two words between the frame pointer and the last argument. 2913 // There are two words between the frame pointer and the last argument.
2914 // Subtracting from length accounts for one of them add one more. 2914 // Subtracting from length accounts for one of them add one more.
2915 __ sub(length, length, index); 2915 __ sub(length, length, index);
2916 __ add(length, length, Operand(1)); 2916 __ add(length, length, Operand(1));
2917 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); 2917 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
2918 } 2918 }
2919 2919
2920 2920
2921 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2921 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2922 Register elements = ToRegister(instr->elements()); 2922 Register external_pointer = ToRegister(instr->elements());
2923 Register result = ToRegister(instr->result()); 2923 Register key = no_reg;
2924 Register scratch = scratch0(); 2924 ElementsKind elements_kind = instr->elements_kind();
2925 Register store_base = scratch; 2925 bool key_is_constant = instr->key()->IsConstantOperand();
2926 int offset = 0; 2926 int constant_key = 0;
2927 if (key_is_constant) {
2928 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2929 if (constant_key & 0xF0000000) {
2930 Abort("array index constant value too big.");
2931 }
2932 } else {
2933 key = ToRegister(instr->key());
2934 }
2935 int element_size_shift = ElementsKindToShiftSize(elements_kind);
2936 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2937 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2938 int additional_offset = instr->additional_index() << element_size_shift;
2927 2939
2928 if (instr->key()->IsConstantOperand()) { 2940 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2929 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 2941 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2930 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + 2942 CpuFeatures::Scope scope(VFP3);
2931 instr->additional_index()); 2943 DwVfpRegister result = ToDoubleRegister(instr->result());
2932 store_base = elements; 2944 Operand operand = key_is_constant
2945 ? Operand(constant_key << element_size_shift)
2946 : Operand(key, LSL, shift_size);
2947 __ add(scratch0(), external_pointer, operand);
2948 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2949 __ vldr(result.low(), scratch0(), additional_offset);
2950 __ vcvt_f64_f32(result, result.low());
2951 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2952 __ vldr(result, scratch0(), additional_offset);
2953 }
2933 } else { 2954 } else {
2934 Register key = EmitLoadRegister(instr->key(), scratch0()); 2955 Register result = ToRegister(instr->result());
2935 // Even though the HLoadKeyedFastElement instruction forces the input 2956 MemOperand mem_operand = PrepareKeyedOperand(
2936 // representation for the key to be an integer, the input gets replaced 2957 key, external_pointer, key_is_constant, constant_key,
2937 // during bound check elimination with the index argument to the bounds 2958 element_size_shift, shift_size,
2938 // check, which can be tagged, so that case must be handled here, too. 2959 instr->additional_index(), additional_offset);
2939 if (instr->hydrogen()->key()->representation().IsTagged()) { 2960 switch (elements_kind) {
2940 __ add(scratch, elements, 2961 case EXTERNAL_BYTE_ELEMENTS:
2941 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); 2962 __ ldrsb(result, mem_operand);
2942 } else { 2963 break;
2943 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2964 case EXTERNAL_PIXEL_ELEMENTS:
2944 } 2965 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2945 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); 2966 __ ldrb(result, mem_operand);
2946 } 2967 break;
2947 __ ldr(result, FieldMemOperand(store_base, offset)); 2968 case EXTERNAL_SHORT_ELEMENTS:
2948 2969 __ ldrsh(result, mem_operand);
2949 // Check for the hole value. 2970 break;
2950 if (instr->hydrogen()->RequiresHoleCheck()) { 2971 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2951 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 2972 __ ldrh(result, mem_operand);
2952 __ tst(result, Operand(kSmiTagMask)); 2973 break;
2953 DeoptimizeIf(ne, instr->environment()); 2974 case EXTERNAL_INT_ELEMENTS:
2954 } else { 2975 __ ldr(result, mem_operand);
2955 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2976 break;
2956 __ cmp(result, scratch); 2977 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2957 DeoptimizeIf(eq, instr->environment()); 2978 __ ldr(result, mem_operand);
2979 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2980 __ cmp(result, Operand(0x80000000));
2981 DeoptimizeIf(cs, instr->environment());
2982 }
2983 break;
2984 case EXTERNAL_FLOAT_ELEMENTS:
2985 case EXTERNAL_DOUBLE_ELEMENTS:
2986 case FAST_HOLEY_DOUBLE_ELEMENTS:
2987 case FAST_HOLEY_ELEMENTS:
2988 case FAST_HOLEY_SMI_ELEMENTS:
2989 case FAST_DOUBLE_ELEMENTS:
2990 case FAST_ELEMENTS:
2991 case FAST_SMI_ELEMENTS:
2992 case DICTIONARY_ELEMENTS:
2993 case NON_STRICT_ARGUMENTS_ELEMENTS:
2994 UNREACHABLE();
2995 break;
2958 } 2996 }
2959 } 2997 }
2960 } 2998 }
2961 2999
2962 3000
2963 void LCodeGen::DoLoadKeyedFastDoubleElement( 3001 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2964 LLoadKeyedFastDoubleElement* instr) {
2965 Register elements = ToRegister(instr->elements()); 3002 Register elements = ToRegister(instr->elements());
2966 bool key_is_constant = instr->key()->IsConstantOperand(); 3003 bool key_is_constant = instr->key()->IsConstantOperand();
2967 Register key = no_reg; 3004 Register key = no_reg;
2968 DwVfpRegister result = ToDoubleRegister(instr->result()); 3005 DwVfpRegister result = ToDoubleRegister(instr->result());
2969 Register scratch = scratch0(); 3006 Register scratch = scratch0();
2970 3007
2971 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 3008 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
2972 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) 3009 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2973 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3010 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2974 int constant_key = 0; 3011 int constant_key = 0;
(...skipping 21 matching lines...) Expand all
2996 if (instr->hydrogen()->RequiresHoleCheck()) { 3033 if (instr->hydrogen()->RequiresHoleCheck()) {
2997 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 3034 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2998 __ cmp(scratch, Operand(kHoleNanUpper32)); 3035 __ cmp(scratch, Operand(kHoleNanUpper32));
2999 DeoptimizeIf(eq, instr->environment()); 3036 DeoptimizeIf(eq, instr->environment());
3000 } 3037 }
3001 3038
3002 __ vldr(result, elements, 0); 3039 __ vldr(result, elements, 0);
3003 } 3040 }
3004 3041
3005 3042
3043 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3044 Register elements = ToRegister(instr->elements());
3045 Register result = ToRegister(instr->result());
3046 Register scratch = scratch0();
3047 Register store_base = scratch;
3048 int offset = 0;
3049
3050 if (instr->key()->IsConstantOperand()) {
3051 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3052 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
3053 instr->additional_index());
3054 store_base = elements;
3055 } else {
3056 Register key = EmitLoadRegister(instr->key(), scratch0());
3057 // Even though the HLoadKeyed instruction forces the input
3058 // representation for the key to be an integer, the input gets replaced
3059 // during bound check elimination with the index argument to the bounds
3060 // check, which can be tagged, so that case must be handled here, too.
3061 if (instr->hydrogen()->key()->representation().IsTagged()) {
3062 __ add(scratch, elements,
3063 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
3064 } else {
3065 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
3066 }
3067 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3068 }
3069 __ ldr(result, FieldMemOperand(store_base, offset));
3070
3071 // Check for the hole value.
3072 if (instr->hydrogen()->RequiresHoleCheck()) {
3073 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
3074 __ tst(result, Operand(kSmiTagMask));
3075 DeoptimizeIf(ne, instr->environment());
3076 } else {
3077 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3078 __ cmp(result, scratch);
3079 DeoptimizeIf(eq, instr->environment());
3080 }
3081 }
3082 }
3083
3084
3085 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
3086 if (instr->is_external()) {
3087 DoLoadKeyedExternalArray(instr);
3088 } else if (instr->hydrogen()->representation().IsDouble()) {
3089 DoLoadKeyedFixedDoubleArray(instr);
3090 } else {
3091 DoLoadKeyedFixedArray(instr);
3092 }
3093 }
3094
3095
3006 MemOperand LCodeGen::PrepareKeyedOperand(Register key, 3096 MemOperand LCodeGen::PrepareKeyedOperand(Register key,
3007 Register base, 3097 Register base,
3008 bool key_is_constant, 3098 bool key_is_constant,
3009 int constant_key, 3099 int constant_key,
3010 int element_size, 3100 int element_size,
3011 int shift_size, 3101 int shift_size,
3012 int additional_index, 3102 int additional_index,
3013 int additional_offset) { 3103 int additional_offset) {
3014 if (additional_index != 0 && !key_is_constant) { 3104 if (additional_index != 0 && !key_is_constant) {
3015 additional_index *= 1 << (element_size - shift_size); 3105 additional_index *= 1 << (element_size - shift_size);
(...skipping 16 matching lines...) Expand all
3032 3122
3033 if (shift_size >= 0) { 3123 if (shift_size >= 0) {
3034 return MemOperand(base, scratch0(), LSL, shift_size); 3124 return MemOperand(base, scratch0(), LSL, shift_size);
3035 } else { 3125 } else {
3036 ASSERT_EQ(-1, shift_size); 3126 ASSERT_EQ(-1, shift_size);
3037 return MemOperand(base, scratch0(), LSR, 1); 3127 return MemOperand(base, scratch0(), LSR, 1);
3038 } 3128 }
3039 } 3129 }
3040 3130
3041 3131
3042 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
3043 LLoadKeyedSpecializedArrayElement* instr) {
3044 Register external_pointer = ToRegister(instr->external_pointer());
3045 Register key = no_reg;
3046 ElementsKind elements_kind = instr->elements_kind();
3047 bool key_is_constant = instr->key()->IsConstantOperand();
3048 int constant_key = 0;
3049 if (key_is_constant) {
3050 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3051 if (constant_key & 0xF0000000) {
3052 Abort("array index constant value too big.");
3053 }
3054 } else {
3055 key = ToRegister(instr->key());
3056 }
3057 int element_size_shift = ElementsKindToShiftSize(elements_kind);
3058 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3059 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3060 int additional_offset = instr->additional_index() << element_size_shift;
3061
3062 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3063 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3064 CpuFeatures::Scope scope(VFP3);
3065 DwVfpRegister result = ToDoubleRegister(instr->result());
3066 Operand operand = key_is_constant
3067 ? Operand(constant_key << element_size_shift)
3068 : Operand(key, LSL, shift_size);
3069 __ add(scratch0(), external_pointer, operand);
3070 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3071 __ vldr(result.low(), scratch0(), additional_offset);
3072 __ vcvt_f64_f32(result, result.low());
3073 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3074 __ vldr(result, scratch0(), additional_offset);
3075 }
3076 } else {
3077 Register result = ToRegister(instr->result());
3078 MemOperand mem_operand = PrepareKeyedOperand(
3079 key, external_pointer, key_is_constant, constant_key,
3080 element_size_shift, shift_size,
3081 instr->additional_index(), additional_offset);
3082 switch (elements_kind) {
3083 case EXTERNAL_BYTE_ELEMENTS:
3084 __ ldrsb(result, mem_operand);
3085 break;
3086 case EXTERNAL_PIXEL_ELEMENTS:
3087 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3088 __ ldrb(result, mem_operand);
3089 break;
3090 case EXTERNAL_SHORT_ELEMENTS:
3091 __ ldrsh(result, mem_operand);
3092 break;
3093 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3094 __ ldrh(result, mem_operand);
3095 break;
3096 case EXTERNAL_INT_ELEMENTS:
3097 __ ldr(result, mem_operand);
3098 break;
3099 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3100 __ ldr(result, mem_operand);
3101 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3102 __ cmp(result, Operand(0x80000000));
3103 DeoptimizeIf(cs, instr->environment());
3104 }
3105 break;
3106 case EXTERNAL_FLOAT_ELEMENTS:
3107 case EXTERNAL_DOUBLE_ELEMENTS:
3108 case FAST_HOLEY_DOUBLE_ELEMENTS:
3109 case FAST_HOLEY_ELEMENTS:
3110 case FAST_HOLEY_SMI_ELEMENTS:
3111 case FAST_DOUBLE_ELEMENTS:
3112 case FAST_ELEMENTS:
3113 case FAST_SMI_ELEMENTS:
3114 case DICTIONARY_ELEMENTS:
3115 case NON_STRICT_ARGUMENTS_ELEMENTS:
3116 UNREACHABLE();
3117 break;
3118 }
3119 }
3120 }
3121
3122
3123 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 3132 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
3124 ASSERT(ToRegister(instr->object()).is(r1)); 3133 ASSERT(ToRegister(instr->object()).is(r1));
3125 ASSERT(ToRegister(instr->key()).is(r0)); 3134 ASSERT(ToRegister(instr->key()).is(r0));
3126 3135
3127 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 3136 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
3128 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); 3137 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
3129 } 3138 }
3130 3139
3131 3140
3132 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 3141 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
3993 __ mov(ip, Operand(constant_index)); 4002 __ mov(ip, Operand(constant_index));
3994 } 4003 }
3995 __ cmp(ip, ToRegister(instr->length())); 4004 __ cmp(ip, ToRegister(instr->length()));
3996 } else { 4005 } else {
3997 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); 4006 __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
3998 } 4007 }
3999 DeoptimizeIf(hs, instr->environment()); 4008 DeoptimizeIf(hs, instr->environment());
4000 } 4009 }
4001 4010
4002 4011
4003 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 4012 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4004 Register value = ToRegister(instr->value()); 4013 Register external_pointer = ToRegister(instr->elements());
4005 Register elements = ToRegister(instr->object());
4006 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4007 Register scratch = scratch0();
4008 Register store_base = scratch;
4009 int offset = 0;
4010
4011 // Do the store.
4012 if (instr->key()->IsConstantOperand()) {
4013 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4014 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
4015 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
4016 instr->additional_index());
4017 store_base = elements;
4018 } else {
4019 // Even though the HLoadKeyedFastElement instruction forces the input
4020 // representation for the key to be an integer, the input gets replaced
4021 // during bound check elimination with the index argument to the bounds
4022 // check, which can be tagged, so that case must be handled here, too.
4023 if (instr->hydrogen()->key()->representation().IsTagged()) {
4024 __ add(scratch, elements,
4025 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
4026 } else {
4027 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
4028 }
4029 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
4030 }
4031 __ str(value, FieldMemOperand(store_base, offset));
4032
4033 if (instr->hydrogen()->NeedsWriteBarrier()) {
4034 HType type = instr->hydrogen()->value()->type();
4035 SmiCheck check_needed =
4036 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4037 // Compute address of modified element and store it into key register.
4038 __ add(key, store_base, Operand(offset - kHeapObjectTag));
4039 __ RecordWrite(elements,
4040 key,
4041 value,
4042 kLRHasBeenSaved,
4043 kSaveFPRegs,
4044 EMIT_REMEMBERED_SET,
4045 check_needed);
4046 }
4047 }
4048
4049
4050 void LCodeGen::DoStoreKeyedFastDoubleElement(
4051 LStoreKeyedFastDoubleElement* instr) {
4052 DwVfpRegister value = ToDoubleRegister(instr->value());
4053 Register elements = ToRegister(instr->elements());
4054 Register key = no_reg;
4055 Register scratch = scratch0();
4056 bool key_is_constant = instr->key()->IsConstantOperand();
4057 int constant_key = 0;
4058
4059 // Calculate the effective address of the slot in the array to store the
4060 // double value.
4061 if (key_is_constant) {
4062 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4063 if (constant_key & 0xF0000000) {
4064 Abort("array index constant value too big.");
4065 }
4066 } else {
4067 key = ToRegister(instr->key());
4068 }
4069 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
4070 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
4071 ? (element_size_shift - kSmiTagSize) : element_size_shift;
4072 Operand operand = key_is_constant
4073 ? Operand((constant_key << element_size_shift) +
4074 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
4075 : Operand(key, LSL, shift_size);
4076 __ add(scratch, elements, operand);
4077 if (!key_is_constant) {
4078 __ add(scratch, scratch,
4079 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
4080 }
4081
4082 if (instr->NeedsCanonicalization()) {
4083 // Check for NaN. All NaNs must be canonicalized.
4084 __ VFPCompareAndSetFlags(value, value);
4085 // Only load canonical NaN if the comparison above set the overflow.
4086 __ Vmov(value,
4087 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
4088 no_reg, vs);
4089 }
4090
4091 __ vstr(value, scratch, instr->additional_index() << element_size_shift);
4092 }
4093
4094
4095 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
4096 LStoreKeyedSpecializedArrayElement* instr) {
4097
4098 Register external_pointer = ToRegister(instr->external_pointer());
4099 Register key = no_reg; 4014 Register key = no_reg;
4100 ElementsKind elements_kind = instr->elements_kind(); 4015 ElementsKind elements_kind = instr->elements_kind();
4101 bool key_is_constant = instr->key()->IsConstantOperand(); 4016 bool key_is_constant = instr->key()->IsConstantOperand();
4102 int constant_key = 0; 4017 int constant_key = 0;
4103 if (key_is_constant) { 4018 if (key_is_constant) {
4104 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 4019 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4105 if (constant_key & 0xF0000000) { 4020 if (constant_key & 0xF0000000) {
4106 Abort("array index constant value too big."); 4021 Abort("array index constant value too big.");
4107 } 4022 }
4108 } else { 4023 } else {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4157 case FAST_HOLEY_SMI_ELEMENTS: 4072 case FAST_HOLEY_SMI_ELEMENTS:
4158 case DICTIONARY_ELEMENTS: 4073 case DICTIONARY_ELEMENTS:
4159 case NON_STRICT_ARGUMENTS_ELEMENTS: 4074 case NON_STRICT_ARGUMENTS_ELEMENTS:
4160 UNREACHABLE(); 4075 UNREACHABLE();
4161 break; 4076 break;
4162 } 4077 }
4163 } 4078 }
4164 } 4079 }
4165 4080
4166 4081
4082 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4083 DwVfpRegister value = ToDoubleRegister(instr->value());
4084 Register elements = ToRegister(instr->elements());
4085 Register key = no_reg;
4086 Register scratch = scratch0();
4087 bool key_is_constant = instr->key()->IsConstantOperand();
4088 int constant_key = 0;
4089
4090 // Calculate the effective address of the slot in the array to store the
4091 // double value.
4092 if (key_is_constant) {
4093 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4094 if (constant_key & 0xF0000000) {
4095 Abort("array index constant value too big.");
4096 }
4097 } else {
4098 key = ToRegister(instr->key());
4099 }
4100 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
4101 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
4102 ? (element_size_shift - kSmiTagSize) : element_size_shift;
4103 Operand operand = key_is_constant
4104 ? Operand((constant_key << element_size_shift) +
4105 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
4106 : Operand(key, LSL, shift_size);
4107 __ add(scratch, elements, operand);
4108 if (!key_is_constant) {
4109 __ add(scratch, scratch,
4110 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
4111 }
4112
4113 if (instr->NeedsCanonicalization()) {
4114 // Check for NaN. All NaNs must be canonicalized.
4115 __ VFPCompareAndSetFlags(value, value);
4116 // Only load canonical NaN if the comparison above set the overflow.
4117 __ Vmov(value,
4118 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
4119 no_reg, vs);
4120 }
4121
4122 __ vstr(value, scratch, instr->additional_index() << element_size_shift);
4123 }
4124
4125
4126 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4127 Register value = ToRegister(instr->value());
4128 Register elements = ToRegister(instr->elements());
4129 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
4130 : no_reg;
4131 Register scratch = scratch0();
4132 Register store_base = scratch;
4133 int offset = 0;
4134
4135 // Do the store.
4136 if (instr->key()->IsConstantOperand()) {
4137 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4138 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
4139 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
4140 instr->additional_index());
4141 store_base = elements;
4142 } else {
4143 // Even though the HLoadKeyed instruction forces the input
4144 // representation for the key to be an integer, the input gets replaced
4145 // during bound check elimination with the index argument to the bounds
4146 // check, which can be tagged, so that case must be handled here, too.
4147 if (instr->hydrogen()->key()->representation().IsTagged()) {
4148 __ add(scratch, elements,
4149 Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
4150 } else {
4151 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
4152 }
4153 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
4154 }
4155 __ str(value, FieldMemOperand(store_base, offset));
4156
4157 if (instr->hydrogen()->NeedsWriteBarrier()) {
4158 HType type = instr->hydrogen()->value()->type();
4159 SmiCheck check_needed =
4160 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4161 // Compute address of modified element and store it into key register.
4162 __ add(key, store_base, Operand(offset - kHeapObjectTag));
4163 __ RecordWrite(elements,
4164 key,
4165 value,
4166 kLRHasBeenSaved,
4167 kSaveFPRegs,
4168 EMIT_REMEMBERED_SET,
4169 check_needed);
4170 }
4171 }
4172
4173
4174 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4175 // By cases: external, fast double
4176 if (instr->is_external()) {
4177 DoStoreKeyedExternalArray(instr);
4178 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4179 DoStoreKeyedFixedDoubleArray(instr);
4180 } else {
4181 DoStoreKeyedFixedArray(instr);
4182 }
4183 }
4184
4185
4167 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 4186 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
4168 ASSERT(ToRegister(instr->object()).is(r2)); 4187 ASSERT(ToRegister(instr->object()).is(r2));
4169 ASSERT(ToRegister(instr->key()).is(r1)); 4188 ASSERT(ToRegister(instr->key()).is(r1));
4170 ASSERT(ToRegister(instr->value()).is(r0)); 4189 ASSERT(ToRegister(instr->value()).is(r0));
4171 4190
4172 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4191 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4173 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 4192 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
4174 : isolate()->builtins()->KeyedStoreIC_Initialize(); 4193 : isolate()->builtins()->KeyedStoreIC_Initialize();
4175 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); 4194 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
4176 } 4195 }
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
5679 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5698 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5680 __ ldr(result, FieldMemOperand(scratch, 5699 __ ldr(result, FieldMemOperand(scratch,
5681 FixedArray::kHeaderSize - kPointerSize)); 5700 FixedArray::kHeaderSize - kPointerSize));
5682 __ bind(&done); 5701 __ bind(&done);
5683 } 5702 }
5684 5703
5685 5704
5686 #undef __ 5705 #undef __
5687 5706
5688 } } // namespace v8::internal 5707 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/elements-kind.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698