Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: runtime/vm/flow_graph_compiler_arm.cc

Issue 13801014: Fix bug in ParallelMoveResolver::EmitSwap: implement swaps of FPU spill slots. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698