Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1139 MoveMemoryToMemory(destination.ToStackSlotAddress(), | 1139 MoveMemoryToMemory(destination.ToStackSlotAddress(), |
| 1140 source.ToStackSlotAddress()); | 1140 source.ToStackSlotAddress()); |
| 1141 } | 1141 } |
| 1142 } else if (source.IsFpuRegister()) { | 1142 } else if (source.IsFpuRegister()) { |
| 1143 if (destination.IsFpuRegister()) { | 1143 if (destination.IsFpuRegister()) { |
| 1144 __ vmovd(destination.fpu_reg(), source.fpu_reg()); | 1144 __ vmovd(destination.fpu_reg(), source.fpu_reg()); |
| 1145 } else { | 1145 } else { |
| 1146 if (destination.IsDoubleStackSlot()) { | 1146 if (destination.IsDoubleStackSlot()) { |
| 1147 __ vstrd(source.fpu_reg(), destination.ToStackSlotAddress()); | 1147 __ vstrd(source.fpu_reg(), destination.ToStackSlotAddress()); |
| 1148 } else { | 1148 } else { |
| 1149 ASSERT(destination.IsFloat32x4StackSlot() || | 1149 ASSERT(destination.IsQuadStackSlot()); |
| 1150 destination.IsUint32x4StackSlot()); | |
| 1151 UNIMPLEMENTED(); | 1150 UNIMPLEMENTED(); |
| 1152 } | 1151 } |
| 1153 } | 1152 } |
| 1154 } else if (source.IsDoubleStackSlot()) { | 1153 } else if (source.IsDoubleStackSlot()) { |
| 1155 if (destination.IsFpuRegister()) { | 1154 if (destination.IsFpuRegister()) { |
| 1156 __ vldrd(destination.fpu_reg(), source.ToStackSlotAddress()); | 1155 __ vldrd(destination.fpu_reg(), source.ToStackSlotAddress()); |
| 1157 } else { | 1156 } else { |
| 1158 ASSERT(destination.IsDoubleStackSlot()); | 1157 ASSERT(destination.IsDoubleStackSlot()); |
| 1159 __ vldrd(FpuTMP, source.ToStackSlotAddress()); | 1158 __ vldrd(FpuTMP, source.ToStackSlotAddress()); |
| 1160 __ vstrd(FpuTMP, destination.ToStackSlotAddress()); | 1159 __ vstrd(FpuTMP, destination.ToStackSlotAddress()); |
| 1161 } | 1160 } |
| 1162 } else if (source.IsFloat32x4StackSlot() || source.IsUint32x4StackSlot()) { | 1161 } else if (source.IsQuadStackSlot()) { |
| 1163 UNIMPLEMENTED(); | 1162 UNIMPLEMENTED(); |
| 1164 } else { | 1163 } else { |
| 1165 ASSERT(source.IsConstant()); | 1164 ASSERT(source.IsConstant()); |
| 1166 if (destination.IsRegister()) { | 1165 if (destination.IsRegister()) { |
| 1167 const Object& constant = source.constant(); | 1166 const Object& constant = source.constant(); |
| 1168 __ LoadObject(destination.reg(), constant); | 1167 __ LoadObject(destination.reg(), constant); |
| 1169 } else { | 1168 } else { |
| 1170 ASSERT(destination.IsStackSlot()); | 1169 ASSERT(destination.IsStackSlot()); |
| 1171 StoreObject(destination.ToStackSlotAddress(), source.constant()); | 1170 StoreObject(destination.ToStackSlotAddress(), source.constant()); |
| 1172 } | 1171 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1192 } else if (source.IsStackSlot() && destination.IsRegister()) { | 1191 } else if (source.IsStackSlot() && destination.IsRegister()) { |
| 1193 Exchange(destination.reg(), source.ToStackSlotAddress()); | 1192 Exchange(destination.reg(), source.ToStackSlotAddress()); |
| 1194 } else if (source.IsStackSlot() && destination.IsStackSlot()) { | 1193 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
| 1195 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); | 1194 Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress()); |
| 1196 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { | 1195 } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { |
| 1197 __ vmovd(FpuTMP, source.fpu_reg()); | 1196 __ vmovd(FpuTMP, source.fpu_reg()); |
| 1198 __ vmovd(source.fpu_reg(), destination.fpu_reg()); | 1197 __ vmovd(source.fpu_reg(), destination.fpu_reg()); |
| 1199 __ vmovd(destination.fpu_reg(), FpuTMP); | 1198 __ vmovd(destination.fpu_reg(), FpuTMP); |
| 1200 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { | 1199 } else if (source.IsFpuRegister() || destination.IsFpuRegister()) { |
| 1201 ASSERT(destination.IsDoubleStackSlot() || | 1200 ASSERT(destination.IsDoubleStackSlot() || |
| 1202 destination.IsFloat32x4StackSlot() || | 1201 destination.IsQuadStackSlot() || |
| 1203 destination.IsUint32x4StackSlot() || | |
| 1204 source.IsDoubleStackSlot() || | 1202 source.IsDoubleStackSlot() || |
| 1205 source.IsFloat32x4StackSlot() || | 1203 source.IsQuadStackSlot()); |
| 1206 source.IsUint32x4StackSlot()); | |
| 1207 bool double_width = destination.IsDoubleStackSlot() || | 1204 bool double_width = destination.IsDoubleStackSlot() || |
| 1208 source.IsDoubleStackSlot(); | 1205 source.IsDoubleStackSlot(); |
| 1209 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() | 1206 DRegister reg = source.IsFpuRegister() ? source.fpu_reg() |
| 1210 : destination.fpu_reg(); | 1207 : destination.fpu_reg(); |
| 1211 const Address& slot_address = source.IsFpuRegister() | 1208 const Address& slot_address = source.IsFpuRegister() |
| 1212 ? destination.ToStackSlotAddress() | 1209 ? destination.ToStackSlotAddress() |
| 1213 : source.ToStackSlotAddress(); | 1210 : source.ToStackSlotAddress(); |
| 1214 | 1211 |
| 1215 if (double_width) { | 1212 if (double_width) { |
| 1216 __ vldrd(FpuTMP, slot_address); | 1213 __ vldrd(FpuTMP, slot_address); |
| 1217 __ vstrd(reg, slot_address); | 1214 __ vstrd(reg, slot_address); |
| 1218 __ vmovd(reg, FpuTMP); | 1215 __ vmovd(reg, FpuTMP); |
| 1219 } else { | 1216 } else { |
| 1220 UNIMPLEMENTED(); | 1217 UNIMPLEMENTED(); |
| 1221 } | 1218 } |
| 1219 } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { | |
| 1220 const Address& source_slot_address = source.ToStackSlotAddress(); | |
| 1221 const Address& destination_slot_address = destination.ToStackSlotAddress(); | |
| 1222 | |
| 1223 ScratchFpuRegisterScope ensure_scratch(this, FpuTMP); | |
| 1224 __ vldrd(FpuTMP, source_slot_address); | |
| 1225 __ vldrd(ensure_scratch.reg(), destination_slot_address); | |
| 1226 __ vstrd(FpuTMP, destination_slot_address); | |
| 1227 __ vstrd(ensure_scratch.reg(), source_slot_address); | |
| 1228 } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) { | |
| 1229 UNIMPLEMENTED(); | |
| 1222 } else { | 1230 } else { |
| 1223 UNREACHABLE(); | 1231 UNREACHABLE(); |
| 1224 } | 1232 } |
| 1225 | 1233 |
| 1226 // The swap of source and destination has executed a move from source to | 1234 // The swap of source and destination has executed a move from source to |
| 1227 // destination. | 1235 // destination. |
| 1228 move->Eliminate(); | 1236 move->Eliminate(); |
| 1229 | 1237 |
| 1230 // Any unperformed (including pending) move with a source of either | 1238 // Any unperformed (including pending) move with a source of either |
| 1231 // this move's source or destination needs to have their source | 1239 // this move's source or destination needs to have their source |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1256 | 1264 |
| 1257 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { | 1265 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
| 1258 ASSERT(reg != IP); | 1266 ASSERT(reg != IP); |
| 1259 __ mov(IP, ShifterOperand(reg)); | 1267 __ mov(IP, ShifterOperand(reg)); |
| 1260 __ ldr(reg, mem); | 1268 __ ldr(reg, mem); |
| 1261 __ str(IP, mem); | 1269 __ str(IP, mem); |
| 1262 } | 1270 } |
| 1263 | 1271 |
| 1264 | 1272 |
| 1265 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1273 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1266 // TODO(vegorov): allocate temporary registers for such moves. | 1274 ScratchRegisterScope ensure_scratch(this, IP); |
|
regis
2013/04/09 15:29:27
IP is not an available register, so there is no ne
| |
| 1267 __ Push(R0); | 1275 __ ldr(ensure_scratch.reg(), mem1); |
| 1268 __ ldr(R0, mem1); | |
| 1269 __ ldr(IP, mem2); | 1276 __ ldr(IP, mem2); |
| 1277 __ str(ensure_scratch.reg(), mem2); | |
| 1270 __ str(IP, mem1); | 1278 __ str(IP, mem1); |
| 1271 __ str(R0, mem2); | |
| 1272 __ Pop(R0); | |
| 1273 } | 1279 } |
| 1274 | 1280 |
| 1275 | 1281 |
| 1282 void ParallelMoveResolver::SpillScratch(Register reg) { | |
| 1283 __ Push(reg); | |
| 1284 } | |
| 1285 | |
| 1286 | |
| 1287 void ParallelMoveResolver::RestoreScratch(Register reg) { | |
| 1288 __ Pop(reg); | |
| 1289 } | |
| 1290 | |
| 1291 | |
| 1292 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { | |
| 1293 __ vstrd(reg, Address(SP, -kDoubleSize, Address::PreIndex)); | |
| 1294 } | |
| 1295 | |
| 1296 | |
| 1297 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | |
| 1298 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); | |
| 1299 } | |
| 1300 | |
| 1301 | |
| 1276 #undef __ | 1302 #undef __ |
| 1277 | 1303 |
| 1278 } // namespace dart | 1304 } // namespace dart |
| 1279 | 1305 |
| 1280 #endif // defined TARGET_ARCH_ARM | 1306 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |