OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/compiler/simd-lowering.h" | |
6 | |
7 #include "src/assembler.h" | |
8 #include "src/compiler/js-graph.h" | |
9 #include "src/compiler/linkage.h" | |
10 #include "src/compiler/machine-operator.h" | |
11 #include "src/compiler/operator-properties.h" | |
12 #include "src/compiler/simplified-operator.h" | |
13 | |
14 namespace v8 { | |
15 namespace internal { | |
16 namespace compiler { | |
17 | |
18 SimdLowering::~SimdLowering() {} | |
19 | |
20 Reduction SimdLowering::Reduce(Node* node) { | |
21 // For now lower everything to runtime calls. | |
22 switch (node->opcode()) { | |
23 case IrOpcode::kCreateInt32x4: { | |
24 Conversion signature[] = {kOpaque, kInt32, kInt32, kInt32, kInt32}; | |
25 return ChangeToRuntimeCall(node, Runtime::kCreateInt32x4, signature); | |
26 } | |
27 case IrOpcode::kCreateInt16x8: { | |
28 Conversion signature[] = { | |
titzer
2016/05/19 09:58:38
You can use "static const" here to make the C++ co
gdeepti
2016/07/01 22:24:47
Done.
| |
29 kOpaque, kInt32, kInt32, kInt32, kInt32, | |
30 kInt32, kInt32, kInt32, kInt32, | |
31 }; | |
32 return ChangeToRuntimeCall(node, Runtime::kCreateInt16x8, signature); | |
33 } | |
34 case IrOpcode::kCreateInt8x16: { | |
35 Conversion signature[] = { | |
36 kOpaque, kInt32, kInt32, kInt32, kInt32, kInt32, | |
37 kInt32, kInt32, kInt32, kInt32, kInt32, kInt32, | |
38 kInt32, kInt32, kInt32, kInt32, kInt32, | |
39 }; | |
40 return ChangeToRuntimeCall(node, Runtime::kCreateInt8x16, signature); | |
41 } | |
42 case IrOpcode::kCreateFloat32x4: { | |
43 Conversion signature[] = {kOpaque, kFloat32, kFloat32, kFloat32, | |
44 kFloat32}; | |
45 return ChangeToRuntimeCall(node, Runtime::kCreateFloat32x4, signature); | |
46 } | |
47 case IrOpcode::kInt8x16ExtractLane: | |
48 case IrOpcode::kInt16x8ExtractLane: | |
49 case IrOpcode::kInt32x4ExtractLane: { | |
50 Conversion signature[] = {kInt32, kOpaque, kInt32}; | |
51 return ChangeToRuntimeCall(node, Runtime::kInt32x4ExtractLane, signature); | |
52 } | |
53 case IrOpcode::kFloat32x4ExtractLane: { | |
54 Conversion signature[] = {kFloat32, kOpaque, kInt32}; | |
55 return ChangeToRuntimeCall(node, Runtime::kFloat32x4ExtractLane, | |
56 signature); | |
57 } | |
58 default: { break; } | |
59 } | |
60 // TODO(gdeepti): Implement and test. | |
61 // Assume the others are all just simd in and out. | |
62 switch (node->opcode()) { | |
63 #define F(Opcode) \ | |
64 case IrOpcode::k##Opcode: { \ | |
65 Conversion signature[17] = { \ | |
66 kNone, kNone, kNone, kNone, kNone, kNone, kNone, kNone, kNone, \ | |
67 kNone, kNone, kNone, kNone, kNone, kNone, kNone, kNone, \ | |
bbudge
2016/05/19 09:53:13
I'm not sure what the compiler does with this repe
gdeepti
2016/07/01 22:24:48
Done.
| |
68 }; \ | |
69 return ChangeToRuntimeCall(node, Runtime::k##Opcode, signature); \ | |
70 } | |
71 MACHINE_SIMD_RETURN_SIMD_OP_LIST(F) | |
72 MACHINE_SIMD_RETURN_BOOL_OP_LIST(F) | |
73 #undef F | |
74 default: { return NoChange(); } | |
75 } | |
76 UNREACHABLE(); | |
77 return NoChange(); | |
78 } | |
79 | |
80 Reduction SimdLowering::ChangeToRuntimeCall(Node* node, Runtime::FunctionId f, | |
81 Conversion* signature) { | |
82 SimplifiedOperatorBuilder simplified(jsgraph()->zone()); | |
83 const Runtime::Function* fun = Runtime::FunctionForId(f); | |
84 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( | |
85 jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties, | |
86 CallDescriptor::kNoFlags); | |
87 Node* inputs[16 + 6]; | |
bbudge
2016/05/19 09:53:13
Need some constants defined for these magic number
gdeepti
2016/07/01 22:24:47
Done.
| |
88 DCHECK_LE(fun->nargs + 6, static_cast<int>(arraysize(inputs))); | |
89 // Either there are control + effect or not. | |
90 DCHECK(node->InputCount() == fun->nargs || | |
91 node->InputCount() == fun->nargs + 2); | |
92 int index = 0; | |
93 inputs[index++] = jsgraph()->CEntryStubConstant(fun->result_size); | |
94 for (int i = 0; i < fun->nargs; ++i) { | |
95 Node* arg = node->InputAt(i); | |
96 switch (signature[i + 1]) { | |
97 case kInt32: | |
98 arg = builder_->BuildChangeInt32ToTagged(arg); | |
99 break; | |
100 case kFloat32: | |
101 arg = jsgraph()->graph()->NewNode( | |
102 jsgraph()->machine()->ChangeFloat32ToFloat64(), arg); | |
103 arg = builder_->BuildChangeFloat64ToTagged(arg); | |
104 break; | |
105 case kFloat64: | |
106 arg = builder_->BuildChangeFloat64ToTagged(arg); | |
107 break; | |
108 default: | |
109 break; | |
110 } | |
111 inputs[index++] = arg; | |
112 } | |
113 inputs[index++] = | |
114 jsgraph()->ExternalConstant(ExternalReference(f, jsgraph()->isolate())); | |
115 inputs[index++] = jsgraph()->Int32Constant(fun->nargs); | |
116 inputs[index++] = jsgraph()->Constant(context_); | |
117 // Loads and stores have control and effect, others do not and use | |
118 // the start node instead. | |
119 if (node->InputCount() == fun->nargs + 2) { | |
120 inputs[index++] = node->InputAt(fun->nargs + 1); // effect | |
121 inputs[index++] = node->InputAt(fun->nargs + 2); // control | |
122 } else { | |
123 inputs[index++] = jsgraph()->graph()->start(); // effect | |
124 inputs[index++] = jsgraph()->graph()->start(); // control | |
125 } | |
126 Node* ret = jsgraph()->graph()->NewNode(jsgraph()->common()->Call(desc), | |
127 index, inputs); | |
128 switch (signature[0]) { | |
bbudge
2016/05/19 09:53:14
Maybe this would benefit with a well named local,
gdeepti
2016/07/01 22:24:47
Done.
| |
129 case kInt32: | |
130 ret = builder_->BuildChangeTaggedToInt32(ret); | |
131 break; | |
132 case kFloat32: | |
133 NodeProperties::SetType(ret, Type::Number()); | |
134 ret = builder_->BuildChangeTaggedToFloat64(ret); | |
135 ret = jsgraph()->graph()->NewNode( | |
136 jsgraph()->machine()->TruncateInt64ToInt32(), ret); | |
137 break; | |
138 case kFloat64: | |
139 ret = builder_->BuildChangeTaggedToFloat64(ret); | |
140 break; | |
141 default: | |
142 break; | |
143 } | |
144 return Replace(ret); | |
145 } | |
146 | |
147 } // namespace compiler | |
148 } // namespace internal | |
149 } // namespace v8 | |
OLD | NEW |