OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include "src/crankshaft/s390/lithium-codegen-s390.h" | 6 #include "src/crankshaft/s390/lithium-codegen-s390.h" |
7 | 7 |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2863 if (key_is_constant) { | 2863 if (key_is_constant) { |
2864 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2864 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
2865 if (constant_key & 0xF0000000) { | 2865 if (constant_key & 0xF0000000) { |
2866 Abort(kArrayIndexConstantValueTooBig); | 2866 Abort(kArrayIndexConstantValueTooBig); |
2867 } | 2867 } |
2868 } else { | 2868 } else { |
2869 key = ToRegister(instr->key()); | 2869 key = ToRegister(instr->key()); |
2870 } | 2870 } |
2871 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 2871 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
2872 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 2872 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 2873 bool keyMaybeNegative = instr->hydrogen()->IsDehoisted(); |
2873 int base_offset = instr->base_offset(); | 2874 int base_offset = instr->base_offset(); |
2874 bool use_scratch = false; | 2875 bool use_scratch = false; |
2875 | 2876 |
2876 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 2877 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { |
2877 DoubleRegister result = ToDoubleRegister(instr->result()); | 2878 DoubleRegister result = ToDoubleRegister(instr->result()); |
2878 if (key_is_constant) { | 2879 if (key_is_constant) { |
2879 base_offset += constant_key << element_size_shift; | 2880 base_offset += constant_key << element_size_shift; |
2880 if (!is_int20(base_offset)) { | 2881 if (!is_int20(base_offset)) { |
2881 __ mov(scratch0(), Operand(base_offset)); | 2882 __ mov(scratch0(), Operand(base_offset)); |
2882 base_offset = 0; | 2883 base_offset = 0; |
2883 use_scratch = true; | 2884 use_scratch = true; |
2884 } | 2885 } |
2885 } else { | 2886 } else { |
2886 __ IndexToArrayOffset(scratch0(), key, element_size_shift, key_is_smi); | 2887 __ IndexToArrayOffset(scratch0(), key, element_size_shift, key_is_smi, |
| 2888 keyMaybeNegative); |
2887 use_scratch = true; | 2889 use_scratch = true; |
2888 } | 2890 } |
2889 if (elements_kind == FLOAT32_ELEMENTS) { | 2891 if (elements_kind == FLOAT32_ELEMENTS) { |
2890 if (!use_scratch) { | 2892 if (!use_scratch) { |
2891 __ ldeb(result, MemOperand(external_pointer, base_offset)); | 2893 __ ldeb(result, MemOperand(external_pointer, base_offset)); |
2892 } else { | 2894 } else { |
2893 __ ldeb(result, MemOperand(scratch0(), external_pointer, base_offset)); | 2895 __ ldeb(result, MemOperand(scratch0(), external_pointer, base_offset)); |
2894 } | 2896 } |
2895 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 2897 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
2896 if (!use_scratch) { | 2898 if (!use_scratch) { |
2897 __ ld(result, MemOperand(external_pointer, base_offset)); | 2899 __ ld(result, MemOperand(external_pointer, base_offset)); |
2898 } else { | 2900 } else { |
2899 __ ld(result, MemOperand(scratch0(), external_pointer, base_offset)); | 2901 __ ld(result, MemOperand(scratch0(), external_pointer, base_offset)); |
2900 } | 2902 } |
2901 } | 2903 } |
2902 } else { | 2904 } else { |
2903 Register result = ToRegister(instr->result()); | 2905 Register result = ToRegister(instr->result()); |
2904 MemOperand mem_operand = | 2906 MemOperand mem_operand = |
2905 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, | 2907 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, |
2906 constant_key, element_size_shift, base_offset); | 2908 constant_key, element_size_shift, base_offset, |
| 2909 keyMaybeNegative); |
2907 switch (elements_kind) { | 2910 switch (elements_kind) { |
2908 case INT8_ELEMENTS: | 2911 case INT8_ELEMENTS: |
2909 __ LoadB(result, mem_operand); | 2912 __ LoadB(result, mem_operand); |
2910 break; | 2913 break; |
2911 case UINT8_ELEMENTS: | 2914 case UINT8_ELEMENTS: |
2912 case UINT8_CLAMPED_ELEMENTS: | 2915 case UINT8_CLAMPED_ELEMENTS: |
2913 __ LoadlB(result, mem_operand); | 2916 __ LoadlB(result, mem_operand); |
2914 break; | 2917 break; |
2915 case INT16_ELEMENTS: | 2918 case INT16_ELEMENTS: |
2916 __ LoadHalfWordP(result, mem_operand); | 2919 __ LoadHalfWordP(result, mem_operand); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2950 | 2953 |
2951 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 2954 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
2952 Register elements = ToRegister(instr->elements()); | 2955 Register elements = ToRegister(instr->elements()); |
2953 bool key_is_constant = instr->key()->IsConstantOperand(); | 2956 bool key_is_constant = instr->key()->IsConstantOperand(); |
2954 Register key = no_reg; | 2957 Register key = no_reg; |
2955 DoubleRegister result = ToDoubleRegister(instr->result()); | 2958 DoubleRegister result = ToDoubleRegister(instr->result()); |
2956 Register scratch = scratch0(); | 2959 Register scratch = scratch0(); |
2957 | 2960 |
2958 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 2961 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
2959 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 2962 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 2963 bool keyMaybeNegative = instr->hydrogen()->IsDehoisted(); |
2960 int constant_key = 0; | 2964 int constant_key = 0; |
2961 if (key_is_constant) { | 2965 if (key_is_constant) { |
2962 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2966 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
2963 if (constant_key & 0xF0000000) { | 2967 if (constant_key & 0xF0000000) { |
2964 Abort(kArrayIndexConstantValueTooBig); | 2968 Abort(kArrayIndexConstantValueTooBig); |
2965 } | 2969 } |
2966 } else { | 2970 } else { |
2967 key = ToRegister(instr->key()); | 2971 key = ToRegister(instr->key()); |
2968 } | 2972 } |
2969 | 2973 |
2970 bool use_scratch = false; | 2974 bool use_scratch = false; |
2971 intptr_t base_offset = instr->base_offset() + constant_key * kDoubleSize; | 2975 intptr_t base_offset = instr->base_offset() + constant_key * kDoubleSize; |
2972 if (!key_is_constant) { | 2976 if (!key_is_constant) { |
2973 use_scratch = true; | 2977 use_scratch = true; |
2974 __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi); | 2978 __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi, |
| 2979 keyMaybeNegative); |
2975 } | 2980 } |
2976 | 2981 |
2977 // Memory references support up to 20-bits signed displacement in RXY form | 2982 // Memory references support up to 20-bits signed displacement in RXY form |
2978 // Include Register::kExponentOffset in check, so we are guaranteed not to | 2983 // Include Register::kExponentOffset in check, so we are guaranteed not to |
2979 // overflow displacement later. | 2984 // overflow displacement later. |
2980 if (!is_int20(base_offset + Register::kExponentOffset)) { | 2985 if (!is_int20(base_offset + Register::kExponentOffset)) { |
2981 use_scratch = true; | 2986 use_scratch = true; |
2982 if (key_is_constant) { | 2987 if (key_is_constant) { |
2983 __ mov(scratch, Operand(base_offset)); | 2988 __ mov(scratch, Operand(base_offset)); |
2984 } else { | 2989 } else { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3086 DoLoadKeyedFixedDoubleArray(instr); | 3091 DoLoadKeyedFixedDoubleArray(instr); |
3087 } else { | 3092 } else { |
3088 DoLoadKeyedFixedArray(instr); | 3093 DoLoadKeyedFixedArray(instr); |
3089 } | 3094 } |
3090 } | 3095 } |
3091 | 3096 |
3092 MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base, | 3097 MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base, |
3093 bool key_is_constant, bool key_is_smi, | 3098 bool key_is_constant, bool key_is_smi, |
3094 int constant_key, | 3099 int constant_key, |
3095 int element_size_shift, | 3100 int element_size_shift, |
3096 int base_offset) { | 3101 int base_offset, |
| 3102 bool keyMaybeNegative) { |
3097 Register scratch = scratch0(); | 3103 Register scratch = scratch0(); |
3098 | 3104 |
3099 if (key_is_constant) { | 3105 if (key_is_constant) { |
3100 int offset = (base_offset + (constant_key << element_size_shift)); | 3106 int offset = (base_offset + (constant_key << element_size_shift)); |
3101 if (!is_int20(offset)) { | 3107 if (!is_int20(offset)) { |
3102 __ mov(scratch, Operand(offset)); | 3108 __ mov(scratch, Operand(offset)); |
3103 return MemOperand(base, scratch); | 3109 return MemOperand(base, scratch); |
3104 } else { | 3110 } else { |
3105 return MemOperand(base, | 3111 return MemOperand(base, |
3106 (constant_key << element_size_shift) + base_offset); | 3112 (constant_key << element_size_shift) + base_offset); |
3107 } | 3113 } |
3108 } | 3114 } |
3109 | 3115 |
3110 bool needs_shift = | 3116 bool needs_shift = |
3111 (element_size_shift != (key_is_smi ? kSmiTagSize + kSmiShiftSize : 0)); | 3117 (element_size_shift != (key_is_smi ? kSmiTagSize + kSmiShiftSize : 0)); |
3112 | 3118 |
3113 if (needs_shift) { | 3119 if (needs_shift) { |
3114 __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi); | 3120 __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi, |
| 3121 keyMaybeNegative); |
3115 } else { | 3122 } else { |
3116 scratch = key; | 3123 scratch = key; |
3117 } | 3124 } |
3118 | 3125 |
3119 if (!is_int20(base_offset)) { | 3126 if (!is_int20(base_offset)) { |
3120 __ AddP(scratch, Operand(base_offset)); | 3127 __ AddP(scratch, Operand(base_offset)); |
3121 base_offset = 0; | 3128 base_offset = 0; |
3122 } | 3129 } |
3123 return MemOperand(scratch, base, base_offset); | 3130 return MemOperand(scratch, base, base_offset); |
3124 } | 3131 } |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4043 if (key_is_constant) { | 4050 if (key_is_constant) { |
4044 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4051 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4045 if (constant_key & 0xF0000000) { | 4052 if (constant_key & 0xF0000000) { |
4046 Abort(kArrayIndexConstantValueTooBig); | 4053 Abort(kArrayIndexConstantValueTooBig); |
4047 } | 4054 } |
4048 } else { | 4055 } else { |
4049 key = ToRegister(instr->key()); | 4056 key = ToRegister(instr->key()); |
4050 } | 4057 } |
4051 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4058 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
4052 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 4059 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 4060 bool keyMaybeNegative = instr->hydrogen()->IsDehoisted(); |
4053 int base_offset = instr->base_offset(); | 4061 int base_offset = instr->base_offset(); |
4054 | 4062 |
4055 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 4063 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { |
4056 Register address = scratch0(); | 4064 Register address = scratch0(); |
4057 DoubleRegister value(ToDoubleRegister(instr->value())); | 4065 DoubleRegister value(ToDoubleRegister(instr->value())); |
4058 if (key_is_constant) { | 4066 if (key_is_constant) { |
4059 if (constant_key != 0) { | 4067 if (constant_key != 0) { |
4060 base_offset += constant_key << element_size_shift; | 4068 base_offset += constant_key << element_size_shift; |
4061 if (!is_int20(base_offset)) { | 4069 if (!is_int20(base_offset)) { |
4062 __ mov(address, Operand(base_offset)); | 4070 __ mov(address, Operand(base_offset)); |
4063 __ AddP(address, external_pointer); | 4071 __ AddP(address, external_pointer); |
4064 } else { | 4072 } else { |
4065 __ AddP(address, external_pointer, Operand(base_offset)); | 4073 __ AddP(address, external_pointer, Operand(base_offset)); |
4066 } | 4074 } |
4067 base_offset = 0; | 4075 base_offset = 0; |
4068 } else { | 4076 } else { |
4069 address = external_pointer; | 4077 address = external_pointer; |
4070 } | 4078 } |
4071 } else { | 4079 } else { |
4072 __ IndexToArrayOffset(address, key, element_size_shift, key_is_smi); | 4080 __ IndexToArrayOffset(address, key, element_size_shift, key_is_smi, |
| 4081 keyMaybeNegative); |
4073 __ AddP(address, external_pointer); | 4082 __ AddP(address, external_pointer); |
4074 } | 4083 } |
4075 if (elements_kind == FLOAT32_ELEMENTS) { | 4084 if (elements_kind == FLOAT32_ELEMENTS) { |
4076 __ ledbr(double_scratch0(), value); | 4085 __ ledbr(double_scratch0(), value); |
4077 __ StoreFloat32(double_scratch0(), MemOperand(address, base_offset)); | 4086 __ StoreFloat32(double_scratch0(), MemOperand(address, base_offset)); |
4078 } else { // Storing doubles, not floats. | 4087 } else { // Storing doubles, not floats. |
4079 __ StoreDouble(value, MemOperand(address, base_offset)); | 4088 __ StoreDouble(value, MemOperand(address, base_offset)); |
4080 } | 4089 } |
4081 } else { | 4090 } else { |
4082 Register value(ToRegister(instr->value())); | 4091 Register value(ToRegister(instr->value())); |
4083 MemOperand mem_operand = | 4092 MemOperand mem_operand = |
4084 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, | 4093 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, |
4085 constant_key, element_size_shift, base_offset); | 4094 constant_key, element_size_shift, base_offset, |
| 4095 keyMaybeNegative); |
4086 switch (elements_kind) { | 4096 switch (elements_kind) { |
4087 case UINT8_ELEMENTS: | 4097 case UINT8_ELEMENTS: |
4088 case UINT8_CLAMPED_ELEMENTS: | 4098 case UINT8_CLAMPED_ELEMENTS: |
4089 case INT8_ELEMENTS: | 4099 case INT8_ELEMENTS: |
4090 if (key_is_constant) { | 4100 if (key_is_constant) { |
4091 __ StoreByte(value, mem_operand, r0); | 4101 __ StoreByte(value, mem_operand, r0); |
4092 } else { | 4102 } else { |
4093 __ StoreByte(value, mem_operand); | 4103 __ StoreByte(value, mem_operand); |
4094 } | 4104 } |
4095 break; | 4105 break; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4143 if (key_is_constant) { | 4153 if (key_is_constant) { |
4144 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4154 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4145 if (constant_key & 0xF0000000) { | 4155 if (constant_key & 0xF0000000) { |
4146 Abort(kArrayIndexConstantValueTooBig); | 4156 Abort(kArrayIndexConstantValueTooBig); |
4147 } | 4157 } |
4148 } else { | 4158 } else { |
4149 key = ToRegister(instr->key()); | 4159 key = ToRegister(instr->key()); |
4150 } | 4160 } |
4151 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4161 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
4152 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 4162 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 4163 bool keyMaybeNegative = instr->hydrogen()->IsDehoisted(); |
4153 int base_offset = instr->base_offset() + constant_key * kDoubleSize; | 4164 int base_offset = instr->base_offset() + constant_key * kDoubleSize; |
4154 bool use_scratch = false; | 4165 bool use_scratch = false; |
4155 intptr_t address_offset = base_offset; | 4166 intptr_t address_offset = base_offset; |
4156 | 4167 |
4157 if (key_is_constant) { | 4168 if (key_is_constant) { |
4158 // Memory references support up to 20-bits signed displacement in RXY form | 4169 // Memory references support up to 20-bits signed displacement in RXY form |
4159 if (!is_int20((address_offset))) { | 4170 if (!is_int20((address_offset))) { |
4160 __ mov(scratch, Operand(address_offset)); | 4171 __ mov(scratch, Operand(address_offset)); |
4161 address_offset = 0; | 4172 address_offset = 0; |
4162 use_scratch = true; | 4173 use_scratch = true; |
4163 } | 4174 } |
4164 } else { | 4175 } else { |
4165 use_scratch = true; | 4176 use_scratch = true; |
4166 __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi); | 4177 __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi, |
| 4178 keyMaybeNegative); |
4167 // Memory references support up to 20-bits signed displacement in RXY form | 4179 // Memory references support up to 20-bits signed displacement in RXY form |
4168 if (!is_int20((address_offset))) { | 4180 if (!is_int20((address_offset))) { |
4169 __ AddP(scratch, Operand(address_offset)); | 4181 __ AddP(scratch, Operand(address_offset)); |
4170 address_offset = 0; | 4182 address_offset = 0; |
4171 } | 4183 } |
4172 } | 4184 } |
4173 | 4185 |
4174 if (instr->NeedsCanonicalization()) { | 4186 if (instr->NeedsCanonicalization()) { |
4175 // Turn potential sNaN value into qNaN. | 4187 // Turn potential sNaN value into qNaN. |
4176 __ CanonicalizeNaN(double_scratch, value); | 4188 __ CanonicalizeNaN(double_scratch, value); |
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5691 __ LoadP(result, | 5703 __ LoadP(result, |
5692 FieldMemOperand(scratch, FixedArray::kHeaderSize - kPointerSize)); | 5704 FieldMemOperand(scratch, FixedArray::kHeaderSize - kPointerSize)); |
5693 __ bind(deferred->exit()); | 5705 __ bind(deferred->exit()); |
5694 __ bind(&done); | 5706 __ bind(&done); |
5695 } | 5707 } |
5696 | 5708 |
5697 #undef __ | 5709 #undef __ |
5698 | 5710 |
5699 } // namespace internal | 5711 } // namespace internal |
5700 } // namespace v8 | 5712 } // namespace v8 |
OLD | NEW |