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 |