OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. Use of this | 1 // Copyright 2016 the V8 project authors. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
3 // LICENSE file. | 3 // LICENSE file. |
4 | 4 |
5 #include <cmath> | 5 #include <cmath> |
6 #include <functional> | 6 #include <functional> |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/utils/random-number-generator.h" | 10 #include "src/base/utils/random-number-generator.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 template <> | 40 template <> |
41 void CheckOobValue(double val) { | 41 void CheckOobValue(double val) { |
42 CHECK(std::isnan(val)); | 42 CHECK(std::isnan(val)); |
43 } | 43 } |
44 } // namespace | 44 } // namespace |
45 | 45 |
46 namespace v8 { | 46 namespace v8 { |
47 namespace internal { | 47 namespace internal { |
48 namespace compiler { | 48 namespace compiler { |
49 | 49 |
50 enum LoadStoreKind { | |
titzer
2016/07/21 13:54:37
Can you simply name this TestAlignment { kAligned,
| |
51 kLoadStore, | |
52 kUnalignedLoadStore, | |
53 }; | |
54 | |
50 // This is a America! | 55 // This is a America! |
51 #define A_BILLION 1000000000ULL | 56 #define A_BILLION 1000000000ULL |
52 #define A_GIG (1024ULL * 1024ULL * 1024ULL) | 57 #define A_GIG (1024ULL * 1024ULL * 1024ULL) |
53 | 58 |
54 TEST(RunLoadInt32) { | 59 namespace { |
60 void RunLoadInt32(const LoadStoreKind t) { | |
55 RawMachineAssemblerTester<int32_t> m; | 61 RawMachineAssemblerTester<int32_t> m; |
56 | 62 |
57 int32_t p1 = 0; // loads directly from this location. | 63 int32_t p1 = 0; // loads directly from this location. |
58 m.Return(m.LoadFromPointer(&p1, MachineType::Int32())); | 64 |
65 if (t == LoadStoreKind::kLoadStore) { | |
66 m.Return(m.LoadFromPointer(&p1, MachineType::Int32())); | |
67 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
68 m.Return(m.UnalignedLoadFromPointer(&p1, MachineType::Int32())); | |
69 } else { | |
70 UNREACHABLE(); | |
71 } | |
59 | 72 |
60 FOR_INT32_INPUTS(i) { | 73 FOR_INT32_INPUTS(i) { |
61 p1 = *i; | 74 p1 = *i; |
62 CHECK_EQ(p1, m.Call()); | 75 CHECK_EQ(p1, m.Call()); |
63 } | 76 } |
64 } | 77 } |
65 | 78 |
66 TEST(RunLoadInt32Offset) { | 79 void RunLoadInt32Offset(LoadStoreKind t) { |
67 int32_t p1 = 0; // loads directly from this location. | 80 int32_t p1 = 0; // loads directly from this location. |
68 | 81 |
69 int32_t offsets[] = {-2000000, -100, -101, 1, 3, | 82 int32_t offsets[] = {-2000000, -100, -101, 1, 3, |
70 7, 120, 2000, 2000000000, 0xff}; | 83 7, 120, 2000, 2000000000, 0xff}; |
71 | 84 |
72 for (size_t i = 0; i < arraysize(offsets); i++) { | 85 for (size_t i = 0; i < arraysize(offsets); i++) { |
73 RawMachineAssemblerTester<int32_t> m; | 86 RawMachineAssemblerTester<int32_t> m; |
74 int32_t offset = offsets[i]; | 87 int32_t offset = offsets[i]; |
75 byte* pointer = reinterpret_cast<byte*>(&p1) - offset; | 88 byte* pointer = reinterpret_cast<byte*>(&p1) - offset; |
89 | |
76 // generate load [#base + #index] | 90 // generate load [#base + #index] |
77 m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset)); | 91 if (t == LoadStoreKind::kLoadStore) { |
92 m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset)); | |
93 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
94 m.Return( | |
95 m.UnalignedLoadFromPointer(pointer, MachineType::Int32(), offset)); | |
96 } else { | |
97 UNREACHABLE(); | |
98 } | |
78 | 99 |
79 FOR_INT32_INPUTS(j) { | 100 FOR_INT32_INPUTS(j) { |
80 p1 = *j; | 101 p1 = *j; |
81 CHECK_EQ(p1, m.Call()); | 102 CHECK_EQ(p1, m.Call()); |
82 } | 103 } |
83 } | 104 } |
84 } | 105 } |
85 | 106 |
86 TEST(RunLoadStoreFloat32Offset) { | 107 void RunLoadStoreFloat32Offset(LoadStoreKind t) { |
87 float p1 = 0.0f; // loads directly from this location. | 108 float p1 = 0.0f; // loads directly from this location. |
88 float p2 = 0.0f; // and stores directly into this location. | 109 float p2 = 0.0f; // and stores directly into this location. |
89 | 110 |
90 FOR_INT32_INPUTS(i) { | 111 FOR_INT32_INPUTS(i) { |
91 int32_t magic = 0x2342aabb + *i * 3; | 112 int32_t magic = 0x2342aabb + *i * 3; |
92 RawMachineAssemblerTester<int32_t> m; | 113 RawMachineAssemblerTester<int32_t> m; |
93 int32_t offset = *i; | 114 int32_t offset = *i; |
94 byte* from = reinterpret_cast<byte*>(&p1) - offset; | 115 byte* from = reinterpret_cast<byte*>(&p1) - offset; |
95 byte* to = reinterpret_cast<byte*>(&p2) - offset; | 116 byte* to = reinterpret_cast<byte*>(&p2) - offset; |
96 // generate load [#base + #index] | 117 // generate load [#base + #index] |
97 Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), | 118 if (t == LoadStoreKind::kLoadStore) { |
98 m.IntPtrConstant(offset)); | 119 Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), |
99 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to), | 120 m.IntPtrConstant(offset)); |
100 m.IntPtrConstant(offset), load, kNoWriteBarrier); | 121 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to), |
122 m.IntPtrConstant(offset), load, kNoWriteBarrier); | |
123 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
124 Node* load = | |
125 m.UnalignedLoad(MachineType::Float32(), m.PointerConstant(from), | |
126 m.IntPtrConstant(offset)); | |
127 m.UnalignedStore(MachineRepresentation::kFloat32, m.PointerConstant(to), | |
128 m.IntPtrConstant(offset), load); | |
129 | |
130 } else { | |
131 UNREACHABLE(); | |
132 } | |
101 m.Return(m.Int32Constant(magic)); | 133 m.Return(m.Int32Constant(magic)); |
102 | 134 |
103 FOR_FLOAT32_INPUTS(j) { | 135 FOR_FLOAT32_INPUTS(j) { |
104 p1 = *j; | 136 p1 = *j; |
105 p2 = *j - 5; | 137 p2 = *j - 5; |
106 CHECK_EQ(magic, m.Call()); | 138 CHECK_EQ(magic, m.Call()); |
107 CheckDoubleEq(p1, p2); | 139 CheckDoubleEq(p1, p2); |
108 } | 140 } |
109 } | 141 } |
110 } | 142 } |
111 | 143 |
112 TEST(RunLoadStoreFloat64Offset) { | 144 void RunLoadStoreFloat64Offset(LoadStoreKind t) { |
113 double p1 = 0; // loads directly from this location. | 145 double p1 = 0; // loads directly from this location. |
114 double p2 = 0; // and stores directly into this location. | 146 double p2 = 0; // and stores directly into this location. |
115 | 147 |
116 FOR_INT32_INPUTS(i) { | 148 FOR_INT32_INPUTS(i) { |
117 int32_t magic = 0x2342aabb + *i * 3; | 149 int32_t magic = 0x2342aabb + *i * 3; |
118 RawMachineAssemblerTester<int32_t> m; | 150 RawMachineAssemblerTester<int32_t> m; |
119 int32_t offset = *i; | 151 int32_t offset = *i; |
120 byte* from = reinterpret_cast<byte*>(&p1) - offset; | 152 byte* from = reinterpret_cast<byte*>(&p1) - offset; |
121 byte* to = reinterpret_cast<byte*>(&p2) - offset; | 153 byte* to = reinterpret_cast<byte*>(&p2) - offset; |
122 // generate load [#base + #index] | 154 // generate load [#base + #index] |
123 Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), | 155 if (t == LoadStoreKind::kLoadStore) { |
124 m.IntPtrConstant(offset)); | 156 Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), |
125 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to), | 157 m.IntPtrConstant(offset)); |
126 m.IntPtrConstant(offset), load, kNoWriteBarrier); | 158 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to), |
159 m.IntPtrConstant(offset), load, kNoWriteBarrier); | |
160 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
161 Node* load = | |
162 m.UnalignedLoad(MachineType::Float64(), m.PointerConstant(from), | |
163 m.IntPtrConstant(offset)); | |
164 m.UnalignedStore(MachineRepresentation::kFloat64, m.PointerConstant(to), | |
165 m.IntPtrConstant(offset), load); | |
166 } else { | |
167 UNREACHABLE(); | |
168 } | |
127 m.Return(m.Int32Constant(magic)); | 169 m.Return(m.Int32Constant(magic)); |
128 | 170 |
129 FOR_FLOAT64_INPUTS(j) { | 171 FOR_FLOAT64_INPUTS(j) { |
130 p1 = *j; | 172 p1 = *j; |
131 p2 = *j - 5; | 173 p2 = *j - 5; |
132 CHECK_EQ(magic, m.Call()); | 174 CHECK_EQ(magic, m.Call()); |
133 CheckDoubleEq(p1, p2); | 175 CheckDoubleEq(p1, p2); |
134 } | 176 } |
135 } | 177 } |
136 } | 178 } |
179 } // namespace | |
180 | |
181 TEST(RunLoadInt32) { RunLoadInt32(LoadStoreKind::kLoadStore); } | |
182 | |
183 TEST(RunUnalignedLoadInt32) { | |
184 RunLoadInt32(LoadStoreKind::kUnalignedLoadStore); | |
185 } | |
186 | |
187 TEST(RunLoadInt32Offset) { RunLoadInt32Offset(LoadStoreKind::kLoadStore); } | |
188 | |
189 TEST(RunUnalignedLoadInt32Offset) { | |
190 RunLoadInt32Offset(LoadStoreKind::kUnalignedLoadStore); | |
191 } | |
192 | |
193 TEST(RunLoadStoreFloat32Offset) { | |
194 RunLoadStoreFloat32Offset(LoadStoreKind::kLoadStore); | |
195 } | |
196 | |
197 TEST(RunUnalignedLoadStoreFloat32Offset) { | |
198 RunLoadStoreFloat32Offset(LoadStoreKind::kUnalignedLoadStore); | |
199 } | |
200 | |
201 TEST(RunLoadStoreFloat64Offset) { | |
202 RunLoadStoreFloat64Offset(LoadStoreKind::kLoadStore); | |
203 } | |
204 | |
205 TEST(RunUnalignedLoadStoreFloat64Offset) { | |
206 RunLoadStoreFloat64Offset(LoadStoreKind::kUnalignedLoadStore); | |
207 } | |
137 | 208 |
138 namespace { | 209 namespace { |
139 template <typename Type> | 210 template <typename Type> |
140 void RunLoadImmIndex(MachineType rep) { | 211 void RunLoadImmIndex(MachineType rep, LoadStoreKind t) { |
141 const int kNumElems = 3; | 212 const int kNumElems = 3; |
142 Type buffer[kNumElems]; | 213 Type buffer[kNumElems]; |
143 | 214 |
144 // initialize the buffer with some raw data. | 215 // initialize the buffer with some raw data. |
145 byte* raw = reinterpret_cast<byte*>(buffer); | 216 byte* raw = reinterpret_cast<byte*>(buffer); |
146 for (size_t i = 0; i < sizeof(buffer); i++) { | 217 for (size_t i = 0; i < sizeof(buffer); i++) { |
147 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); | 218 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); |
148 } | 219 } |
149 | 220 |
150 // Test with various large and small offsets. | 221 // Test with various large and small offsets. |
151 for (int offset = -1; offset <= 200000; offset *= -5) { | 222 for (int offset = -1; offset <= 200000; offset *= -5) { |
152 for (int i = 0; i < kNumElems; i++) { | 223 for (int i = 0; i < kNumElems; i++) { |
153 BufferedRawMachineAssemblerTester<Type> m; | 224 BufferedRawMachineAssemblerTester<Type> m; |
154 Node* base = m.PointerConstant(buffer - offset); | 225 Node* base = m.PointerConstant(buffer - offset); |
155 Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0])); | 226 Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0])); |
156 m.Return(m.Load(rep, base, index)); | 227 if (t == LoadStoreKind::kLoadStore) { |
228 m.Return(m.Load(rep, base, index)); | |
229 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
230 m.Return(m.UnalignedLoad(rep, base, index)); | |
231 } else { | |
232 UNREACHABLE(); | |
233 } | |
157 | 234 |
158 volatile Type expected = buffer[i]; | 235 volatile Type expected = buffer[i]; |
159 volatile Type actual = m.Call(); | 236 volatile Type actual = m.Call(); |
160 CHECK_EQ(expected, actual); | 237 CHECK_EQ(expected, actual); |
161 } | 238 } |
162 } | 239 } |
163 } | 240 } |
164 | 241 |
165 template <typename CType> | 242 template <typename CType> |
166 void RunLoadStore(MachineType rep) { | 243 void RunLoadStore(MachineType rep, LoadStoreKind t) { |
167 const int kNumElems = 4; | 244 const int kNumElems = 4; |
168 CType buffer[kNumElems]; | 245 CType buffer[kNumElems]; |
169 | 246 |
170 for (int32_t x = 0; x < kNumElems; x++) { | 247 for (int32_t x = 0; x < kNumElems; x++) { |
171 int32_t y = kNumElems - x - 1; | 248 int32_t y = kNumElems - x - 1; |
172 // initialize the buffer with raw data. | 249 // initialize the buffer with raw data. |
173 byte* raw = reinterpret_cast<byte*>(buffer); | 250 byte* raw = reinterpret_cast<byte*>(buffer); |
174 for (size_t i = 0; i < sizeof(buffer); i++) { | 251 for (size_t i = 0; i < sizeof(buffer); i++) { |
175 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); | 252 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); |
176 } | 253 } |
177 | 254 |
178 RawMachineAssemblerTester<int32_t> m; | 255 RawMachineAssemblerTester<int32_t> m; |
179 int32_t OK = 0x29000 + x; | 256 int32_t OK = 0x29000 + x; |
180 Node* base = m.PointerConstant(buffer); | 257 Node* base = m.PointerConstant(buffer); |
181 Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0])); | 258 Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0])); |
182 Node* load = m.Load(rep, base, index0); | |
183 Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0])); | 259 Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0])); |
184 m.Store(rep.representation(), base, index1, load, kNoWriteBarrier); | 260 if (t == LoadStoreKind::kLoadStore) { |
261 Node* load = m.Load(rep, base, index0); | |
262 m.Store(rep.representation(), base, index1, load, kNoWriteBarrier); | |
263 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
264 Node* load = m.UnalignedLoad(rep, base, index0); | |
265 m.UnalignedStore(rep.representation(), base, index1, load); | |
266 } | |
267 | |
185 m.Return(m.Int32Constant(OK)); | 268 m.Return(m.Int32Constant(OK)); |
186 | 269 |
187 CHECK(buffer[x] != buffer[y]); | 270 CHECK(buffer[x] != buffer[y]); |
188 CHECK_EQ(OK, m.Call()); | 271 CHECK_EQ(OK, m.Call()); |
189 CHECK(buffer[x] == buffer[y]); | 272 CHECK(buffer[x] == buffer[y]); |
190 } | 273 } |
191 } | 274 } |
275 | |
276 template <typename CType> | |
277 void RunUnalignedLoadStoreUnalignedAccess(MachineType rep) { | |
278 CType in, out; | |
279 CType in_buffer[2]; | |
280 CType out_buffer[2]; | |
281 byte* raw; | |
282 | |
283 for (int x = 0; x < sizeof(CType); x++) { | |
284 int y = sizeof(CType) - x; | |
285 | |
286 raw = reinterpret_cast<byte*>(&in); | |
287 for (size_t i = 0; i < sizeof(CType); i++) { | |
288 raw[i] = static_cast<byte>((i + sizeof(CType)) ^ 0xAA); | |
289 } | |
290 | |
291 raw = reinterpret_cast<byte*>(in_buffer); | |
292 MemCopy(raw + x, &in, sizeof(CType)); | |
293 | |
294 RawMachineAssemblerTester<int32_t> m; | |
295 int32_t OK = 0x29000 + x; | |
296 | |
297 Node* base0 = m.PointerConstant(in_buffer); | |
298 Node* base1 = m.PointerConstant(out_buffer); | |
299 Node* index0 = m.IntPtrConstant(x); | |
300 Node* index1 = m.IntPtrConstant(y); | |
301 Node* load = m.UnalignedLoad(rep, base0, index0); | |
302 m.UnalignedStore(rep.representation(), base1, index1, load); | |
303 | |
304 m.Return(m.Int32Constant(OK)); | |
305 | |
306 CHECK_EQ(OK, m.Call()); | |
307 | |
308 raw = reinterpret_cast<byte*>(&out_buffer); | |
309 MemCopy(&out, raw + y, sizeof(CType)); | |
310 CHECK(in == out); | |
311 } | |
312 } | |
192 } // namespace | 313 } // namespace |
193 | 314 |
194 TEST(RunLoadImmIndex) { | 315 TEST(RunLoadImmIndex) { |
195 RunLoadImmIndex<int8_t>(MachineType::Int8()); | 316 RunLoadImmIndex<int8_t>(MachineType::Int8(), LoadStoreKind::kLoadStore); |
196 RunLoadImmIndex<uint8_t>(MachineType::Uint8()); | 317 RunLoadImmIndex<uint8_t>(MachineType::Uint8(), LoadStoreKind::kLoadStore); |
197 RunLoadImmIndex<int16_t>(MachineType::Int16()); | 318 RunLoadImmIndex<int16_t>(MachineType::Int16(), LoadStoreKind::kLoadStore); |
198 RunLoadImmIndex<uint16_t>(MachineType::Uint16()); | 319 RunLoadImmIndex<uint16_t>(MachineType::Uint16(), LoadStoreKind::kLoadStore); |
199 RunLoadImmIndex<int32_t>(MachineType::Int32()); | 320 RunLoadImmIndex<int32_t>(MachineType::Int32(), LoadStoreKind::kLoadStore); |
200 RunLoadImmIndex<uint32_t>(MachineType::Uint32()); | 321 RunLoadImmIndex<uint32_t>(MachineType::Uint32(), LoadStoreKind::kLoadStore); |
201 RunLoadImmIndex<int32_t*>(MachineType::AnyTagged()); | 322 RunLoadImmIndex<int32_t*>(MachineType::AnyTagged(), |
202 RunLoadImmIndex<float>(MachineType::Float32()); | 323 LoadStoreKind::kLoadStore); |
203 RunLoadImmIndex<double>(MachineType::Float64()); | 324 RunLoadImmIndex<float>(MachineType::Float32(), LoadStoreKind::kLoadStore); |
325 RunLoadImmIndex<double>(MachineType::Float64(), LoadStoreKind::kLoadStore); | |
204 #if V8_TARGET_ARCH_64_BIT | 326 #if V8_TARGET_ARCH_64_BIT |
205 RunLoadImmIndex<int64_t>(MachineType::Int64()); | 327 RunLoadImmIndex<int64_t>(MachineType::Int64(), LoadStoreKind::kLoadStore); |
328 #endif | |
329 // TODO(titzer): test various indexing modes. | |
330 } | |
331 | |
332 TEST(RunUnalignedLoadImmIndex) { | |
333 RunLoadImmIndex<int16_t>(MachineType::Int16(), | |
334 LoadStoreKind::kUnalignedLoadStore); | |
335 RunLoadImmIndex<uint16_t>(MachineType::Uint16(), | |
336 LoadStoreKind::kUnalignedLoadStore); | |
337 RunLoadImmIndex<int32_t>(MachineType::Int32(), | |
338 LoadStoreKind::kUnalignedLoadStore); | |
339 RunLoadImmIndex<uint32_t>(MachineType::Uint32(), | |
340 LoadStoreKind::kUnalignedLoadStore); | |
341 RunLoadImmIndex<int32_t*>(MachineType::AnyTagged(), | |
342 LoadStoreKind::kUnalignedLoadStore); | |
343 RunLoadImmIndex<float>(MachineType::Float32(), | |
344 LoadStoreKind::kUnalignedLoadStore); | |
345 RunLoadImmIndex<double>(MachineType::Float64(), | |
346 LoadStoreKind::kUnalignedLoadStore); | |
347 #if V8_TARGET_ARCH_64_BIT | |
348 RunLoadImmIndex<int64_t>(MachineType::Int64(), | |
349 LoadStoreKind::kUnalignedLoadStore); | |
206 #endif | 350 #endif |
207 // TODO(titzer): test various indexing modes. | 351 // TODO(titzer): test various indexing modes. |
208 } | 352 } |
209 | 353 |
210 TEST(RunLoadStore) { | 354 TEST(RunLoadStore) { |
211 RunLoadStore<int8_t>(MachineType::Int8()); | 355 RunLoadStore<int8_t>(MachineType::Int8(), LoadStoreKind::kLoadStore); |
212 RunLoadStore<uint8_t>(MachineType::Uint8()); | 356 RunLoadStore<uint8_t>(MachineType::Uint8(), LoadStoreKind::kLoadStore); |
213 RunLoadStore<int16_t>(MachineType::Int16()); | 357 RunLoadStore<int16_t>(MachineType::Int16(), LoadStoreKind::kLoadStore); |
214 RunLoadStore<uint16_t>(MachineType::Uint16()); | 358 RunLoadStore<uint16_t>(MachineType::Uint16(), LoadStoreKind::kLoadStore); |
215 RunLoadStore<int32_t>(MachineType::Int32()); | 359 RunLoadStore<int32_t>(MachineType::Int32(), LoadStoreKind::kLoadStore); |
216 RunLoadStore<uint32_t>(MachineType::Uint32()); | 360 RunLoadStore<uint32_t>(MachineType::Uint32(), LoadStoreKind::kLoadStore); |
217 RunLoadStore<void*>(MachineType::AnyTagged()); | 361 RunLoadStore<void*>(MachineType::AnyTagged(), LoadStoreKind::kLoadStore); |
218 RunLoadStore<float>(MachineType::Float32()); | 362 RunLoadStore<float>(MachineType::Float32(), LoadStoreKind::kLoadStore); |
219 RunLoadStore<double>(MachineType::Float64()); | 363 RunLoadStore<double>(MachineType::Float64(), LoadStoreKind::kLoadStore); |
220 #if V8_TARGET_ARCH_64_BIT | 364 #if V8_TARGET_ARCH_64_BIT |
221 RunLoadStore<int64_t>(MachineType::Int64()); | 365 RunLoadStore<int64_t>(MachineType::Int64(), LoadStoreKind::kLoadStore); |
222 #endif | 366 #endif |
223 } | 367 } |
224 | 368 |
369 TEST(RunUnalignedLoadStore) { | |
370 RunLoadStore<int16_t>(MachineType::Int16(), | |
371 LoadStoreKind::kUnalignedLoadStore); | |
372 RunLoadStore<uint16_t>(MachineType::Uint16(), | |
373 LoadStoreKind::kUnalignedLoadStore); | |
374 RunLoadStore<int32_t>(MachineType::Int32(), | |
375 LoadStoreKind::kUnalignedLoadStore); | |
376 RunLoadStore<uint32_t>(MachineType::Uint32(), | |
377 LoadStoreKind::kUnalignedLoadStore); | |
378 RunLoadStore<void*>(MachineType::AnyTagged(), | |
379 LoadStoreKind::kUnalignedLoadStore); | |
380 RunLoadStore<float>(MachineType::Float32(), | |
381 LoadStoreKind::kUnalignedLoadStore); | |
382 RunLoadStore<double>(MachineType::Float64(), | |
383 LoadStoreKind::kUnalignedLoadStore); | |
384 #if V8_TARGET_ARCH_64_BIT | |
385 RunLoadStore<int64_t>(MachineType::Int64(), | |
386 LoadStoreKind::kUnalignedLoadStore); | |
387 #endif | |
388 } | |
389 | |
390 TEST(RunUnalignedLoadStoreUnalignedAccess) { | |
391 RunUnalignedLoadStoreUnalignedAccess<int16_t>(MachineType::Int16()); | |
392 RunUnalignedLoadStoreUnalignedAccess<uint16_t>(MachineType::Uint16()); | |
393 RunUnalignedLoadStoreUnalignedAccess<int32_t>(MachineType::Int32()); | |
394 RunUnalignedLoadStoreUnalignedAccess<uint32_t>(MachineType::Uint32()); | |
395 RunUnalignedLoadStoreUnalignedAccess<void*>(MachineType::AnyTagged()); | |
396 RunUnalignedLoadStoreUnalignedAccess<float>(MachineType::Float32()); | |
397 RunUnalignedLoadStoreUnalignedAccess<double>(MachineType::Float64()); | |
398 #if V8_TARGET_ARCH_64_BIT | |
399 RunUnalignedLoadStoreUnalignedAccess<int64_t>(MachineType::Int64()); | |
400 #endif | |
401 } | |
402 | |
225 #if V8_TARGET_LITTLE_ENDIAN | 403 #if V8_TARGET_LITTLE_ENDIAN |
226 #define LSB(addr, bytes) addr | 404 #define LSB(addr, bytes) addr |
227 #elif V8_TARGET_BIG_ENDIAN | 405 #elif V8_TARGET_BIG_ENDIAN |
228 #define LSB(addr, bytes) reinterpret_cast<byte*>(addr + 1) - bytes | 406 #define LSB(addr, bytes) reinterpret_cast<byte*>(addr + 1) - bytes |
229 #else | 407 #else |
230 #error "Unknown Architecture" | 408 #error "Unknown Architecture" |
231 #endif | 409 #endif |
232 | 410 |
233 TEST(RunLoadStoreSignExtend32) { | 411 namespace { |
412 void RunLoadStoreSignExtend32(LoadStoreKind t) { | |
234 int32_t buffer[4]; | 413 int32_t buffer[4]; |
235 RawMachineAssemblerTester<int32_t> m; | 414 RawMachineAssemblerTester<int32_t> m; |
236 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Int8()); | 415 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Int8()); |
237 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); | 416 if (t == LoadStoreKind::kLoadStore) { |
238 Node* load32 = m.LoadFromPointer(&buffer[0], MachineType::Int32()); | 417 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); |
239 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); | 418 Node* load32 = m.LoadFromPointer(&buffer[0], MachineType::Int32()); |
240 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord32, load16); | 419 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); |
241 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord32, load32); | 420 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord32, load16); |
421 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord32, load32); | |
422 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
423 Node* load16 = | |
424 m.UnalignedLoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); | |
425 Node* load32 = m.UnalignedLoadFromPointer(&buffer[0], MachineType::Int32()); | |
426 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); | |
427 m.UnalignedStoreToPointer(&buffer[2], MachineRepresentation::kWord32, | |
428 load16); | |
429 m.UnalignedStoreToPointer(&buffer[3], MachineRepresentation::kWord32, | |
430 load32); | |
431 } else { | |
432 UNREACHABLE(); | |
433 } | |
242 m.Return(load8); | 434 m.Return(load8); |
243 | 435 |
244 FOR_INT32_INPUTS(i) { | 436 FOR_INT32_INPUTS(i) { |
245 buffer[0] = *i; | 437 buffer[0] = *i; |
246 | 438 |
247 CHECK_EQ(static_cast<int8_t>(*i & 0xff), m.Call()); | 439 CHECK_EQ(static_cast<int8_t>(*i & 0xff), m.Call()); |
248 CHECK_EQ(static_cast<int8_t>(*i & 0xff), buffer[1]); | 440 CHECK_EQ(static_cast<int8_t>(*i & 0xff), buffer[1]); |
249 CHECK_EQ(static_cast<int16_t>(*i & 0xffff), buffer[2]); | 441 CHECK_EQ(static_cast<int16_t>(*i & 0xffff), buffer[2]); |
250 CHECK_EQ(*i, buffer[3]); | 442 CHECK_EQ(*i, buffer[3]); |
251 } | 443 } |
252 } | 444 } |
253 | 445 |
254 TEST(RunLoadStoreZeroExtend32) { | 446 void RunLoadStoreZeroExtend32(LoadStoreKind t) { |
255 uint32_t buffer[4]; | 447 uint32_t buffer[4]; |
256 RawMachineAssemblerTester<uint32_t> m; | 448 RawMachineAssemblerTester<uint32_t> m; |
257 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Uint8()); | 449 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Uint8()); |
258 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); | 450 if (t == LoadStoreKind::kLoadStore) { |
259 Node* load32 = m.LoadFromPointer(&buffer[0], MachineType::Uint32()); | 451 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); |
260 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); | 452 Node* load32 = m.LoadFromPointer(&buffer[0], MachineType::Uint32()); |
261 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord32, load16); | 453 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); |
262 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord32, load32); | 454 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord32, load16); |
455 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord32, load32); | |
456 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
457 Node* load16 = | |
458 m.UnalignedLoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); | |
459 Node* load32 = | |
460 m.UnalignedLoadFromPointer(&buffer[0], MachineType::Uint32()); | |
461 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord32, load8); | |
462 m.UnalignedStoreToPointer(&buffer[2], MachineRepresentation::kWord32, | |
463 load16); | |
464 m.UnalignedStoreToPointer(&buffer[3], MachineRepresentation::kWord32, | |
465 load32); | |
466 } | |
263 m.Return(load8); | 467 m.Return(load8); |
264 | 468 |
265 FOR_UINT32_INPUTS(i) { | 469 FOR_UINT32_INPUTS(i) { |
266 buffer[0] = *i; | 470 buffer[0] = *i; |
267 | 471 |
268 CHECK_EQ((*i & 0xff), m.Call()); | 472 CHECK_EQ((*i & 0xff), m.Call()); |
269 CHECK_EQ((*i & 0xff), buffer[1]); | 473 CHECK_EQ((*i & 0xff), buffer[1]); |
270 CHECK_EQ((*i & 0xffff), buffer[2]); | 474 CHECK_EQ((*i & 0xffff), buffer[2]); |
271 CHECK_EQ(*i, buffer[3]); | 475 CHECK_EQ(*i, buffer[3]); |
272 } | 476 } |
273 } | 477 } |
478 } // namespace | |
479 | |
480 TEST(RunLoadStoreSignExtend32) { | |
481 RunLoadStoreSignExtend32(LoadStoreKind::kLoadStore); | |
482 } | |
483 | |
484 TEST(RunUnalignedLoadStoreSignExtend32) { | |
485 RunLoadStoreSignExtend32(LoadStoreKind::kUnalignedLoadStore); | |
486 } | |
487 | |
488 TEST(RunLoadStoreZeroExtend32) { | |
489 RunLoadStoreZeroExtend32(LoadStoreKind::kLoadStore); | |
490 } | |
491 | |
492 TEST(RunUnalignedLoadStoreZeroExtend32) { | |
493 RunLoadStoreZeroExtend32(LoadStoreKind::kUnalignedLoadStore); | |
494 } | |
274 | 495 |
275 #if V8_TARGET_ARCH_64_BIT | 496 #if V8_TARGET_ARCH_64_BIT |
276 TEST(RunCheckedLoadInt64) { | |
277 int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL}; | |
278 RawMachineAssemblerTester<int64_t> m(MachineType::Int32()); | |
279 Node* base = m.PointerConstant(buffer); | |
280 Node* index = m.Parameter(0); | |
281 Node* length = m.Int32Constant(16); | |
282 Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base, | |
283 index, length); | |
284 m.Return(load); | |
285 | 497 |
286 CHECK_EQ(buffer[0], m.Call(0)); | 498 namespace { |
287 CHECK_EQ(buffer[1], m.Call(8)); | 499 void RunLoadStoreSignExtend64(LoadStoreKind t) { |
288 CheckOobValue(m.Call(16)); | |
289 } | |
290 | |
291 TEST(RunLoadStoreSignExtend64) { | |
292 if (true) return; // TODO(titzer): sign extension of loads to 64-bit. | 500 if (true) return; // TODO(titzer): sign extension of loads to 64-bit. |
293 int64_t buffer[5]; | 501 int64_t buffer[5]; |
294 RawMachineAssemblerTester<int64_t> m; | 502 RawMachineAssemblerTester<int64_t> m; |
295 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Int8()); | 503 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Int8()); |
296 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); | 504 if (t == LoadStoreKind::kLoadStore) { |
297 Node* load32 = m.LoadFromPointer(LSB(&buffer[0], 4), MachineType::Int32()); | 505 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); |
298 Node* load64 = m.LoadFromPointer(&buffer[0], MachineType::Int64()); | 506 Node* load32 = m.LoadFromPointer(LSB(&buffer[0], 4), MachineType::Int32()); |
299 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); | 507 Node* load64 = m.LoadFromPointer(&buffer[0], MachineType::Int64()); |
300 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord64, load16); | 508 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); |
301 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord64, load32); | 509 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord64, load16); |
302 m.StoreToPointer(&buffer[4], MachineRepresentation::kWord64, load64); | 510 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord64, load32); |
511 m.StoreToPointer(&buffer[4], MachineRepresentation::kWord64, load64); | |
512 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
513 Node* load16 = | |
514 m.UnalignedLoadFromPointer(LSB(&buffer[0], 2), MachineType::Int16()); | |
515 Node* load32 = | |
516 m.UnalignedLoadFromPointer(LSB(&buffer[0], 4), MachineType::Int32()); | |
517 Node* load64 = m.UnalignedLoadFromPointer(&buffer[0], MachineType::Int64()); | |
518 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); | |
519 m.UnalignedStoreToPointer(&buffer[2], MachineRepresentation::kWord64, | |
520 load16); | |
521 m.UnalignedStoreToPointer(&buffer[3], MachineRepresentation::kWord64, | |
522 load32); | |
523 m.UnalignedStoreToPointer(&buffer[4], MachineRepresentation::kWord64, | |
524 load64); | |
525 } else { | |
526 UNREACHABLE(); | |
527 } | |
303 m.Return(load8); | 528 m.Return(load8); |
304 | 529 |
305 FOR_INT64_INPUTS(i) { | 530 FOR_INT64_INPUTS(i) { |
306 buffer[0] = *i; | 531 buffer[0] = *i; |
307 | 532 |
308 CHECK_EQ(static_cast<int8_t>(*i & 0xff), m.Call()); | 533 CHECK_EQ(static_cast<int8_t>(*i & 0xff), m.Call()); |
309 CHECK_EQ(static_cast<int8_t>(*i & 0xff), buffer[1]); | 534 CHECK_EQ(static_cast<int8_t>(*i & 0xff), buffer[1]); |
310 CHECK_EQ(static_cast<int16_t>(*i & 0xffff), buffer[2]); | 535 CHECK_EQ(static_cast<int16_t>(*i & 0xffff), buffer[2]); |
311 CHECK_EQ(static_cast<int32_t>(*i & 0xffffffff), buffer[3]); | 536 CHECK_EQ(static_cast<int32_t>(*i & 0xffffffff), buffer[3]); |
312 CHECK_EQ(*i, buffer[4]); | 537 CHECK_EQ(*i, buffer[4]); |
313 } | 538 } |
314 } | 539 } |
315 | 540 |
316 TEST(RunLoadStoreZeroExtend64) { | 541 void RunLoadStoreZeroExtend64(LoadStoreKind t) { |
317 if (kPointerSize < 8) return; | 542 if (kPointerSize < 8) return; |
318 uint64_t buffer[5]; | 543 uint64_t buffer[5]; |
319 RawMachineAssemblerTester<int64_t> m; | 544 RawMachineAssemblerTester<int64_t> m; |
320 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Uint8()); | 545 Node* load8 = m.LoadFromPointer(LSB(&buffer[0], 1), MachineType::Uint8()); |
321 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); | 546 if (t == LoadStoreKind::kLoadStore) { |
322 Node* load32 = m.LoadFromPointer(LSB(&buffer[0], 4), MachineType::Uint32()); | 547 Node* load16 = m.LoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); |
323 Node* load64 = m.LoadFromPointer(&buffer[0], MachineType::Uint64()); | 548 Node* load32 = m.LoadFromPointer(LSB(&buffer[0], 4), MachineType::Uint32()); |
324 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); | 549 Node* load64 = m.LoadFromPointer(&buffer[0], MachineType::Uint64()); |
325 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord64, load16); | 550 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); |
326 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord64, load32); | 551 m.StoreToPointer(&buffer[2], MachineRepresentation::kWord64, load16); |
327 m.StoreToPointer(&buffer[4], MachineRepresentation::kWord64, load64); | 552 m.StoreToPointer(&buffer[3], MachineRepresentation::kWord64, load32); |
553 m.StoreToPointer(&buffer[4], MachineRepresentation::kWord64, load64); | |
554 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
555 Node* load16 = | |
556 m.UnalignedLoadFromPointer(LSB(&buffer[0], 2), MachineType::Uint16()); | |
557 Node* load32 = | |
558 m.UnalignedLoadFromPointer(LSB(&buffer[0], 4), MachineType::Uint32()); | |
559 Node* load64 = | |
560 m.UnalignedLoadFromPointer(&buffer[0], MachineType::Uint64()); | |
561 m.StoreToPointer(&buffer[1], MachineRepresentation::kWord64, load8); | |
562 m.UnalignedStoreToPointer(&buffer[2], MachineRepresentation::kWord64, | |
563 load16); | |
564 m.UnalignedStoreToPointer(&buffer[3], MachineRepresentation::kWord64, | |
565 load32); | |
566 m.UnalignedStoreToPointer(&buffer[4], MachineRepresentation::kWord64, | |
567 load64); | |
568 } else { | |
569 UNREACHABLE(); | |
570 } | |
328 m.Return(load8); | 571 m.Return(load8); |
329 | 572 |
330 FOR_UINT64_INPUTS(i) { | 573 FOR_UINT64_INPUTS(i) { |
331 buffer[0] = *i; | 574 buffer[0] = *i; |
332 | 575 |
333 CHECK_EQ((*i & 0xff), m.Call()); | 576 CHECK_EQ((*i & 0xff), m.Call()); |
334 CHECK_EQ((*i & 0xff), buffer[1]); | 577 CHECK_EQ((*i & 0xff), buffer[1]); |
335 CHECK_EQ((*i & 0xffff), buffer[2]); | 578 CHECK_EQ((*i & 0xffff), buffer[2]); |
336 CHECK_EQ((*i & 0xffffffff), buffer[3]); | 579 CHECK_EQ((*i & 0xffffffff), buffer[3]); |
337 CHECK_EQ(*i, buffer[4]); | 580 CHECK_EQ(*i, buffer[4]); |
338 } | 581 } |
339 } | 582 } |
340 | 583 |
584 } // namespace | |
585 | |
586 TEST(RunCheckedLoadInt64) { | |
587 int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL}; | |
588 RawMachineAssemblerTester<int64_t> m(MachineType::Int32()); | |
589 Node* base = m.PointerConstant(buffer); | |
590 Node* index = m.Parameter(0); | |
591 Node* length = m.Int32Constant(16); | |
592 Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base, | |
593 index, length); | |
594 m.Return(load); | |
595 | |
596 CHECK_EQ(buffer[0], m.Call(0)); | |
597 CHECK_EQ(buffer[1], m.Call(8)); | |
598 CheckOobValue(m.Call(16)); | |
599 } | |
600 | |
601 TEST(RunLoadStoreSignExtend64) { | |
602 RunLoadStoreSignExtend64(LoadStoreKind::kLoadStore); | |
603 } | |
604 | |
605 TEST(RunUnalignedLoadStoreSignExtend64) { | |
606 RunLoadStoreSignExtend64(LoadStoreKind::kUnalignedLoadStore); | |
607 } | |
608 | |
609 TEST(RunLoadStoreZeroExtend64) { | |
610 RunLoadStoreZeroExtend64(LoadStoreKind::kLoadStore); | |
611 } | |
612 | |
613 TEST(RunUnalignedLoadStoreZeroExtend64) { | |
614 RunLoadStoreZeroExtend64(LoadStoreKind::kUnalignedLoadStore); | |
615 } | |
616 | |
341 TEST(RunCheckedStoreInt64) { | 617 TEST(RunCheckedStoreInt64) { |
342 const int64_t write = 0x5566778899aabbLL; | 618 const int64_t write = 0x5566778899aabbLL; |
343 const int64_t before = 0x33bbccddeeff0011LL; | 619 const int64_t before = 0x33bbccddeeff0011LL; |
344 int64_t buffer[] = {before, before}; | 620 int64_t buffer[] = {before, before}; |
345 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); | 621 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); |
346 Node* base = m.PointerConstant(buffer); | 622 Node* base = m.PointerConstant(buffer); |
347 Node* index = m.Parameter(0); | 623 Node* index = m.Parameter(0); |
348 Node* length = m.Int32Constant(16); | 624 Node* length = m.Int32Constant(16); |
349 Node* value = m.Int64Constant(write); | 625 Node* value = m.Int64Constant(write); |
350 Node* store = | 626 Node* store = |
(...skipping 11 matching lines...) Expand all Loading... | |
362 CHECK_EQ(before, buffer[1]); | 638 CHECK_EQ(before, buffer[1]); |
363 | 639 |
364 CHECK_EQ(11, m.Call(8)); | 640 CHECK_EQ(11, m.Call(8)); |
365 CHECK_EQ(write, buffer[0]); | 641 CHECK_EQ(write, buffer[0]); |
366 CHECK_EQ(write, buffer[1]); | 642 CHECK_EQ(write, buffer[1]); |
367 } | 643 } |
368 #endif | 644 #endif |
369 | 645 |
370 namespace { | 646 namespace { |
371 template <typename IntType> | 647 template <typename IntType> |
372 void LoadStoreTruncation(MachineType kRepresentation) { | 648 void LoadStoreTruncation(MachineType kRepresentation, LoadStoreKind t) { |
373 IntType input; | 649 IntType input; |
374 | 650 |
375 RawMachineAssemblerTester<int32_t> m; | 651 RawMachineAssemblerTester<int32_t> m; |
376 Node* a = m.LoadFromPointer(&input, kRepresentation); | 652 Node* ap1; |
377 Node* ap1 = m.Int32Add(a, m.Int32Constant(1)); | 653 if (t == LoadStoreKind::kLoadStore) { |
378 m.StoreToPointer(&input, kRepresentation.representation(), ap1); | 654 Node* a = m.LoadFromPointer(&input, kRepresentation); |
655 ap1 = m.Int32Add(a, m.Int32Constant(1)); | |
656 m.StoreToPointer(&input, kRepresentation.representation(), ap1); | |
657 } else if (t == LoadStoreKind::kUnalignedLoadStore) { | |
658 Node* a = m.UnalignedLoadFromPointer(&input, kRepresentation); | |
659 ap1 = m.Int32Add(a, m.Int32Constant(1)); | |
660 m.UnalignedStoreToPointer(&input, kRepresentation.representation(), ap1); | |
661 } else { | |
662 UNREACHABLE(); | |
663 } | |
379 m.Return(ap1); | 664 m.Return(ap1); |
380 | 665 |
381 const IntType max = std::numeric_limits<IntType>::max(); | 666 const IntType max = std::numeric_limits<IntType>::max(); |
382 const IntType min = std::numeric_limits<IntType>::min(); | 667 const IntType min = std::numeric_limits<IntType>::min(); |
383 | 668 |
384 // Test upper bound. | 669 // Test upper bound. |
385 input = max; | 670 input = max; |
386 CHECK_EQ(max + 1, m.Call()); | 671 CHECK_EQ(max + 1, m.Call()); |
387 CHECK_EQ(min, input); | 672 CHECK_EQ(min, input); |
388 | 673 |
389 // Test lower bound. | 674 // Test lower bound. |
390 input = min; | 675 input = min; |
391 CHECK_EQ(static_cast<IntType>(max + 2), m.Call()); | 676 CHECK_EQ(static_cast<IntType>(max + 2), m.Call()); |
392 CHECK_EQ(min + 1, input); | 677 CHECK_EQ(min + 1, input); |
393 | 678 |
394 // Test all one byte values that are not one byte bounds. | 679 // Test all one byte values that are not one byte bounds. |
395 for (int i = -127; i < 127; i++) { | 680 for (int i = -127; i < 127; i++) { |
396 input = i; | 681 input = i; |
397 int expected = i >= 0 ? i + 1 : max + (i - min) + 2; | 682 int expected = i >= 0 ? i + 1 : max + (i - min) + 2; |
398 CHECK_EQ(static_cast<IntType>(expected), m.Call()); | 683 CHECK_EQ(static_cast<IntType>(expected), m.Call()); |
399 CHECK_EQ(static_cast<IntType>(i + 1), input); | 684 CHECK_EQ(static_cast<IntType>(i + 1), input); |
400 } | 685 } |
401 } | 686 } |
402 } // namespace | 687 } // namespace |
403 | 688 |
404 TEST(RunLoadStoreTruncation) { | 689 TEST(RunLoadStoreTruncation) { |
405 LoadStoreTruncation<int8_t>(MachineType::Int8()); | 690 LoadStoreTruncation<int8_t>(MachineType::Int8(), LoadStoreKind::kLoadStore); |
406 LoadStoreTruncation<int16_t>(MachineType::Int16()); | 691 LoadStoreTruncation<int16_t>(MachineType::Int16(), LoadStoreKind::kLoadStore); |
692 } | |
693 | |
694 TEST(RunUnalignedLoadStoreTruncation) { | |
695 LoadStoreTruncation<int16_t>(MachineType::Int16(), | |
696 LoadStoreKind::kUnalignedLoadStore); | |
407 } | 697 } |
408 | 698 |
409 void TestRunOobCheckedLoad(bool length_is_immediate) { | 699 void TestRunOobCheckedLoad(bool length_is_immediate) { |
410 USE(CheckOobValue<int32_t>); | 700 USE(CheckOobValue<int32_t>); |
411 USE(CheckOobValue<int64_t>); | 701 USE(CheckOobValue<int64_t>); |
412 USE(CheckOobValue<float>); | 702 USE(CheckOobValue<float>); |
413 USE(CheckOobValue<double>); | 703 USE(CheckOobValue<double>); |
414 | 704 |
415 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), | 705 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), |
416 MachineType::Int32()); | 706 MachineType::Int32()); |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 TestRunOobCheckedLoadT_pseudo<int32_t>(4 * A_BILLION, true); | 1200 TestRunOobCheckedLoadT_pseudo<int32_t>(4 * A_BILLION, true); |
911 TestRunOobCheckedLoadT_pseudo<float>(4 * A_BILLION, false); | 1201 TestRunOobCheckedLoadT_pseudo<float>(4 * A_BILLION, false); |
912 TestRunOobCheckedLoadT_pseudo<float>(4 * A_BILLION, true); | 1202 TestRunOobCheckedLoadT_pseudo<float>(4 * A_BILLION, true); |
913 TestRunOobCheckedLoadT_pseudo<double>(4 * A_BILLION, false); | 1203 TestRunOobCheckedLoadT_pseudo<double>(4 * A_BILLION, false); |
914 TestRunOobCheckedLoadT_pseudo<double>(4 * A_BILLION, true); | 1204 TestRunOobCheckedLoadT_pseudo<double>(4 * A_BILLION, true); |
915 } | 1205 } |
916 | 1206 |
917 } // namespace compiler | 1207 } // namespace compiler |
918 } // namespace internal | 1208 } // namespace internal |
919 } // namespace v8 | 1209 } // namespace v8 |
OLD | NEW |