| 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 125 | 125 | 
| 126 | 126 | 
| 127 static void VisitBinop(InstructionSelector* selector, Node* node, | 127 static void VisitBinop(InstructionSelector* selector, Node* node, | 
| 128                        InstructionCode opcode) { | 128                        InstructionCode opcode) { | 
| 129   FlagsContinuation cont; | 129   FlagsContinuation cont; | 
| 130   VisitBinop(selector, node, opcode, &cont); | 130   VisitBinop(selector, node, opcode, &cont); | 
| 131 } | 131 } | 
| 132 | 132 | 
| 133 | 133 | 
| 134 void InstructionSelector::VisitLoad(Node* node) { | 134 void InstructionSelector::VisitLoad(Node* node) { | 
| 135   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 135   LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 
| 136   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |  | 
| 137   Mips64OperandGenerator g(this); | 136   Mips64OperandGenerator g(this); | 
| 138   Node* base = node->InputAt(0); | 137   Node* base = node->InputAt(0); | 
| 139   Node* index = node->InputAt(1); | 138   Node* index = node->InputAt(1); | 
| 140 | 139 | 
| 141   ArchOpcode opcode; | 140   ArchOpcode opcode; | 
| 142   switch (rep) { | 141   switch (load_rep.representation()) { | 
| 143     case kRepFloat32: | 142     case MachineRepresentation::kFloat32: | 
| 144       opcode = kMips64Lwc1; | 143       opcode = kMips64Lwc1; | 
| 145       break; | 144       break; | 
| 146     case kRepFloat64: | 145     case MachineRepresentation::kFloat64: | 
| 147       opcode = kMips64Ldc1; | 146       opcode = kMips64Ldc1; | 
| 148       break; | 147       break; | 
| 149     case kRepBit:  // Fall through. | 148     case MachineRepresentation::kBit:  // Fall through. | 
| 150     case kRepWord8: | 149     case MachineRepresentation::kWord8: | 
| 151       opcode = typ == kTypeUint32 ? kMips64Lbu : kMips64Lb; | 150       opcode = load_rep.IsUnsigned() ? kMips64Lbu : kMips64Lb; | 
| 152       break; | 151       break; | 
| 153     case kRepWord16: | 152     case MachineRepresentation::kWord16: | 
| 154       opcode = typ == kTypeUint32 ? kMips64Lhu : kMips64Lh; | 153       opcode = load_rep.IsUnsigned() ? kMips64Lhu : kMips64Lh; | 
| 155       break; | 154       break; | 
| 156     case kRepWord32: | 155     case MachineRepresentation::kWord32: | 
| 157       opcode = kMips64Lw; | 156       opcode = kMips64Lw; | 
| 158       break; | 157       break; | 
| 159     case kRepTagged:  // Fall through. | 158     case MachineRepresentation::kTagged:  // Fall through. | 
| 160     case kRepWord64: | 159     case MachineRepresentation::kWord64: | 
| 161       opcode = kMips64Ld; | 160       opcode = kMips64Ld; | 
| 162       break; | 161       break; | 
| 163     default: | 162     default: | 
| 164       UNREACHABLE(); | 163       UNREACHABLE(); | 
| 165       return; | 164       return; | 
| 166   } | 165   } | 
| 167 | 166 | 
| 168   if (g.CanBeImmediate(index, opcode)) { | 167   if (g.CanBeImmediate(index, opcode)) { | 
| 169     Emit(opcode | AddressingModeField::encode(kMode_MRI), | 168     Emit(opcode | AddressingModeField::encode(kMode_MRI), | 
| 170          g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 169          g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 
| 171   } else { | 170   } else { | 
| 172     InstructionOperand addr_reg = g.TempRegister(); | 171     InstructionOperand addr_reg = g.TempRegister(); | 
| 173     Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, | 172     Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, | 
| 174          g.UseRegister(index), g.UseRegister(base)); | 173          g.UseRegister(index), g.UseRegister(base)); | 
| 175     // Emit desired load opcode, using temp addr_reg. | 174     // Emit desired load opcode, using temp addr_reg. | 
| 176     Emit(opcode | AddressingModeField::encode(kMode_MRI), | 175     Emit(opcode | AddressingModeField::encode(kMode_MRI), | 
| 177          g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); | 176          g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); | 
| 178   } | 177   } | 
| 179 } | 178 } | 
| 180 | 179 | 
| 181 | 180 | 
| 182 void InstructionSelector::VisitStore(Node* node) { | 181 void InstructionSelector::VisitStore(Node* node) { | 
| 183   Mips64OperandGenerator g(this); | 182   Mips64OperandGenerator g(this); | 
| 184   Node* base = node->InputAt(0); | 183   Node* base = node->InputAt(0); | 
| 185   Node* index = node->InputAt(1); | 184   Node* index = node->InputAt(1); | 
| 186   Node* value = node->InputAt(2); | 185   Node* value = node->InputAt(2); | 
| 187 | 186 | 
| 188   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 187   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 
| 189   WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 188   WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 
| 190   MachineType rep = RepresentationOf(store_rep.machine_type()); | 189   MachineRepresentation rep = store_rep.machine_type().representation(); | 
| 191 | 190 | 
| 192   // TODO(mips): I guess this could be done in a better way. | 191   // TODO(mips): I guess this could be done in a better way. | 
| 193   if (write_barrier_kind != kNoWriteBarrier) { | 192   if (write_barrier_kind != kNoWriteBarrier) { | 
| 194     DCHECK_EQ(kRepTagged, rep); | 193     DCHECK_EQ(MachineRepresentation::kTagged, rep); | 
| 195     InstructionOperand inputs[3]; | 194     InstructionOperand inputs[3]; | 
| 196     size_t input_count = 0; | 195     size_t input_count = 0; | 
| 197     inputs[input_count++] = g.UseUniqueRegister(base); | 196     inputs[input_count++] = g.UseUniqueRegister(base); | 
| 198     inputs[input_count++] = g.UseUniqueRegister(index); | 197     inputs[input_count++] = g.UseUniqueRegister(index); | 
| 199     inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 198     inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 
| 200                                 ? g.UseRegister(value) | 199                                 ? g.UseRegister(value) | 
| 201                                 : g.UseUniqueRegister(value); | 200                                 : g.UseUniqueRegister(value); | 
| 202     RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 201     RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 
| 203     switch (write_barrier_kind) { | 202     switch (write_barrier_kind) { | 
| 204       case kNoWriteBarrier: | 203       case kNoWriteBarrier: | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 215         break; | 214         break; | 
| 216     } | 215     } | 
| 217     InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 216     InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 
| 218     size_t const temp_count = arraysize(temps); | 217     size_t const temp_count = arraysize(temps); | 
| 219     InstructionCode code = kArchStoreWithWriteBarrier; | 218     InstructionCode code = kArchStoreWithWriteBarrier; | 
| 220     code |= MiscField::encode(static_cast<int>(record_write_mode)); | 219     code |= MiscField::encode(static_cast<int>(record_write_mode)); | 
| 221     Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 220     Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 
| 222   } else { | 221   } else { | 
| 223     ArchOpcode opcode; | 222     ArchOpcode opcode; | 
| 224     switch (rep) { | 223     switch (rep) { | 
| 225       case kRepFloat32: | 224       case MachineRepresentation::kFloat32: | 
| 226         opcode = kMips64Swc1; | 225         opcode = kMips64Swc1; | 
| 227         break; | 226         break; | 
| 228       case kRepFloat64: | 227       case MachineRepresentation::kFloat64: | 
| 229         opcode = kMips64Sdc1; | 228         opcode = kMips64Sdc1; | 
| 230         break; | 229         break; | 
| 231       case kRepBit:  // Fall through. | 230       case MachineRepresentation::kBit:  // Fall through. | 
| 232       case kRepWord8: | 231       case MachineRepresentation::kWord8: | 
| 233         opcode = kMips64Sb; | 232         opcode = kMips64Sb; | 
| 234         break; | 233         break; | 
| 235       case kRepWord16: | 234       case MachineRepresentation::kWord16: | 
| 236         opcode = kMips64Sh; | 235         opcode = kMips64Sh; | 
| 237         break; | 236         break; | 
| 238       case kRepWord32: | 237       case MachineRepresentation::kWord32: | 
| 239         opcode = kMips64Sw; | 238         opcode = kMips64Sw; | 
| 240         break; | 239         break; | 
| 241       case kRepTagged:  // Fall through. | 240       case MachineRepresentation::kTagged:  // Fall through. | 
| 242       case kRepWord64: | 241       case MachineRepresentation::kWord64: | 
| 243         opcode = kMips64Sd; | 242         opcode = kMips64Sd; | 
| 244         break; | 243         break; | 
| 245       default: | 244       default: | 
| 246         UNREACHABLE(); | 245         UNREACHABLE(); | 
| 247         return; | 246         return; | 
| 248     } | 247     } | 
| 249 | 248 | 
| 250     if (g.CanBeImmediate(index, opcode)) { | 249     if (g.CanBeImmediate(index, opcode)) { | 
| 251       Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 250       Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 
| 252            g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 251            g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1220       } | 1219       } | 
| 1221     } | 1220     } | 
| 1222   } | 1221   } | 
| 1223 } | 1222 } | 
| 1224 | 1223 | 
| 1225 | 1224 | 
| 1226 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 1225 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 
| 1227 | 1226 | 
| 1228 | 1227 | 
| 1229 void InstructionSelector::VisitCheckedLoad(Node* node) { | 1228 void InstructionSelector::VisitCheckedLoad(Node* node) { | 
| 1230   MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 1229   CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); | 
| 1231   MachineType typ = TypeOf(OpParameter<MachineType>(node)); |  | 
| 1232   Mips64OperandGenerator g(this); | 1230   Mips64OperandGenerator g(this); | 
| 1233   Node* const buffer = node->InputAt(0); | 1231   Node* const buffer = node->InputAt(0); | 
| 1234   Node* const offset = node->InputAt(1); | 1232   Node* const offset = node->InputAt(1); | 
| 1235   Node* const length = node->InputAt(2); | 1233   Node* const length = node->InputAt(2); | 
| 1236   ArchOpcode opcode; | 1234   ArchOpcode opcode; | 
| 1237   switch (rep) { | 1235   switch (load_rep.representation()) { | 
| 1238     case kRepWord8: | 1236     case MachineRepresentation::kWord8: | 
| 1239       opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 1237       opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; | 
| 1240       break; | 1238       break; | 
| 1241     case kRepWord16: | 1239     case MachineRepresentation::kWord16: | 
| 1242       opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 1240       opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; | 
| 1243       break; | 1241       break; | 
| 1244     case kRepWord32: | 1242     case MachineRepresentation::kWord32: | 
| 1245       opcode = kCheckedLoadWord32; | 1243       opcode = kCheckedLoadWord32; | 
| 1246       break; | 1244       break; | 
| 1247     case kRepWord64: | 1245     case MachineRepresentation::kWord64: | 
| 1248       opcode = kCheckedLoadWord64; | 1246       opcode = kCheckedLoadWord64; | 
| 1249       break; | 1247       break; | 
| 1250     case kRepFloat32: | 1248     case MachineRepresentation::kFloat32: | 
| 1251       opcode = kCheckedLoadFloat32; | 1249       opcode = kCheckedLoadFloat32; | 
| 1252       break; | 1250       break; | 
| 1253     case kRepFloat64: | 1251     case MachineRepresentation::kFloat64: | 
| 1254       opcode = kCheckedLoadFloat64; | 1252       opcode = kCheckedLoadFloat64; | 
| 1255       break; | 1253       break; | 
| 1256     default: | 1254     default: | 
| 1257       UNREACHABLE(); | 1255       UNREACHABLE(); | 
| 1258       return; | 1256       return; | 
| 1259   } | 1257   } | 
| 1260   InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 1258   InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 
| 1261                                           ? g.UseImmediate(offset) | 1259                                           ? g.UseImmediate(offset) | 
| 1262                                           : g.UseRegister(offset); | 1260                                           : g.UseRegister(offset); | 
| 1263 | 1261 | 
| 1264   InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) | 1262   InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) | 
| 1265                                           ? g.CanBeImmediate(length, opcode) | 1263                                           ? g.CanBeImmediate(length, opcode) | 
| 1266                                                 ? g.UseImmediate(length) | 1264                                                 ? g.UseImmediate(length) | 
| 1267                                                 : g.UseRegister(length) | 1265                                                 : g.UseRegister(length) | 
| 1268                                           : g.UseRegister(length); | 1266                                           : g.UseRegister(length); | 
| 1269 | 1267 | 
| 1270   Emit(opcode | AddressingModeField::encode(kMode_MRI), | 1268   Emit(opcode | AddressingModeField::encode(kMode_MRI), | 
| 1271        g.DefineAsRegister(node), offset_operand, length_operand, | 1269        g.DefineAsRegister(node), offset_operand, length_operand, | 
| 1272        g.UseRegister(buffer)); | 1270        g.UseRegister(buffer)); | 
| 1273 } | 1271 } | 
| 1274 | 1272 | 
| 1275 | 1273 | 
| 1276 void InstructionSelector::VisitCheckedStore(Node* node) { | 1274 void InstructionSelector::VisitCheckedStore(Node* node) { | 
| 1277   MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 1275   MachineRepresentation rep = | 
|  | 1276       CheckedStoreRepresentationOf(node->op()).representation(); | 
| 1278   Mips64OperandGenerator g(this); | 1277   Mips64OperandGenerator g(this); | 
| 1279   Node* const buffer = node->InputAt(0); | 1278   Node* const buffer = node->InputAt(0); | 
| 1280   Node* const offset = node->InputAt(1); | 1279   Node* const offset = node->InputAt(1); | 
| 1281   Node* const length = node->InputAt(2); | 1280   Node* const length = node->InputAt(2); | 
| 1282   Node* const value = node->InputAt(3); | 1281   Node* const value = node->InputAt(3); | 
| 1283   ArchOpcode opcode; | 1282   ArchOpcode opcode; | 
| 1284   switch (rep) { | 1283   switch (rep) { | 
| 1285     case kRepWord8: | 1284     case MachineRepresentation::kWord8: | 
| 1286       opcode = kCheckedStoreWord8; | 1285       opcode = kCheckedStoreWord8; | 
| 1287       break; | 1286       break; | 
| 1288     case kRepWord16: | 1287     case MachineRepresentation::kWord16: | 
| 1289       opcode = kCheckedStoreWord16; | 1288       opcode = kCheckedStoreWord16; | 
| 1290       break; | 1289       break; | 
| 1291     case kRepWord32: | 1290     case MachineRepresentation::kWord32: | 
| 1292       opcode = kCheckedStoreWord32; | 1291       opcode = kCheckedStoreWord32; | 
| 1293       break; | 1292       break; | 
| 1294     case kRepWord64: | 1293     case MachineRepresentation::kWord64: | 
| 1295       opcode = kCheckedStoreWord64; | 1294       opcode = kCheckedStoreWord64; | 
| 1296       break; | 1295       break; | 
| 1297     case kRepFloat32: | 1296     case MachineRepresentation::kFloat32: | 
| 1298       opcode = kCheckedStoreFloat32; | 1297       opcode = kCheckedStoreFloat32; | 
| 1299       break; | 1298       break; | 
| 1300     case kRepFloat64: | 1299     case MachineRepresentation::kFloat64: | 
| 1301       opcode = kCheckedStoreFloat64; | 1300       opcode = kCheckedStoreFloat64; | 
| 1302       break; | 1301       break; | 
| 1303     default: | 1302     default: | 
| 1304       UNREACHABLE(); | 1303       UNREACHABLE(); | 
| 1305       return; | 1304       return; | 
| 1306   } | 1305   } | 
| 1307   InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 1306   InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 
| 1308                                           ? g.UseImmediate(offset) | 1307                                           ? g.UseImmediate(offset) | 
| 1309                                           : g.UseRegister(offset); | 1308                                           : g.UseRegister(offset); | 
| 1310 | 1309 | 
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1777          MachineOperatorBuilder::kFloat32RoundUp | | 1776          MachineOperatorBuilder::kFloat32RoundUp | | 
| 1778          MachineOperatorBuilder::kFloat64RoundTruncate | | 1777          MachineOperatorBuilder::kFloat64RoundTruncate | | 
| 1779          MachineOperatorBuilder::kFloat32RoundTruncate | | 1778          MachineOperatorBuilder::kFloat32RoundTruncate | | 
| 1780          MachineOperatorBuilder::kFloat64RoundTiesEven | | 1779          MachineOperatorBuilder::kFloat64RoundTiesEven | | 
| 1781          MachineOperatorBuilder::kFloat32RoundTiesEven; | 1780          MachineOperatorBuilder::kFloat32RoundTiesEven; | 
| 1782 } | 1781 } | 
| 1783 | 1782 | 
| 1784 }  // namespace compiler | 1783 }  // namespace compiler | 
| 1785 }  // namespace internal | 1784 }  // namespace internal | 
| 1786 }  // namespace v8 | 1785 }  // namespace v8 | 
| OLD | NEW | 
|---|