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

Side by Side Diff: src/ia32/lithium-ia32.cc

Issue 90643003: Experimental implementation: Exposing SIMD instructions into JavaScript Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 380
381 stream->Add(" length "); 381 stream->Add(" length ");
382 length()->PrintTo(stream); 382 length()->PrintTo(stream);
383 383
384 stream->Add(" index "); 384 stream->Add(" index ");
385 index()->PrintTo(stream); 385 index()->PrintTo(stream);
386 } 386 }
387 387
388 388
389 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) { 389 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
390 // Skip a slot if for a double-width slot. 390 switch (kind) {
391 if (kind == DOUBLE_REGISTERS) { 391 case GENERAL_REGISTERS: return spill_slot_count_++;
392 spill_slot_count_++; 392 case DOUBLE_REGISTERS: {
393 spill_slot_count_ |= 1; 393 // Skip a slot if for a double-width slot.
394 num_double_slots_++; 394 spill_slot_count_++;
395 spill_slot_count_ |= 1;
396 num_double_slots_++;
397 return spill_slot_count_++;
398 }
399 case FLOAT32x4_REGISTERS:
400 case INT32x4_REGISTERS: {
401 // Skip three slots if for a double-width slot.
402 spill_slot_count_ += 3;
403 num_double_slots_++; // for dynamic frame alignment
404 return spill_slot_count_++;
405 }
406 default:
407 UNREACHABLE();
408 return -1;
395 } 409 }
396 return spill_slot_count_++;
397 } 410 }
398 411
399 412
400 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { 413 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
401 int index = GetNextSpillIndex(kind); 414 int index = GetNextSpillIndex(kind);
402 if (kind == DOUBLE_REGISTERS) { 415 switch (kind) {
403 return LDoubleStackSlot::Create(index, zone()); 416 case GENERAL_REGISTERS: return LStackSlot::Create(index, zone());
404 } else { 417 case DOUBLE_REGISTERS: return LDoubleStackSlot::Create(index, zone());
405 ASSERT(kind == GENERAL_REGISTERS); 418 case FLOAT32x4_REGISTERS: return LFloat32x4StackSlot::Create(index, zone());
406 return LStackSlot::Create(index, zone()); 419 case INT32x4_REGISTERS: return LInt32x4StackSlot::Create(index, zone());
420 default:
421 UNREACHABLE();
422 return NULL;
407 } 423 }
408 } 424 }
409 425
410 426
411 void LStoreNamedField::PrintDataTo(StringStream* stream) { 427 void LStoreNamedField::PrintDataTo(StringStream* stream) {
412 object()->PrintTo(stream); 428 object()->PrintTo(stream);
413 hydrogen()->access().PrintTo(stream); 429 hydrogen()->access().PrintTo(stream);
414 stream->Add(" <- "); 430 stream->Add(" <- ");
415 value()->PrintTo(stream); 431 value()->PrintTo(stream);
416 } 432 }
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after
1977 // Only mark conversions that might need to allocate as calling rather than 1993 // Only mark conversions that might need to allocate as calling rather than
1978 // all changes. This makes simple, non-allocating conversion not have to force 1994 // all changes. This makes simple, non-allocating conversion not have to force
1979 // building a stack frame. 1995 // building a stack frame.
1980 if (from.IsTagged()) { 1996 if (from.IsTagged()) {
1981 if (to.IsDouble()) { 1997 if (to.IsDouble()) {
1982 LOperand* value = UseRegister(instr->value()); 1998 LOperand* value = UseRegister(instr->value());
1983 // Temp register only necessary for minus zero check. 1999 // Temp register only necessary for minus zero check.
1984 LOperand* temp = TempRegister(); 2000 LOperand* temp = TempRegister();
1985 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); 2001 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
1986 return AssignEnvironment(DefineAsRegister(res)); 2002 return AssignEnvironment(DefineAsRegister(res));
2003 } else if (to.IsFloat32x4()) {
2004 LOperand* value = UseRegister(instr->value());
2005 LOperand* temp = TempRegister();
2006 LTaggedToFloat32x4* res = new(zone()) LTaggedToFloat32x4(value, temp);
2007 return AssignEnvironment(DefineAsRegister(res));
2008 } else if (to.IsInt32x4()) {
2009 LOperand* value = UseRegister(instr->value());
2010 LOperand* temp = TempRegister();
2011 LTaggedToInt32x4* res = new(zone()) LTaggedToInt32x4(value, temp);
2012 return AssignEnvironment(DefineAsRegister(res));
1987 } else if (to.IsSmi()) { 2013 } else if (to.IsSmi()) {
1988 HValue* val = instr->value(); 2014 HValue* val = instr->value();
1989 LOperand* value = UseRegister(val); 2015 LOperand* value = UseRegister(val);
1990 if (val->type().IsSmi()) { 2016 if (val->type().IsSmi()) {
1991 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 2017 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1992 } 2018 }
1993 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 2019 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
1994 } else { 2020 } else {
1995 ASSERT(to.IsInteger32()); 2021 ASSERT(to.IsInteger32());
1996 HValue* val = instr->value(); 2022 HValue* val = instr->value();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 ASSERT(to.IsDouble()); 2086 ASSERT(to.IsDouble());
2061 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 2087 if (instr->value()->CheckFlag(HInstruction::kUint32)) {
2062 LOperand* temp = FixedTemp(xmm1); 2088 LOperand* temp = FixedTemp(xmm1);
2063 return DefineAsRegister( 2089 return DefineAsRegister(
2064 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp)); 2090 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
2065 } else { 2091 } else {
2066 return DefineAsRegister( 2092 return DefineAsRegister(
2067 new(zone()) LInteger32ToDouble(Use(instr->value()))); 2093 new(zone()) LInteger32ToDouble(Use(instr->value())));
2068 } 2094 }
2069 } 2095 }
2096 } else if (from.IsFloat32x4()) {
2097 ASSERT(to.IsTagged());
2098 info()->MarkAsDeferredCalling();
2099 LOperand* value = UseRegister(instr->value());
2100 LOperand* temp = TempRegister();
2101
2102 // Make sure that temp and result_temp are different registers.
2103 LUnallocated* result_temp = TempRegister();
2104 LFloat32x4ToTagged* result =
2105 new(zone()) LFloat32x4ToTagged(value, temp);
2106 return AssignPointerMap(Define(result, result_temp));
2107 } else if (from.IsInt32x4()) {
2108 ASSERT(to.IsTagged());
2109 info()->MarkAsDeferredCalling();
2110 LOperand* value = UseRegister(instr->value());
2111 LOperand* temp = TempRegister();
2112
2113 // Make sure that temp and result_temp are different registers.
2114 LUnallocated* result_temp = TempRegister();
2115 LInt32x4ToTagged* result = new(zone()) LInt32x4ToTagged(value, temp);
2116 return AssignPointerMap(Define(result, result_temp));
2070 } 2117 }
2071 UNREACHABLE(); 2118 UNREACHABLE();
2072 return NULL; 2119 return NULL;
2073 } 2120 }
2074 2121
2075 2122
2076 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 2123 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
2077 LOperand* value = UseAtStart(instr->value()); 2124 LOperand* value = UseAtStart(instr->value());
2078 return AssignEnvironment(new(zone()) LCheckNonSmi(value)); 2125 return AssignEnvironment(new(zone()) LCheckNonSmi(value));
2079 } 2126 }
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { 2323 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2277 ASSERT(instr->key()->representation().IsSmiOrInteger32()); 2324 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2278 ElementsKind elements_kind = instr->elements_kind(); 2325 ElementsKind elements_kind = instr->elements_kind();
2279 bool clobbers_key = ExternalArrayOpRequiresTemp( 2326 bool clobbers_key = ExternalArrayOpRequiresTemp(
2280 instr->key()->representation(), elements_kind); 2327 instr->key()->representation(), elements_kind);
2281 LOperand* key = clobbers_key 2328 LOperand* key = clobbers_key
2282 ? UseTempRegister(instr->key()) 2329 ? UseTempRegister(instr->key())
2283 : UseRegisterOrConstantAtStart(instr->key()); 2330 : UseRegisterOrConstantAtStart(instr->key());
2284 LLoadKeyed* result = NULL; 2331 LLoadKeyed* result = NULL;
2285 2332
2333 bool load_128bits_without_sse2 =
2334 ExternalArrayOpRequiresSpecialHandling(elements_kind);
2286 if (!instr->is_external()) { 2335 if (!instr->is_external()) {
2287 LOperand* obj = UseRegisterAtStart(instr->elements()); 2336 LOperand* obj = UseRegisterAtStart(instr->elements());
2288 result = new(zone()) LLoadKeyed(obj, key); 2337 result = new(zone()) LLoadKeyed(obj, key, NULL);
2289 } else { 2338 } else {
2290 ASSERT( 2339 ASSERT(
2291 (instr->representation().IsInteger32() && 2340 (instr->representation().IsInteger32() &&
2292 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && 2341 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
2293 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || 2342 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS) &&
2343 (elements_kind != EXTERNAL_FLOAT32x4_ELEMENTS) &&
2344 (elements_kind != EXTERNAL_INT32x4_ELEMENTS)) ||
2294 (instr->representation().IsDouble() && 2345 (instr->representation().IsDouble() &&
2295 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || 2346 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
2296 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); 2347 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))) ||
2348 (CpuFeatures::IsSupported(SSE2) ?
2349 instr->representation().IsFloat32x4() :
2350 instr->representation().IsTagged() &&
2351 elements_kind == EXTERNAL_FLOAT32x4_ELEMENTS) ||
2352 (CpuFeatures::IsSupported(SSE2) ?
2353 instr->representation().IsInt32x4() :
2354 instr->representation().IsTagged() &&
2355 elements_kind == EXTERNAL_INT32x4_ELEMENTS));
2297 LOperand* external_pointer = UseRegister(instr->elements()); 2356 LOperand* external_pointer = UseRegister(instr->elements());
2298 result = new(zone()) LLoadKeyed(external_pointer, key); 2357 result = new(zone()) LLoadKeyed(external_pointer, key,
2358 load_128bits_without_sse2 ? TempRegister() : NULL);
2359 if (load_128bits_without_sse2) info()->MarkAsDeferredCalling();
2299 } 2360 }
2300 2361
2301 DefineAsRegister(result); 2362 DefineAsRegister(result);
2302 bool can_deoptimize = instr->RequiresHoleCheck() || 2363 bool can_deoptimize = instr->RequiresHoleCheck() ||
2303 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS); 2364 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS);
2304 // An unsigned int array load might overflow and cause a deopt, make sure it 2365 // An unsigned int array load might overflow and cause a deopt, make sure it
2305 // has an environment. 2366 // has an environment.
2306 return can_deoptimize ? AssignEnvironment(result) : result; 2367 return can_deoptimize ? AssignEnvironment(result)
2368 : load_128bits_without_sse2 ? AssignPointerMap(result) : result;
2307 } 2369 }
2308 2370
2309 2371
2310 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 2372 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2311 LOperand* context = UseFixed(instr->context(), esi); 2373 LOperand* context = UseFixed(instr->context(), esi);
2312 LOperand* object = UseFixed(instr->object(), edx); 2374 LOperand* object = UseFixed(instr->object(), edx);
2313 LOperand* key = UseFixed(instr->key(), ecx); 2375 LOperand* key = UseFixed(instr->key(), ecx);
2314 2376
2315 LLoadKeyedGeneric* result = 2377 LLoadKeyedGeneric* result =
2316 new(zone()) LLoadKeyedGeneric(context, object, key); 2378 new(zone()) LLoadKeyedGeneric(context, object, key);
(...skipping 26 matching lines...) Expand all
2343 if (!instr->is_external()) { 2405 if (!instr->is_external()) {
2344 ASSERT(instr->elements()->representation().IsTagged()); 2406 ASSERT(instr->elements()->representation().IsTagged());
2345 ASSERT(instr->key()->representation().IsInteger32() || 2407 ASSERT(instr->key()->representation().IsInteger32() ||
2346 instr->key()->representation().IsSmi()); 2408 instr->key()->representation().IsSmi());
2347 2409
2348 if (instr->value()->representation().IsDouble()) { 2410 if (instr->value()->representation().IsDouble()) {
2349 LOperand* object = UseRegisterAtStart(instr->elements()); 2411 LOperand* object = UseRegisterAtStart(instr->elements());
2350 LOperand* val = NULL; 2412 LOperand* val = NULL;
2351 val = UseRegisterAtStart(instr->value()); 2413 val = UseRegisterAtStart(instr->value());
2352 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2414 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2353 return new(zone()) LStoreKeyed(object, key, val); 2415 return new(zone()) LStoreKeyed(object, key, val, NULL);
2354 } else { 2416 } else {
2355 ASSERT(instr->value()->representation().IsSmiOrTagged()); 2417 ASSERT(instr->value()->representation().IsSmiOrTagged());
2356 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2418 bool needs_write_barrier = instr->NeedsWriteBarrier();
2357 2419
2358 LOperand* obj = UseRegister(instr->elements()); 2420 LOperand* obj = UseRegister(instr->elements());
2359 LOperand* val; 2421 LOperand* val;
2360 LOperand* key; 2422 LOperand* key;
2361 if (needs_write_barrier) { 2423 if (needs_write_barrier) {
2362 val = UseTempRegister(instr->value()); 2424 val = UseTempRegister(instr->value());
2363 key = UseTempRegister(instr->key()); 2425 key = UseTempRegister(instr->key());
2364 } else { 2426 } else {
2365 val = UseRegisterOrConstantAtStart(instr->value()); 2427 val = UseRegisterOrConstantAtStart(instr->value());
2366 key = UseRegisterOrConstantAtStart(instr->key()); 2428 key = UseRegisterOrConstantAtStart(instr->key());
2367 } 2429 }
2368 return new(zone()) LStoreKeyed(obj, key, val); 2430 return new(zone()) LStoreKeyed(obj, key, val, NULL);
2369 } 2431 }
2370 } 2432 }
2371 2433
2372 ElementsKind elements_kind = instr->elements_kind(); 2434 ElementsKind elements_kind = instr->elements_kind();
2373 ASSERT( 2435 ASSERT(
2374 (instr->value()->representation().IsInteger32() && 2436 (instr->value()->representation().IsInteger32() &&
2375 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && 2437 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
2376 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || 2438 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS) &&
2439 (elements_kind != EXTERNAL_FLOAT32x4_ELEMENTS)) ||
2377 (instr->value()->representation().IsDouble() && 2440 (instr->value()->representation().IsDouble() &&
2378 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || 2441 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
2379 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); 2442 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))) ||
2443 (CpuFeatures::IsSupported(SSE2)
2444 ? instr->value()->representation().IsFloat32x4()
2445 : instr->value()->representation().IsTagged() &&
2446 elements_kind == EXTERNAL_FLOAT32x4_ELEMENTS) ||
2447 (CpuFeatures::IsSupported(SSE2)
2448 ? instr->value()->representation().IsInt32x4()
2449 : instr->value()->representation().IsTagged() &&
2450 elements_kind == EXTERNAL_INT32x4_ELEMENTS));
2380 ASSERT(instr->elements()->representation().IsExternal()); 2451 ASSERT(instr->elements()->representation().IsExternal());
2381 2452
2382 LOperand* external_pointer = UseRegister(instr->elements()); 2453 LOperand* external_pointer = UseRegister(instr->elements());
2383 LOperand* val = GetStoreKeyedValueOperand(instr); 2454 LOperand* val = GetStoreKeyedValueOperand(instr);
2384 bool clobbers_key = ExternalArrayOpRequiresTemp( 2455 bool clobbers_key = ExternalArrayOpRequiresTemp(
2385 instr->key()->representation(), elements_kind); 2456 instr->key()->representation(), elements_kind);
2386 LOperand* key = clobbers_key 2457 LOperand* key = clobbers_key
2387 ? UseTempRegister(instr->key()) 2458 ? UseTempRegister(instr->key())
2388 : UseRegisterOrConstantAtStart(instr->key()); 2459 : UseRegisterOrConstantAtStart(instr->key());
2389 return new(zone()) LStoreKeyed(external_pointer, 2460 bool store_128bits_without_sse2 =
2390 key, 2461 ExternalArrayOpRequiresSpecialHandling(elements_kind);
2391 val); 2462 LStoreKeyed* result =
2463 new(zone()) LStoreKeyed(external_pointer, key, val,
2464 store_128bits_without_sse2 ? TempRegister() : NULL);
2465 return store_128bits_without_sse2 ? AssignEnvironment(result) : result;
2392 } 2466 }
2393 2467
2394 2468
2395 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 2469 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2396 LOperand* context = UseFixed(instr->context(), esi); 2470 LOperand* context = UseFixed(instr->context(), esi);
2397 LOperand* object = UseFixed(instr->object(), edx); 2471 LOperand* object = UseFixed(instr->object(), edx);
2398 LOperand* key = UseFixed(instr->key(), ecx); 2472 LOperand* key = UseFixed(instr->key(), ecx);
2399 LOperand* value = UseFixed(instr->value(), eax); 2473 LOperand* value = UseFixed(instr->value(), eax);
2400 2474
2401 ASSERT(instr->object()->representation().IsTagged()); 2475 ASSERT(instr->object()->representation().IsTagged());
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2785 } 2859 }
2786 2860
2787 2861
2788 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2862 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2789 LOperand* object = UseRegister(instr->object()); 2863 LOperand* object = UseRegister(instr->object());
2790 LOperand* index = UseTempRegister(instr->index()); 2864 LOperand* index = UseTempRegister(instr->index());
2791 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2865 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2792 } 2866 }
2793 2867
2794 2868
2869 const char* LNullarySIMDOperation::Mnemonic() const {
2870 switch (op()) {
2871 case kFloat32x4Zero: return "float32x4-zero";
2872 default:
2873 UNREACHABLE();
2874 return NULL;
2875 }
2876 }
2877
2878
2879 LInstruction* LChunkBuilder::DoNullarySIMDOperation(
2880 HNullarySIMDOperation* instr) {
2881 LNullarySIMDOperation* result =
2882 new(zone()) LNullarySIMDOperation(instr->op());
2883 switch (instr->op()) {
2884 case kFloat32x4Zero:
2885 return DefineAsRegister(result);
2886 default:
2887 UNREACHABLE();
2888 return NULL;
2889 }
2890 }
2891
2892
2893 const char* LUnarySIMDOperation::Mnemonic() const {
2894 switch (op()) {
2895 case kFloat32x4OrInt32x4Change: return "float32x4_int32x4-change";
2896 case kSIMDAbs: return "simd-abs";
2897 case kSIMDNeg: return "simd-neg";
2898 case kSIMDNegU32: return "simd-negu32";
2899 case kSIMDReciprocal: return "simd-reciprocal";
2900 case kSIMDReciprocalSqrt: return "simd-reciprocalSqrt";
2901 case kSIMDSqrt: return "simd-sqrt";
2902 case kSIMDBitsToFloat32x4: return "simd-bitsToFloat32x4";
2903 case kSIMDToFloat32x4: return "simd-toFloat32x4";
2904 case kSIMDBitsToInt32x4: return "simd-bitsToInt32x4";
2905 case kSIMDToInt32x4: return "simd-toInt32x4";
2906 case kFloat32x4Splat: return "float32x4-splat";
2907 case kInt32x4Splat: return "int32x4-splat";
2908 case kFloat32x4SignMask: return "float32x4-signMask";
2909 case kFloat32x4X: return "float32x4-x";
2910 case kFloat32x4Y: return "float32x4-y";
2911 case kFloat32x4Z: return "float32x4-z";
2912 case kFloat32x4W: return "float32x4-w";
2913 case kInt32x4SignMask: return "int32x4-signMask";
2914 case kInt32x4X: return "int32x4-x";
2915 case kInt32x4Y: return "int32x4-y";
2916 case kInt32x4Z: return "int32x4-z";
2917 case kInt32x4W: return "int32x4-w";
2918 case kInt32x4FlagX: return "int32x4-flagX";
2919 case kInt32x4FlagY: return "int32x4-flagY";
2920 case kInt32x4FlagZ: return "int32x4-flagZ";
2921 case kInt32x4FlagW: return "int32x4-flagW";
2922 default:
2923 UNREACHABLE();
2924 return NULL;
2925 }
2926 }
2927
2928
2929 LInstruction* LChunkBuilder::DoUnarySIMDOperation(HUnarySIMDOperation* instr) {
2930 LOperand* input = UseRegisterAtStart(instr->value());
2931 LUnarySIMDOperation* result =
2932 new(zone()) LUnarySIMDOperation(input, instr->op());
2933 switch (instr->op()) {
2934 case kFloat32x4OrInt32x4Change:
2935 return AssignEnvironment(DefineAsRegister(result));
2936 case kSIMDAbs:
2937 case kSIMDNeg:
2938 case kSIMDNegU32:
2939 case kSIMDReciprocal:
2940 case kSIMDReciprocalSqrt:
2941 case kSIMDSqrt:
2942 return DefineSameAsFirst(result);
2943 case kSIMDBitsToFloat32x4:
2944 case kSIMDToFloat32x4:
2945 case kSIMDBitsToInt32x4:
2946 case kSIMDToInt32x4:
2947 case kFloat32x4Splat:
2948 case kInt32x4Splat:
2949 case kFloat32x4SignMask:
2950 case kFloat32x4X:
2951 case kFloat32x4Y:
2952 case kFloat32x4Z:
2953 case kFloat32x4W:
2954 case kInt32x4SignMask:
2955 case kInt32x4X:
2956 case kInt32x4Y:
2957 case kInt32x4Z:
2958 case kInt32x4W:
2959 case kInt32x4FlagX:
2960 case kInt32x4FlagY:
2961 case kInt32x4FlagZ:
2962 case kInt32x4FlagW:
2963 return DefineAsRegister(result);
2964 default:
2965 UNREACHABLE();
2966 return NULL;
2967 }
2968 }
2969
2970
2971 const char* LBinarySIMDOperation::Mnemonic() const {
2972 switch (op()) {
2973 case kSIMDAdd: return "simd-add";
2974 case kSIMDSub: return "simd-sub";
2975 case kSIMDMul: return "simd-mul";
2976 case kSIMDDiv: return "simd-mul";
2977 case kSIMDMin: return "simd-min";
2978 case kSIMDMax: return "simd-max";
2979 case kSIMDScale: return "simd-scale";
2980 case kSIMDAnd: return "simd-and";
2981 case kSIMDOr: return "simd-or";
2982 case kSIMDXor: return "simd-xor";
2983 case kSIMDAddU32: return "simd-addu32";
2984 case kSIMDSubU32: return "simd-subu32";
2985 case kSIMDMulU32: return "simd-mulu32";
2986 case kSIMDShuffle: return "simd-shuffle";
2987 case kSIMDShuffleU32: return "simd-shuffleu32";
2988 case kSIMDLessThan: return "simd-lessThan";
2989 case kSIMDLessThanOrEqual: return "simd-lessThanOrEqual";
2990 case kSIMDEqual: return "simd-equal";
2991 case kSIMDNotEqual: return "simd-notEqual";
2992 case kSIMDGreaterThanOrEqual: return "simd-greaterThanOrEqual";
2993 case kSIMDGreaterThan: return "simd-greaterThan";
2994 case kSIMDWithX: return "simd-withX";
2995 case kSIMDWithY: return "simd-withY";
2996 case kSIMDWithZ: return "simd-withZ";
2997 case kSIMDWithW: return "simd-withW";
2998 case kSIMDWithXu32: return "simd-withXu32";
2999 case kSIMDWithYu32: return "simd-withYu32";
3000 case kSIMDWithZu32: return "simd-withZu32";
3001 case kSIMDWithWu32: return "simd-withWu32";
3002 case kSIMDWithFlagX: return "simd-withFlagX";
3003 case kSIMDWithFlagY: return "simd-withFlagY";
3004 case kSIMDWithFlagZ: return "simd-withFlagZ";
3005 case kSIMDWithFlagW: return "simd-withFlagW";
3006 default:
3007 UNREACHABLE();
3008 return NULL;
3009 }
3010 }
3011
3012
3013 LInstruction* LChunkBuilder::DoBinarySIMDOperation(
3014 HBinarySIMDOperation* instr) {
3015 switch (instr->op()) {
3016 case kSIMDAdd:
3017 case kSIMDSub:
3018 case kSIMDMul:
3019 case kSIMDDiv:
3020 case kSIMDMin:
3021 case kSIMDMax:
3022 case kSIMDScale:
3023 case kSIMDAnd:
3024 case kSIMDOr:
3025 case kSIMDXor:
3026 case kSIMDAddU32:
3027 case kSIMDSubU32:
3028 case kSIMDMulU32:
3029 case kSIMDWithX:
3030 case kSIMDWithY:
3031 case kSIMDWithZ:
3032 case kSIMDWithW:
3033 case kSIMDWithXu32:
3034 case kSIMDWithYu32:
3035 case kSIMDWithZu32:
3036 case kSIMDWithWu32:
3037 case kSIMDWithFlagX:
3038 case kSIMDWithFlagY:
3039 case kSIMDWithFlagZ:
3040 case kSIMDWithFlagW: {
3041 LOperand* left = UseRegisterAtStart(instr->left());
3042 LOperand* right = UseRegisterAtStart(instr->right());
3043 LBinarySIMDOperation* result =
3044 new(zone()) LBinarySIMDOperation(left, right, instr->op());
3045 if (instr->op() == kSIMDWithFlagX || instr->op() == kSIMDWithFlagY ||
3046 instr->op() == kSIMDWithFlagZ || instr->op() == kSIMDWithFlagW) {
3047 return AssignEnvironment(DefineSameAsFirst(result));
3048 } else {
3049 return DefineSameAsFirst(result);
3050 }
3051 }
3052 case kSIMDShuffle:
3053 case kSIMDShuffleU32: {
3054 LOperand* left = UseRegisterAtStart(instr->left());
3055 LOperand* right = UseOrConstant(instr->right());
3056 LBinarySIMDOperation* result =
3057 new(zone()) LBinarySIMDOperation(left, right, instr->op());
3058 return AssignEnvironment(DefineSameAsFirst(result));
3059 }
3060 case kSIMDLessThan:
3061 case kSIMDLessThanOrEqual:
3062 case kSIMDEqual:
3063 case kSIMDNotEqual:
3064 case kSIMDGreaterThanOrEqual:
3065 case kSIMDGreaterThan: {
3066 LOperand* left = UseRegisterAtStart(instr->left());
3067 LOperand* right = UseRegisterAtStart(instr->right());
3068 LBinarySIMDOperation* result =
3069 new(zone()) LBinarySIMDOperation(left, right, instr->op());
3070 return DefineAsRegister(result);
3071 }
3072 default:
3073 UNREACHABLE();
3074 return NULL;
3075 }
3076 }
3077
3078
3079 const char* LTernarySIMDOperation::Mnemonic() const {
3080 switch (op()) {
3081 case kSIMDSelect: return "simd-select";
3082 case kSIMDShuffleMix: return "simd-shuffleMix";
3083 case kSIMDClamp: return "simd-clamp";
3084 default:
3085 UNREACHABLE();
3086 return NULL;
3087 }
3088 }
3089
3090
3091 LInstruction* LChunkBuilder::DoTernarySIMDOperation(
3092 HTernarySIMDOperation* instr) {
3093 LOperand* first = UseRegisterAtStart(instr->first());
3094 LOperand* second = UseRegisterAtStart(instr->second());
3095 LOperand* third = instr->op() == kSIMDShuffleMix
3096 ? UseOrConstant(instr->third())
3097 : UseRegisterAtStart(instr->third());
3098 LTernarySIMDOperation* result =
3099 new(zone()) LTernarySIMDOperation(first, second, third, instr->op());
3100 switch (instr->op()) {
3101 case kSIMDSelect: {
3102 return DefineAsRegister(result);
3103 }
3104 case kSIMDShuffleMix: {
3105 return AssignEnvironment(DefineSameAsFirst(result));
3106 }
3107 case kSIMDClamp: {
3108 return DefineSameAsFirst(result);
3109 }
3110 default:
3111 UNREACHABLE();
3112 return NULL;
3113 }
3114 }
3115
3116
3117 const char* LQuarternarySIMDOperation::Mnemonic() const {
3118 switch (op()) {
3119 case kFloat32x4Constructor: return "float32x4-constructor";
3120 case kInt32x4Constructor: return "int32x4-constructor";
3121 case kInt32x4Bool: return "int32x4-bool";
3122 default:
3123 UNREACHABLE();
3124 return NULL;
3125 }
3126 }
3127
3128
3129 LInstruction* LChunkBuilder::DoQuarternarySIMDOperation(
3130 HQuarternarySIMDOperation* instr) {
3131 LOperand* x = UseRegisterAtStart(instr->x());
3132 LOperand* y = UseRegisterAtStart(instr->y());
3133 LOperand* z = UseRegisterAtStart(instr->z());
3134 LOperand* w = UseRegisterAtStart(instr->w());
3135 LQuarternarySIMDOperation* result =
3136 new(zone()) LQuarternarySIMDOperation(x, y, z, w, instr->op());
3137 if (instr->op() == kInt32x4Bool) {
3138 return AssignEnvironment(DefineAsRegister(result));
3139 } else {
3140 return DefineAsRegister(result);
3141 }
3142 }
3143
3144
2795 } } // namespace v8::internal 3145 } } // namespace v8::internal
2796 3146
2797 #endif // V8_TARGET_ARCH_IA32 3147 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698