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 "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 } | 179 } |
180 | 180 |
181 | 181 |
182 void InstructionSelector::VisitStore(Node* node) { | 182 void InstructionSelector::VisitStore(Node* node) { |
183 Mips64OperandGenerator g(this); | 183 Mips64OperandGenerator g(this); |
184 Node* base = node->InputAt(0); | 184 Node* base = node->InputAt(0); |
185 Node* index = node->InputAt(1); | 185 Node* index = node->InputAt(1); |
186 Node* value = node->InputAt(2); | 186 Node* value = node->InputAt(2); |
187 | 187 |
188 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 188 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 189 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
189 MachineType rep = RepresentationOf(store_rep.machine_type()); | 190 MachineType rep = RepresentationOf(store_rep.machine_type()); |
190 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { | |
191 DCHECK(rep == kRepTagged); | |
192 // TODO(dcarney): refactor RecordWrite function to take temp registers | |
193 // and pass them here instead of using fixed regs | |
194 // TODO(dcarney): handle immediate indices. | |
195 InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; | |
196 Emit(kMips64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0), | |
197 g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); | |
198 return; | |
199 } | |
200 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | |
201 | 191 |
202 ArchOpcode opcode; | 192 // TODO(mips): I guess this could be done in a better way. |
203 switch (rep) { | 193 if (write_barrier_kind != kNoWriteBarrier) { |
204 case kRepFloat32: | 194 DCHECK_EQ(kRepTagged, rep); |
205 opcode = kMips64Swc1; | 195 InstructionOperand inputs[3]; |
206 break; | 196 size_t input_count = 0; |
207 case kRepFloat64: | 197 inputs[input_count++] = g.UseUniqueRegister(base); |
208 opcode = kMips64Sdc1; | 198 inputs[input_count++] = g.UseUniqueRegister(index); |
209 break; | 199 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
210 case kRepBit: // Fall through. | 200 ? g.UseRegister(value) |
211 case kRepWord8: | 201 : g.UseUniqueRegister(value); |
212 opcode = kMips64Sb; | 202 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
213 break; | 203 switch (write_barrier_kind) { |
214 case kRepWord16: | 204 case kNoWriteBarrier: |
215 opcode = kMips64Sh; | 205 UNREACHABLE(); |
216 break; | 206 break; |
217 case kRepWord32: | 207 case kMapWriteBarrier: |
218 opcode = kMips64Sw; | 208 record_write_mode = RecordWriteMode::kValueIsMap; |
219 break; | 209 break; |
220 case kRepTagged: // Fall through. | 210 case kPointerWriteBarrier: |
221 case kRepWord64: | 211 record_write_mode = RecordWriteMode::kValueIsPointer; |
222 opcode = kMips64Sd; | 212 break; |
223 break; | 213 case kFullWriteBarrier: |
224 default: | 214 record_write_mode = RecordWriteMode::kValueIsAny; |
225 UNREACHABLE(); | 215 break; |
226 return; | 216 } |
227 } | 217 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 218 size_t const temp_count = arraysize(temps); |
| 219 InstructionCode code = kArchStoreWithWriteBarrier; |
| 220 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 221 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 222 } else { |
| 223 ArchOpcode opcode; |
| 224 switch (rep) { |
| 225 case kRepFloat32: |
| 226 opcode = kMips64Swc1; |
| 227 break; |
| 228 case kRepFloat64: |
| 229 opcode = kMips64Sdc1; |
| 230 break; |
| 231 case kRepBit: // Fall through. |
| 232 case kRepWord8: |
| 233 opcode = kMips64Sb; |
| 234 break; |
| 235 case kRepWord16: |
| 236 opcode = kMips64Sh; |
| 237 break; |
| 238 case kRepWord32: |
| 239 opcode = kMips64Sw; |
| 240 break; |
| 241 case kRepTagged: // Fall through. |
| 242 case kRepWord64: |
| 243 opcode = kMips64Sd; |
| 244 break; |
| 245 default: |
| 246 UNREACHABLE(); |
| 247 return; |
| 248 } |
228 | 249 |
229 if (g.CanBeImmediate(index, opcode)) { | 250 if (g.CanBeImmediate(index, opcode)) { |
230 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 251 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
231 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 252 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
232 } else { | 253 } else { |
233 InstructionOperand addr_reg = g.TempRegister(); | 254 InstructionOperand addr_reg = g.TempRegister(); |
234 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, | 255 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, |
235 g.UseRegister(index), g.UseRegister(base)); | 256 g.UseRegister(index), g.UseRegister(base)); |
236 // Emit desired store opcode, using temp addr_reg. | 257 // Emit desired store opcode, using temp addr_reg. |
237 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 258 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
238 addr_reg, g.TempImmediate(0), g.UseRegister(value)); | 259 addr_reg, g.TempImmediate(0), g.UseRegister(value)); |
| 260 } |
239 } | 261 } |
240 } | 262 } |
241 | 263 |
242 | 264 |
243 void InstructionSelector::VisitWord32And(Node* node) { | 265 void InstructionSelector::VisitWord32And(Node* node) { |
244 VisitBinop(this, node, kMips64And); | 266 VisitBinop(this, node, kMips64And); |
245 } | 267 } |
246 | 268 |
247 | 269 |
248 void InstructionSelector::VisitWord64And(Node* node) { | 270 void InstructionSelector::VisitWord64And(Node* node) { |
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 MachineOperatorBuilder::kFloat64Max | | 1375 MachineOperatorBuilder::kFloat64Max | |
1354 MachineOperatorBuilder::kFloat32Min | | 1376 MachineOperatorBuilder::kFloat32Min | |
1355 MachineOperatorBuilder::kFloat32Max | | 1377 MachineOperatorBuilder::kFloat32Max | |
1356 MachineOperatorBuilder::kFloat64RoundDown | | 1378 MachineOperatorBuilder::kFloat64RoundDown | |
1357 MachineOperatorBuilder::kFloat64RoundTruncate; | 1379 MachineOperatorBuilder::kFloat64RoundTruncate; |
1358 } | 1380 } |
1359 | 1381 |
1360 } // namespace compiler | 1382 } // namespace compiler |
1361 } // namespace internal | 1383 } // namespace internal |
1362 } // namespace v8 | 1384 } // namespace v8 |
OLD | NEW |