OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits> | 5 #include <limits> |
6 | 6 |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 #include "test/cctest/compiler/codegen-tester.h" | 8 #include "test/cctest/compiler/codegen-tester.h" |
9 #include "test/cctest/compiler/graph-builder-tester.h" | 9 #include "test/cctest/compiler/graph-builder-tester.h" |
10 #include "test/cctest/compiler/value-helper.h" | 10 #include "test/cctest/compiler/value-helper.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 CHECK(m.HasValue()); | 76 CHECK(m.HasValue()); |
77 CheckDoubleEq(expected, m.Value()); | 77 CheckDoubleEq(expected, m.Value()); |
78 } | 78 } |
79 | 79 |
80 Node* Parameter(int index = 0) { | 80 Node* Parameter(int index = 0) { |
81 Node* n = graph()->NewNode(common()->Parameter(index), graph()->start()); | 81 Node* n = graph()->NewNode(common()->Parameter(index), graph()->start()); |
82 NodeProperties::SetType(n, Type::Any()); | 82 NodeProperties::SetType(n, Type::Any()); |
83 return n; | 83 return n; |
84 } | 84 } |
85 | 85 |
86 void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { | 86 void CheckTypeError(MachineType from, MachineRepresentation to) { |
87 changer()->testing_type_errors_ = true; | 87 changer()->testing_type_errors_ = true; |
88 changer()->type_error_ = false; | 88 changer()->type_error_ = false; |
89 Node* n = Parameter(0); | 89 Node* n = Parameter(0); |
90 Node* c = changer()->GetRepresentationFor(n, from, to); | 90 Node* c = changer()->GetRepresentationFor(n, from, to); |
91 CHECK(changer()->type_error_); | 91 CHECK(changer()->type_error_); |
92 CHECK_EQ(n, c); | 92 CHECK_EQ(n, c); |
93 } | 93 } |
94 | 94 |
95 void CheckNop(MachineTypeUnion from, MachineTypeUnion to) { | 95 void CheckNop(MachineType from, MachineRepresentation to) { |
96 Node* n = Parameter(0); | 96 Node* n = Parameter(0); |
97 Node* c = changer()->GetRepresentationFor(n, from, to); | 97 Node* c = changer()->GetRepresentationFor(n, from, to); |
98 CHECK_EQ(n, c); | 98 CHECK_EQ(n, c); |
99 } | 99 } |
100 }; | 100 }; |
101 | 101 |
102 | 102 |
103 static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64, | 103 const MachineType kMachineTypes[] = { |
104 kRepFloat32, kRepFloat64, kRepTagged}; | 104 MachineType::Float32(), MachineType::Float64(), MachineType::Int8(), |
| 105 MachineType::Uint8(), MachineType::Int16(), MachineType::Uint16(), |
| 106 MachineType::Int32(), MachineType::Uint32(), MachineType::Int64(), |
| 107 MachineType::Uint64(), MachineType::AnyTagged()}; |
105 | 108 |
106 | 109 |
107 TEST(BoolToBit_constant) { | 110 TEST(BoolToBit_constant) { |
108 RepresentationChangerTester r; | 111 RepresentationChangerTester r; |
109 | 112 |
110 Node* true_node = r.jsgraph()->TrueConstant(); | 113 Node* true_node = r.jsgraph()->TrueConstant(); |
111 Node* true_bit = | 114 Node* true_bit = r.changer()->GetRepresentationFor( |
112 r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); | 115 true_node, MachineType::RepTagged(), MachineRepresentation::kBit); |
113 r.CheckInt32Constant(true_bit, 1); | 116 r.CheckInt32Constant(true_bit, 1); |
114 | 117 |
115 Node* false_node = r.jsgraph()->FalseConstant(); | 118 Node* false_node = r.jsgraph()->FalseConstant(); |
116 Node* false_bit = | 119 Node* false_bit = r.changer()->GetRepresentationFor( |
117 r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit); | 120 false_node, MachineType::RepTagged(), MachineRepresentation::kBit); |
118 r.CheckInt32Constant(false_bit, 0); | 121 r.CheckInt32Constant(false_bit, 0); |
119 } | 122 } |
120 | 123 |
121 | 124 |
122 TEST(BitToBool_constant) { | 125 TEST(BitToBool_constant) { |
123 RepresentationChangerTester r; | 126 RepresentationChangerTester r; |
124 | 127 |
125 for (int i = -5; i < 5; i++) { | 128 for (int i = -5; i < 5; i++) { |
126 Node* node = r.jsgraph()->Int32Constant(i); | 129 Node* node = r.jsgraph()->Int32Constant(i); |
127 Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); | 130 Node* val = r.changer()->GetRepresentationFor( |
| 131 node, MachineType::RepBit(), MachineRepresentation::kTagged); |
128 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() | 132 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() |
129 : r.isolate()->heap()->true_value()); | 133 : r.isolate()->heap()->true_value()); |
130 } | 134 } |
131 } | 135 } |
132 | 136 |
133 | 137 |
134 TEST(ToTagged_constant) { | 138 TEST(ToTagged_constant) { |
135 RepresentationChangerTester r; | 139 RepresentationChangerTester r; |
136 | 140 |
137 { | 141 { |
138 FOR_FLOAT64_INPUTS(i) { | 142 FOR_FLOAT64_INPUTS(i) { |
139 Node* n = r.jsgraph()->Float64Constant(*i); | 143 Node* n = r.jsgraph()->Float64Constant(*i); |
140 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); | 144 Node* c = r.changer()->GetRepresentationFor( |
| 145 n, MachineType::RepFloat64(), MachineRepresentation::kTagged); |
141 r.CheckNumberConstant(c, *i); | 146 r.CheckNumberConstant(c, *i); |
142 } | 147 } |
143 } | 148 } |
144 | 149 |
145 { | 150 { |
146 FOR_FLOAT64_INPUTS(i) { | 151 FOR_FLOAT64_INPUTS(i) { |
147 Node* n = r.jsgraph()->Constant(*i); | 152 Node* n = r.jsgraph()->Constant(*i); |
148 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); | 153 Node* c = r.changer()->GetRepresentationFor( |
| 154 n, MachineType::RepFloat64(), MachineRepresentation::kTagged); |
149 r.CheckNumberConstant(c, *i); | 155 r.CheckNumberConstant(c, *i); |
150 } | 156 } |
151 } | 157 } |
152 | 158 |
153 { | 159 { |
154 FOR_FLOAT32_INPUTS(i) { | 160 FOR_FLOAT32_INPUTS(i) { |
155 Node* n = r.jsgraph()->Float32Constant(*i); | 161 Node* n = r.jsgraph()->Float32Constant(*i); |
156 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged); | 162 Node* c = r.changer()->GetRepresentationFor( |
| 163 n, MachineType::RepFloat32(), MachineRepresentation::kTagged); |
157 r.CheckNumberConstant(c, *i); | 164 r.CheckNumberConstant(c, *i); |
158 } | 165 } |
159 } | 166 } |
160 | 167 |
161 { | 168 { |
162 FOR_INT32_INPUTS(i) { | 169 FOR_INT32_INPUTS(i) { |
163 Node* n = r.jsgraph()->Int32Constant(*i); | 170 Node* n = r.jsgraph()->Int32Constant(*i); |
164 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 171 Node* c = r.changer()->GetRepresentationFor( |
165 kRepTagged); | 172 n, MachineType::Int32(), MachineRepresentation::kTagged); |
166 r.CheckNumberConstant(c, *i); | 173 r.CheckNumberConstant(c, *i); |
167 } | 174 } |
168 } | 175 } |
169 | 176 |
170 { | 177 { |
171 FOR_UINT32_INPUTS(i) { | 178 FOR_UINT32_INPUTS(i) { |
172 Node* n = r.jsgraph()->Int32Constant(*i); | 179 Node* n = r.jsgraph()->Int32Constant(*i); |
173 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 180 Node* c = r.changer()->GetRepresentationFor( |
174 kRepTagged); | 181 n, MachineType::Uint32(), MachineRepresentation::kTagged); |
175 r.CheckNumberConstant(c, *i); | 182 r.CheckNumberConstant(c, *i); |
176 } | 183 } |
177 } | 184 } |
178 } | 185 } |
179 | 186 |
180 | 187 |
181 TEST(ToFloat64_constant) { | 188 TEST(ToFloat64_constant) { |
182 RepresentationChangerTester r; | 189 RepresentationChangerTester r; |
183 | 190 |
184 { | 191 { |
185 FOR_FLOAT64_INPUTS(i) { | 192 FOR_FLOAT64_INPUTS(i) { |
186 Node* n = r.jsgraph()->Float64Constant(*i); | 193 Node* n = r.jsgraph()->Float64Constant(*i); |
187 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat64); | 194 Node* c = r.changer()->GetRepresentationFor( |
| 195 n, MachineType::RepFloat64(), MachineRepresentation::kFloat64); |
188 CHECK_EQ(n, c); | 196 CHECK_EQ(n, c); |
189 } | 197 } |
190 } | 198 } |
191 | 199 |
192 { | 200 { |
193 FOR_FLOAT64_INPUTS(i) { | 201 FOR_FLOAT64_INPUTS(i) { |
194 Node* n = r.jsgraph()->Constant(*i); | 202 Node* n = r.jsgraph()->Constant(*i); |
195 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat64); | 203 Node* c = r.changer()->GetRepresentationFor( |
| 204 n, MachineType::RepTagged(), MachineRepresentation::kFloat64); |
196 r.CheckFloat64Constant(c, *i); | 205 r.CheckFloat64Constant(c, *i); |
197 } | 206 } |
198 } | 207 } |
199 | 208 |
200 { | 209 { |
201 FOR_FLOAT32_INPUTS(i) { | 210 FOR_FLOAT32_INPUTS(i) { |
202 Node* n = r.jsgraph()->Float32Constant(*i); | 211 Node* n = r.jsgraph()->Float32Constant(*i); |
203 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat64); | 212 Node* c = r.changer()->GetRepresentationFor( |
| 213 n, MachineType::RepFloat32(), MachineRepresentation::kFloat64); |
204 r.CheckFloat64Constant(c, *i); | 214 r.CheckFloat64Constant(c, *i); |
205 } | 215 } |
206 } | 216 } |
207 | 217 |
208 { | 218 { |
209 FOR_INT32_INPUTS(i) { | 219 FOR_INT32_INPUTS(i) { |
210 Node* n = r.jsgraph()->Int32Constant(*i); | 220 Node* n = r.jsgraph()->Int32Constant(*i); |
211 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 221 Node* c = r.changer()->GetRepresentationFor( |
212 kRepFloat64); | 222 n, MachineType::Int32(), MachineRepresentation::kFloat64); |
213 r.CheckFloat64Constant(c, *i); | 223 r.CheckFloat64Constant(c, *i); |
214 } | 224 } |
215 } | 225 } |
216 | 226 |
217 { | 227 { |
218 FOR_UINT32_INPUTS(i) { | 228 FOR_UINT32_INPUTS(i) { |
219 Node* n = r.jsgraph()->Int32Constant(*i); | 229 Node* n = r.jsgraph()->Int32Constant(*i); |
220 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 230 Node* c = r.changer()->GetRepresentationFor( |
221 kRepFloat64); | 231 n, MachineType::Uint32(), MachineRepresentation::kFloat64); |
222 r.CheckFloat64Constant(c, *i); | 232 r.CheckFloat64Constant(c, *i); |
223 } | 233 } |
224 } | 234 } |
225 } | 235 } |
226 | 236 |
227 | 237 |
228 static bool IsFloat32Int32(int32_t val) { | 238 static bool IsFloat32Int32(int32_t val) { |
229 return val >= -(1 << 23) && val <= (1 << 23); | 239 return val >= -(1 << 23) && val <= (1 << 23); |
230 } | 240 } |
231 | 241 |
232 | 242 |
233 static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); } | 243 static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); } |
234 | 244 |
235 | 245 |
236 TEST(ToFloat32_constant) { | 246 TEST(ToFloat32_constant) { |
237 RepresentationChangerTester r; | 247 RepresentationChangerTester r; |
238 | 248 |
239 { | 249 { |
240 FOR_FLOAT32_INPUTS(i) { | 250 FOR_FLOAT32_INPUTS(i) { |
241 Node* n = r.jsgraph()->Float32Constant(*i); | 251 Node* n = r.jsgraph()->Float32Constant(*i); |
242 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat32); | 252 Node* c = r.changer()->GetRepresentationFor( |
| 253 n, MachineType::RepFloat32(), MachineRepresentation::kFloat32); |
243 CHECK_EQ(n, c); | 254 CHECK_EQ(n, c); |
244 } | 255 } |
245 } | 256 } |
246 | 257 |
247 { | 258 { |
248 FOR_FLOAT32_INPUTS(i) { | 259 FOR_FLOAT32_INPUTS(i) { |
249 Node* n = r.jsgraph()->Constant(*i); | 260 Node* n = r.jsgraph()->Constant(*i); |
250 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat32); | 261 Node* c = r.changer()->GetRepresentationFor( |
| 262 n, MachineType::RepTagged(), MachineRepresentation::kFloat32); |
251 r.CheckFloat32Constant(c, *i); | 263 r.CheckFloat32Constant(c, *i); |
252 } | 264 } |
253 } | 265 } |
254 | 266 |
255 { | 267 { |
256 FOR_FLOAT32_INPUTS(i) { | 268 FOR_FLOAT32_INPUTS(i) { |
257 Node* n = r.jsgraph()->Float64Constant(*i); | 269 Node* n = r.jsgraph()->Float64Constant(*i); |
258 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat32); | 270 Node* c = r.changer()->GetRepresentationFor( |
| 271 n, MachineType::RepFloat64(), MachineRepresentation::kFloat32); |
259 r.CheckFloat32Constant(c, *i); | 272 r.CheckFloat32Constant(c, *i); |
260 } | 273 } |
261 } | 274 } |
262 | 275 |
263 { | 276 { |
264 FOR_INT32_INPUTS(i) { | 277 FOR_INT32_INPUTS(i) { |
265 if (!IsFloat32Int32(*i)) continue; | 278 if (!IsFloat32Int32(*i)) continue; |
266 Node* n = r.jsgraph()->Int32Constant(*i); | 279 Node* n = r.jsgraph()->Int32Constant(*i); |
267 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 280 Node* c = r.changer()->GetRepresentationFor( |
268 kRepFloat32); | 281 n, MachineType::Int32(), MachineRepresentation::kFloat32); |
269 r.CheckFloat32Constant(c, static_cast<float>(*i)); | 282 r.CheckFloat32Constant(c, static_cast<float>(*i)); |
270 } | 283 } |
271 } | 284 } |
272 | 285 |
273 { | 286 { |
274 FOR_UINT32_INPUTS(i) { | 287 FOR_UINT32_INPUTS(i) { |
275 if (!IsFloat32Uint32(*i)) continue; | 288 if (!IsFloat32Uint32(*i)) continue; |
276 Node* n = r.jsgraph()->Int32Constant(*i); | 289 Node* n = r.jsgraph()->Int32Constant(*i); |
277 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 290 Node* c = r.changer()->GetRepresentationFor( |
278 kRepFloat32); | 291 n, MachineType::Uint32(), MachineRepresentation::kFloat32); |
279 r.CheckFloat32Constant(c, static_cast<float>(*i)); | 292 r.CheckFloat32Constant(c, static_cast<float>(*i)); |
280 } | 293 } |
281 } | 294 } |
282 } | 295 } |
283 | 296 |
284 | 297 |
285 TEST(ToInt32_constant) { | 298 TEST(ToInt32_constant) { |
286 RepresentationChangerTester r; | 299 RepresentationChangerTester r; |
287 | 300 |
288 { | 301 { |
289 FOR_INT32_INPUTS(i) { | 302 FOR_INT32_INPUTS(i) { |
290 Node* n = r.jsgraph()->Int32Constant(*i); | 303 Node* n = r.jsgraph()->Int32Constant(*i); |
291 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, | 304 Node* c = r.changer()->GetRepresentationFor( |
292 kRepWord32); | 305 n, MachineType::Int32(), MachineRepresentation::kWord32); |
293 r.CheckInt32Constant(c, *i); | 306 r.CheckInt32Constant(c, *i); |
294 } | 307 } |
295 } | 308 } |
296 | 309 |
297 { | 310 { |
298 FOR_INT32_INPUTS(i) { | 311 FOR_INT32_INPUTS(i) { |
299 if (!IsFloat32Int32(*i)) continue; | 312 if (!IsFloat32Int32(*i)) continue; |
300 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); | 313 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); |
301 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeInt32, | 314 Node* c = r.changer()->GetRepresentationFor( |
302 kRepWord32); | 315 n, |
| 316 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kInt32), |
| 317 MachineRepresentation::kWord32); |
303 r.CheckInt32Constant(c, *i); | 318 r.CheckInt32Constant(c, *i); |
304 } | 319 } |
305 } | 320 } |
306 | 321 |
307 { | 322 { |
308 FOR_INT32_INPUTS(i) { | 323 FOR_INT32_INPUTS(i) { |
309 Node* n = r.jsgraph()->Float64Constant(*i); | 324 Node* n = r.jsgraph()->Float64Constant(*i); |
310 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeInt32, | 325 Node* c = r.changer()->GetRepresentationFor( |
311 kRepWord32); | 326 n, |
| 327 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kInt32), |
| 328 MachineRepresentation::kWord32); |
312 r.CheckInt32Constant(c, *i); | 329 r.CheckInt32Constant(c, *i); |
313 } | 330 } |
314 } | 331 } |
315 | 332 |
316 { | 333 { |
317 FOR_INT32_INPUTS(i) { | 334 FOR_INT32_INPUTS(i) { |
318 Node* n = r.jsgraph()->Constant(*i); | 335 Node* n = r.jsgraph()->Constant(*i); |
319 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeInt32, | 336 Node* c = r.changer()->GetRepresentationFor( |
320 kRepWord32); | 337 n, |
| 338 MachineType(MachineRepresentation::kTagged, MachineSemantic::kInt32), |
| 339 MachineRepresentation::kWord32); |
321 r.CheckInt32Constant(c, *i); | 340 r.CheckInt32Constant(c, *i); |
322 } | 341 } |
323 } | 342 } |
324 } | 343 } |
325 | 344 |
326 | 345 |
327 TEST(ToUint32_constant) { | 346 TEST(ToUint32_constant) { |
328 RepresentationChangerTester r; | 347 RepresentationChangerTester r; |
329 | 348 |
330 { | 349 { |
331 FOR_UINT32_INPUTS(i) { | 350 FOR_UINT32_INPUTS(i) { |
332 Node* n = r.jsgraph()->Int32Constant(*i); | 351 Node* n = r.jsgraph()->Int32Constant(*i); |
333 Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, | 352 Node* c = r.changer()->GetRepresentationFor( |
334 kRepWord32); | 353 n, MachineType::Uint32(), MachineRepresentation::kWord32); |
335 r.CheckUint32Constant(c, *i); | 354 r.CheckUint32Constant(c, *i); |
336 } | 355 } |
337 } | 356 } |
338 | 357 |
339 { | 358 { |
340 FOR_UINT32_INPUTS(i) { | 359 FOR_UINT32_INPUTS(i) { |
341 if (!IsFloat32Uint32(*i)) continue; | 360 if (!IsFloat32Uint32(*i)) continue; |
342 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); | 361 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); |
343 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeUint32, | 362 Node* c = r.changer()->GetRepresentationFor( |
344 kRepWord32); | 363 n, MachineType(MachineRepresentation::kFloat32, |
| 364 MachineSemantic::kUint32), |
| 365 MachineRepresentation::kWord32); |
345 r.CheckUint32Constant(c, *i); | 366 r.CheckUint32Constant(c, *i); |
346 } | 367 } |
347 } | 368 } |
348 | 369 |
349 { | 370 { |
350 FOR_UINT32_INPUTS(i) { | 371 FOR_UINT32_INPUTS(i) { |
351 Node* n = r.jsgraph()->Float64Constant(*i); | 372 Node* n = r.jsgraph()->Float64Constant(*i); |
352 Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeUint32, | 373 Node* c = r.changer()->GetRepresentationFor( |
353 kRepWord32); | 374 n, MachineType(MachineRepresentation::kFloat64, |
| 375 MachineSemantic::kUint32), |
| 376 MachineRepresentation::kWord32); |
354 r.CheckUint32Constant(c, *i); | 377 r.CheckUint32Constant(c, *i); |
355 } | 378 } |
356 } | 379 } |
357 | 380 |
358 { | 381 { |
359 FOR_UINT32_INPUTS(i) { | 382 FOR_UINT32_INPUTS(i) { |
360 Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); | 383 Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); |
361 Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32, | 384 Node* c = r.changer()->GetRepresentationFor( |
362 kRepWord32); | 385 n, |
| 386 MachineType(MachineRepresentation::kTagged, MachineSemantic::kUint32), |
| 387 MachineRepresentation::kWord32); |
363 r.CheckUint32Constant(c, *i); | 388 r.CheckUint32Constant(c, *i); |
364 } | 389 } |
365 } | 390 } |
366 } | 391 } |
367 | 392 |
368 | 393 |
369 static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, | 394 static void CheckChange(IrOpcode::Value expected, MachineType from, |
370 MachineTypeUnion to) { | 395 MachineRepresentation to) { |
371 RepresentationChangerTester r; | 396 RepresentationChangerTester r; |
372 | 397 |
373 Node* n = r.Parameter(); | 398 Node* n = r.Parameter(); |
374 Node* c = r.changer()->GetRepresentationFor(n, from, to); | 399 Node* c = r.changer()->GetRepresentationFor(n, from, to); |
375 | 400 |
376 CHECK_NE(c, n); | 401 CHECK_NE(c, n); |
377 CHECK_EQ(expected, c->opcode()); | 402 CHECK_EQ(expected, c->opcode()); |
378 CHECK_EQ(n, c->InputAt(0)); | 403 CHECK_EQ(n, c->InputAt(0)); |
379 } | 404 } |
380 | 405 |
381 | 406 |
382 static void CheckTwoChanges(IrOpcode::Value expected2, | 407 static void CheckTwoChanges(IrOpcode::Value expected2, |
383 IrOpcode::Value expected1, MachineTypeUnion from, | 408 IrOpcode::Value expected1, MachineType from, |
384 MachineTypeUnion to) { | 409 MachineRepresentation to) { |
385 RepresentationChangerTester r; | 410 RepresentationChangerTester r; |
386 | 411 |
387 Node* n = r.Parameter(); | 412 Node* n = r.Parameter(); |
388 Node* c1 = r.changer()->GetRepresentationFor(n, from, to); | 413 Node* c1 = r.changer()->GetRepresentationFor(n, from, to); |
389 | 414 |
390 CHECK_NE(c1, n); | 415 CHECK_NE(c1, n); |
391 CHECK_EQ(expected1, c1->opcode()); | 416 CHECK_EQ(expected1, c1->opcode()); |
392 Node* c2 = c1->InputAt(0); | 417 Node* c2 = c1->InputAt(0); |
393 CHECK_NE(c2, n); | 418 CHECK_NE(c2, n); |
394 CHECK_EQ(expected2, c2->opcode()); | 419 CHECK_EQ(expected2, c2->opcode()); |
395 CHECK_EQ(n, c2->InputAt(0)); | 420 CHECK_EQ(n, c2->InputAt(0)); |
396 } | 421 } |
397 | 422 |
398 | 423 |
399 TEST(SingleChanges) { | 424 TEST(SingleChanges) { |
400 CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit); | 425 CheckChange(IrOpcode::kChangeBoolToBit, MachineType::RepTagged(), |
401 CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged); | 426 MachineRepresentation::kBit); |
| 427 CheckChange(IrOpcode::kChangeBitToBool, MachineType::RepBit(), |
| 428 MachineRepresentation::kTagged); |
402 | 429 |
403 CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32, | 430 CheckChange(IrOpcode::kChangeInt32ToTagged, MachineType::Int32(), |
404 kRepTagged); | 431 MachineRepresentation::kTagged); |
405 CheckChange(IrOpcode::kChangeUint32ToTagged, kRepWord32 | kTypeUint32, | 432 CheckChange(IrOpcode::kChangeUint32ToTagged, MachineType::Uint32(), |
406 kRepTagged); | 433 MachineRepresentation::kTagged); |
407 CheckChange(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, kRepTagged); | 434 CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineType::RepFloat64(), |
| 435 MachineRepresentation::kTagged); |
408 | 436 |
409 CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, | 437 CheckChange( |
410 kRepWord32); | 438 IrOpcode::kChangeTaggedToInt32, |
411 CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32, | 439 MachineType(MachineRepresentation::kTagged, MachineSemantic::kInt32), |
412 kRepWord32); | 440 MachineRepresentation::kWord32); |
413 CheckChange(IrOpcode::kChangeTaggedToFloat64, kRepTagged, kRepFloat64); | 441 CheckChange( |
| 442 IrOpcode::kChangeTaggedToUint32, |
| 443 MachineType(MachineRepresentation::kTagged, MachineSemantic::kUint32), |
| 444 MachineRepresentation::kWord32); |
| 445 CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineType::RepTagged(), |
| 446 MachineRepresentation::kFloat64); |
414 | 447 |
415 // Int32,Uint32 <-> Float64 are actually machine conversions. | 448 // Int32,Uint32 <-> Float64 are actually machine conversions. |
416 CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32 | kTypeInt32, | 449 CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineType::Int32(), |
417 kRepFloat64); | 450 MachineRepresentation::kFloat64); |
418 CheckChange(IrOpcode::kChangeUint32ToFloat64, kRepWord32 | kTypeUint32, | 451 CheckChange(IrOpcode::kChangeUint32ToFloat64, MachineType::Uint32(), |
419 kRepFloat64); | 452 MachineRepresentation::kFloat64); |
420 CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32, | 453 CheckChange( |
421 kRepWord32); | 454 IrOpcode::kChangeFloat64ToInt32, |
422 CheckChange(IrOpcode::kChangeFloat64ToUint32, kRepFloat64 | kTypeUint32, | 455 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kInt32), |
423 kRepWord32); | 456 MachineRepresentation::kWord32); |
| 457 CheckChange( |
| 458 IrOpcode::kChangeFloat64ToUint32, |
| 459 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kUint32), |
| 460 MachineRepresentation::kWord32); |
424 | 461 |
425 CheckChange(IrOpcode::kTruncateFloat64ToFloat32, kRepFloat64, kRepFloat32); | 462 CheckChange(IrOpcode::kTruncateFloat64ToFloat32, MachineType::RepFloat64(), |
| 463 MachineRepresentation::kFloat32); |
426 | 464 |
427 // Int32,Uint32 <-> Float32 require two changes. | 465 // Int32,Uint32 <-> Float32 require two changes. |
428 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, | 466 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, |
429 IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeInt32, | 467 IrOpcode::kTruncateFloat64ToFloat32, MachineType::Int32(), |
430 kRepFloat32); | 468 MachineRepresentation::kFloat32); |
431 CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64, | 469 CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64, |
432 IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeUint32, | 470 IrOpcode::kTruncateFloat64ToFloat32, MachineType::Uint32(), |
433 kRepFloat32); | 471 MachineRepresentation::kFloat32); |
434 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 472 CheckTwoChanges( |
435 IrOpcode::kChangeFloat64ToInt32, kRepFloat32 | kTypeInt32, | 473 IrOpcode::kChangeFloat32ToFloat64, IrOpcode::kChangeFloat64ToInt32, |
436 kRepWord32); | 474 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kInt32), |
437 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 475 MachineRepresentation::kWord32); |
438 IrOpcode::kChangeFloat64ToUint32, kRepFloat32 | kTypeUint32, | 476 CheckTwoChanges( |
439 kRepWord32); | 477 IrOpcode::kChangeFloat32ToFloat64, IrOpcode::kChangeFloat64ToUint32, |
| 478 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kUint32), |
| 479 MachineRepresentation::kWord32); |
440 | 480 |
441 // Float32 <-> Tagged require two changes. | 481 // Float32 <-> Tagged require two changes. |
442 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 482 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, |
443 IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged); | 483 IrOpcode::kChangeFloat64ToTagged, MachineType::RepFloat32(), |
| 484 MachineRepresentation::kTagged); |
444 CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, | 485 CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, |
445 IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32); | 486 IrOpcode::kTruncateFloat64ToFloat32, MachineType::RepTagged(), |
| 487 MachineRepresentation::kFloat32); |
446 } | 488 } |
447 | 489 |
448 | 490 |
449 TEST(SignednessInWord32) { | 491 TEST(SignednessInWord32) { |
450 RepresentationChangerTester r; | 492 RepresentationChangerTester r; |
451 | 493 |
452 CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, | 494 CheckChange( |
453 kRepWord32); | 495 IrOpcode::kChangeTaggedToInt32, |
454 CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32, | 496 MachineType(MachineRepresentation::kTagged, MachineSemantic::kInt32), |
455 kRepWord32); | 497 MachineRepresentation::kWord32); |
456 CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64); | 498 CheckChange( |
457 CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32, | 499 IrOpcode::kChangeTaggedToUint32, |
458 kRepWord32); | 500 MachineType(MachineRepresentation::kTagged, MachineSemantic::kUint32), |
459 CheckChange(IrOpcode::kTruncateFloat64ToInt32, kRepFloat64, kRepWord32); | 501 MachineRepresentation::kWord32); |
| 502 CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineType::RepWord32(), |
| 503 MachineRepresentation::kFloat64); |
| 504 CheckChange( |
| 505 IrOpcode::kChangeFloat64ToInt32, |
| 506 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kInt32), |
| 507 MachineRepresentation::kWord32); |
| 508 CheckChange(IrOpcode::kTruncateFloat64ToInt32, MachineType::RepFloat64(), |
| 509 MachineRepresentation::kWord32); |
460 | 510 |
461 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, | 511 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, |
462 IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32); | 512 IrOpcode::kTruncateFloat64ToFloat32, MachineType::RepWord32(), |
| 513 MachineRepresentation::kFloat32); |
463 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, | 514 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, |
464 IrOpcode::kTruncateFloat64ToInt32, kRepFloat32, kRepWord32); | 515 IrOpcode::kTruncateFloat64ToInt32, MachineType::RepFloat32(), |
| 516 MachineRepresentation::kWord32); |
465 } | 517 } |
466 | 518 |
467 | 519 |
468 TEST(Nops) { | 520 TEST(Nops) { |
469 RepresentationChangerTester r; | 521 RepresentationChangerTester r; |
470 | 522 |
471 // X -> X is always a nop for any single representation X. | 523 // X -> X is always a nop for any single representation X. |
472 for (size_t i = 0; i < arraysize(all_reps); i++) { | 524 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { |
473 r.CheckNop(all_reps[i], all_reps[i]); | 525 r.CheckNop(kMachineTypes[i], kMachineTypes[i].representation()); |
474 } | 526 } |
475 | 527 |
476 // 32-bit floats. | 528 // 32-bit floats. |
477 r.CheckNop(kRepFloat32, kRepFloat32); | 529 r.CheckNop(MachineType::RepFloat32(), MachineRepresentation::kFloat32); |
478 r.CheckNop(kRepFloat32 | kTypeNumber, kRepFloat32); | 530 r.CheckNop(MachineType::Float32(), MachineRepresentation::kFloat32); |
479 | 531 |
480 // 32-bit words can be used as smaller word sizes and vice versa, because | 532 // 32-bit words can be used as smaller word sizes and vice versa, because |
481 // loads from memory implicitly sign or zero extend the value to the | 533 // loads from memory implicitly sign or zero extend the value to the |
482 // full machine word size, and stores implicitly truncate. | 534 // full machine word size, and stores implicitly truncate. |
483 r.CheckNop(kRepWord32, kRepWord8); | 535 r.CheckNop(MachineType::Int32(), MachineRepresentation::kWord8); |
484 r.CheckNop(kRepWord32, kRepWord16); | 536 r.CheckNop(MachineType::Int32(), MachineRepresentation::kWord16); |
485 r.CheckNop(kRepWord32, kRepWord32); | 537 r.CheckNop(MachineType::Int32(), MachineRepresentation::kWord32); |
486 r.CheckNop(kRepWord8, kRepWord32); | 538 r.CheckNop(MachineType::Int8(), MachineRepresentation::kWord32); |
487 r.CheckNop(kRepWord16, kRepWord32); | 539 r.CheckNop(MachineType::Int16(), MachineRepresentation::kWord32); |
488 | 540 |
489 // kRepBit (result of comparison) is implicitly a wordish thing. | 541 // kRepBit (result of comparison) is implicitly a wordish thing. |
490 r.CheckNop(kRepBit, kRepWord8); | 542 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord8); |
491 r.CheckNop(kRepBit | kTypeBool, kRepWord8); | 543 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord16); |
492 r.CheckNop(kRepBit, kRepWord16); | 544 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord32); |
493 r.CheckNop(kRepBit | kTypeBool, kRepWord16); | 545 r.CheckNop(MachineType::RepBit(), MachineRepresentation::kWord64); |
494 r.CheckNop(kRepBit, kRepWord32); | 546 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord8); |
495 r.CheckNop(kRepBit | kTypeBool, kRepWord32); | 547 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord16); |
496 r.CheckNop(kRepBit, kRepWord64); | 548 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord32); |
497 r.CheckNop(kRepBit | kTypeBool, kRepWord64); | 549 r.CheckNop(MachineType::Bool(), MachineRepresentation::kWord64); |
498 } | 550 } |
499 | 551 |
500 | 552 |
501 TEST(TypeErrors) { | 553 TEST(TypeErrors) { |
502 RepresentationChangerTester r; | 554 RepresentationChangerTester r; |
503 | 555 |
504 // Wordish cannot be implicitly converted to/from comparison conditions. | 556 // Wordish cannot be implicitly converted to/from comparison conditions. |
505 r.CheckTypeError(kRepWord8, kRepBit); | 557 r.CheckTypeError(MachineType::RepWord8(), MachineRepresentation::kBit); |
506 r.CheckTypeError(kRepWord16, kRepBit); | 558 r.CheckTypeError(MachineType::RepWord16(), MachineRepresentation::kBit); |
507 r.CheckTypeError(kRepWord32, kRepBit); | 559 r.CheckTypeError(MachineType::RepWord32(), MachineRepresentation::kBit); |
508 r.CheckTypeError(kRepWord64, kRepBit); | 560 r.CheckTypeError(MachineType::RepWord64(), MachineRepresentation::kBit); |
509 | 561 |
510 // Floats cannot be implicitly converted to/from comparison conditions. | 562 // Floats cannot be implicitly converted to/from comparison conditions. |
511 r.CheckTypeError(kRepFloat64, kRepBit); | 563 r.CheckTypeError(MachineType::RepFloat64(), MachineRepresentation::kBit); |
512 r.CheckTypeError(kRepBit, kRepFloat64); | 564 r.CheckTypeError(MachineType::RepBit(), MachineRepresentation::kFloat64); |
513 r.CheckTypeError(kRepBit | kTypeBool, kRepFloat64); | 565 r.CheckTypeError(MachineType::Bool(), MachineRepresentation::kFloat64); |
514 | 566 |
515 // Floats cannot be implicitly converted to/from comparison conditions. | 567 // Floats cannot be implicitly converted to/from comparison conditions. |
516 r.CheckTypeError(kRepFloat32, kRepBit); | 568 r.CheckTypeError(MachineType::RepFloat32(), MachineRepresentation::kBit); |
517 r.CheckTypeError(kRepBit, kRepFloat32); | 569 r.CheckTypeError(MachineType::RepBit(), MachineRepresentation::kFloat32); |
518 r.CheckTypeError(kRepBit | kTypeBool, kRepFloat32); | 570 r.CheckTypeError(MachineType::Bool(), MachineRepresentation::kFloat32); |
519 | 571 |
520 // Word64 is internal and shouldn't be implicitly converted. | 572 // Word64 is internal and shouldn't be implicitly converted. |
521 r.CheckTypeError(kRepWord64, kRepTagged); | 573 r.CheckTypeError(MachineType::RepWord64(), MachineRepresentation::kTagged); |
522 r.CheckTypeError(kRepTagged, kRepWord64); | 574 r.CheckTypeError(MachineType::RepTagged(), MachineRepresentation::kWord64); |
523 r.CheckTypeError(kRepTagged | kTypeBool, kRepWord64); | 575 r.CheckTypeError(MachineType::TaggedBool(), MachineRepresentation::kWord64); |
524 | 576 |
525 // Word64 / Word32 shouldn't be implicitly converted. | 577 // Word64 / Word32 shouldn't be implicitly converted. |
526 r.CheckTypeError(kRepWord64, kRepWord32); | 578 r.CheckTypeError(MachineType::RepWord64(), MachineRepresentation::kWord32); |
527 r.CheckTypeError(kRepWord32, kRepWord64); | 579 r.CheckTypeError(MachineType::RepWord32(), MachineRepresentation::kWord64); |
528 r.CheckTypeError(kRepWord32 | kTypeInt32, kRepWord64); | 580 r.CheckTypeError(MachineType::Int32(), MachineRepresentation::kWord64); |
529 r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); | 581 r.CheckTypeError(MachineType::Uint32(), MachineRepresentation::kWord64); |
530 | |
531 for (size_t i = 0; i < arraysize(all_reps); i++) { | |
532 for (size_t j = 0; j < arraysize(all_reps); j++) { | |
533 if (i == j) continue; | |
534 // Only a single from representation is allowed. | |
535 r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); | |
536 } | |
537 } | |
538 } | 582 } |
539 | 583 |
540 } // namespace compiler | 584 } // namespace compiler |
541 } // namespace internal | 585 } // namespace internal |
542 } // namespace v8 | 586 } // namespace v8 |
OLD | NEW |