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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 } | 171 } |
172 | 172 |
173 | 173 |
174 void InstructionSelector::VisitStore(Node* node) { | 174 void InstructionSelector::VisitStore(Node* node) { |
175 MipsOperandGenerator g(this); | 175 MipsOperandGenerator g(this); |
176 Node* base = node->InputAt(0); | 176 Node* base = node->InputAt(0); |
177 Node* index = node->InputAt(1); | 177 Node* index = node->InputAt(1); |
178 Node* value = node->InputAt(2); | 178 Node* value = node->InputAt(2); |
179 | 179 |
180 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 180 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 181 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
181 MachineType rep = RepresentationOf(store_rep.machine_type()); | 182 MachineType rep = RepresentationOf(store_rep.machine_type()); |
182 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { | |
183 DCHECK(rep == kRepTagged); | |
184 // TODO(dcarney): refactor RecordWrite function to take temp registers | |
185 // and pass them here instead of using fixed regs | |
186 // TODO(dcarney): handle immediate indices. | |
187 InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; | |
188 Emit(kMipsStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0), | |
189 g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); | |
190 return; | |
191 } | |
192 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | |
193 | 183 |
194 ArchOpcode opcode; | 184 // TODO(mips): I guess this could be done in a better way. |
195 switch (rep) { | 185 if (write_barrier_kind != kNoWriteBarrier) { |
196 case kRepFloat32: | 186 DCHECK_EQ(kRepTagged, rep); |
197 opcode = kMipsSwc1; | 187 InstructionOperand inputs[3]; |
198 break; | 188 size_t input_count = 0; |
199 case kRepFloat64: | 189 inputs[input_count++] = g.UseUniqueRegister(base); |
200 opcode = kMipsSdc1; | 190 inputs[input_count++] = g.UseUniqueRegister(index); |
201 break; | 191 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
202 case kRepBit: // Fall through. | 192 ? g.UseRegister(value) |
203 case kRepWord8: | 193 : g.UseUniqueRegister(value); |
204 opcode = kMipsSb; | 194 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
205 break; | 195 switch (write_barrier_kind) { |
206 case kRepWord16: | 196 case kNoWriteBarrier: |
207 opcode = kMipsSh; | 197 UNREACHABLE(); |
208 break; | 198 break; |
209 case kRepTagged: // Fall through. | 199 case kMapWriteBarrier: |
210 case kRepWord32: | 200 record_write_mode = RecordWriteMode::kValueIsMap; |
211 opcode = kMipsSw; | 201 break; |
212 break; | 202 case kPointerWriteBarrier: |
213 default: | 203 record_write_mode = RecordWriteMode::kValueIsPointer; |
214 UNREACHABLE(); | 204 break; |
215 return; | 205 case kFullWriteBarrier: |
216 } | 206 record_write_mode = RecordWriteMode::kValueIsAny; |
| 207 break; |
| 208 } |
| 209 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 210 size_t const temp_count = arraysize(temps); |
| 211 InstructionCode code = kArchStoreWithWriteBarrier; |
| 212 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 213 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 214 } else { |
| 215 ArchOpcode opcode; |
| 216 switch (rep) { |
| 217 case kRepFloat32: |
| 218 opcode = kMipsSwc1; |
| 219 break; |
| 220 case kRepFloat64: |
| 221 opcode = kMipsSdc1; |
| 222 break; |
| 223 case kRepBit: // Fall through. |
| 224 case kRepWord8: |
| 225 opcode = kMipsSb; |
| 226 break; |
| 227 case kRepWord16: |
| 228 opcode = kMipsSh; |
| 229 break; |
| 230 case kRepTagged: // Fall through. |
| 231 case kRepWord32: |
| 232 opcode = kMipsSw; |
| 233 break; |
| 234 default: |
| 235 UNREACHABLE(); |
| 236 return; |
| 237 } |
217 | 238 |
218 if (g.CanBeImmediate(index, opcode)) { | 239 if (g.CanBeImmediate(index, opcode)) { |
219 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 240 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
220 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 241 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
221 } else { | 242 } else { |
222 InstructionOperand addr_reg = g.TempRegister(); | 243 InstructionOperand addr_reg = g.TempRegister(); |
223 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, | 244 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, |
224 g.UseRegister(index), g.UseRegister(base)); | 245 g.UseRegister(index), g.UseRegister(base)); |
225 // Emit desired store opcode, using temp addr_reg. | 246 // Emit desired store opcode, using temp addr_reg. |
226 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 247 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
227 addr_reg, g.TempImmediate(0), g.UseRegister(value)); | 248 addr_reg, g.TempImmediate(0), g.UseRegister(value)); |
| 249 } |
228 } | 250 } |
229 } | 251 } |
230 | 252 |
231 | 253 |
232 void InstructionSelector::VisitWord32And(Node* node) { | 254 void InstructionSelector::VisitWord32And(Node* node) { |
233 VisitBinop(this, node, kMipsAnd); | 255 VisitBinop(this, node, kMipsAnd); |
234 } | 256 } |
235 | 257 |
236 | 258 |
237 void InstructionSelector::VisitWord32Or(Node* node) { | 259 void InstructionSelector::VisitWord32Or(Node* node) { |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 } | 1106 } |
1085 return flags | MachineOperatorBuilder::kFloat64Min | | 1107 return flags | MachineOperatorBuilder::kFloat64Min | |
1086 MachineOperatorBuilder::kFloat64Max | | 1108 MachineOperatorBuilder::kFloat64Max | |
1087 MachineOperatorBuilder::kFloat32Min | | 1109 MachineOperatorBuilder::kFloat32Min | |
1088 MachineOperatorBuilder::kFloat32Max; | 1110 MachineOperatorBuilder::kFloat32Max; |
1089 } | 1111 } |
1090 | 1112 |
1091 } // namespace compiler | 1113 } // namespace compiler |
1092 } // namespace internal | 1114 } // namespace internal |
1093 } // namespace v8 | 1115 } // namespace v8 |
OLD | NEW |