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

Side by Side Diff: src/IceInstARM32.cpp

Issue 1665323002: Clean up assembling MOV instructions in the integrated ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Format Created 4 years, 10 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
« no previous file with comments | « src/IceInstARM32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 Str << getPredicate() << WidthString; 1247 Str << getPredicate() << WidthString;
1248 } else { 1248 } else {
1249 Str << WidthString << getPredicate(); 1249 Str << WidthString << getPredicate();
1250 } 1250 }
1251 Str << "\t"; 1251 Str << "\t";
1252 Dest->emit(Func); 1252 Dest->emit(Func);
1253 Str << ", "; 1253 Str << ", ";
1254 Src0->emit(Func); 1254 Src0->emit(Func);
1255 } 1255 }
1256 1256
1257 void InstARM32Mov::emitIASScalarVFPMove(const Cfg *Func) const {
1258 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1259 Operand *Src0 = getSrc(0);
1260 Variable *Dest = getDest();
1261 switch (Dest->getType()) {
1262 default:
1263 assert(false && "Do not know how to emit scalar FP move for type.");
1264 break;
1265 case IceType_f32:
1266 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1267 Asm->vmovss(Dest, Var, getPredicate());
1268 return;
1269 } else if (const auto *FpImm =
1270 llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1271 Asm->vmovs(Dest, FpImm, getPredicate());
1272 return;
1273 }
1274 assert(!Asm->needsTextFixup());
1275 return;
1276 case IceType_f64:
1277 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1278 Asm->vmovdd(Dest, Var, getPredicate());
1279 return;
1280 } else if (const auto *FpImm =
1281 llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1282 Asm->vmovd(Dest, FpImm, getPredicate());
1283 return;
1284 }
1285 assert(!Asm->needsTextFixup());
1286 return;
1287 }
1288 // TODO(kschimpf) Handle register to register move.
1289 Asm->setNeedsTextFixup();
1290 return;
1291 }
1292
1293 void InstARM32Mov::emitIASCoreVFPMove(const Cfg *Func) const {
1294 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1295 Operand *Src0 = getSrc(0);
1296 if (!llvm::isa<Variable>(Src0))
1297 // TODO(kschimpf) Handle moving constants into registers.
1298 return Asm->setNeedsTextFixup();
1299
1300 // Move register to register.
1301 Variable *Dest = getDest();
1302 // TODO(kschimpf) Consider merging methods emitIAS.. methods into
1303 // a single case statement.
1304 switch (Dest->getType()) {
1305 default:
1306 // TODO(kschimpf): Fill this out more.
1307 return Asm->setNeedsTextFixup();
1308 case IceType_i1:
1309 case IceType_i8:
1310 case IceType_i16:
1311 case IceType_i32:
1312 assert(Src0->getType() == IceType_f32 && "Expected int to float move");
1313 Asm->vmovrs(Dest, Src0, getPredicate());
1314 return;
1315 case IceType_i64:
1316 assert(false && "i64 to float moves not handled here!");
1317 return;
1318 case IceType_f32:
1319 switch (Src0->getType()) {
1320 default:
1321 assert(false && "Expected float to int move");
1322 return;
1323 case IceType_i1:
1324 case IceType_i8:
1325 case IceType_i16:
1326 case IceType_i32:
1327 return Asm->vmovsr(Dest, Src0, getPredicate());
1328 }
1329 }
1330 }
1331
1332 void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const {
1333 Variable *Dest = getDest();
1334 Operand *Src0 = getSrc(0);
1335
1336 if (!Dest->hasReg()) {
1337 llvm::report_fatal_error("mov can't store.");
1338 }
1339
1340 if (isMemoryAccess(Src0)) {
1341 llvm::report_fatal_error("mov can't load.");
1342 }
1343
1344 if (isMoveBetweenCoreAndVFPRegisters(Dest, Src0))
1345 return emitIASCoreVFPMove(Func);
1346
1347 const Type DestTy = Dest->getType();
1348 if (isScalarFloatingType(DestTy))
1349 return emitIASScalarVFPMove(Func);
1350
1351 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1352 if (isVectorType(DestTy))
1353 return Asm->setNeedsTextFixup();
1354
1355 return Asm->mov(Dest, Src0, getPredicate());
1356 }
1357
1358 void InstARM32Mov::emit(const Cfg *Func) const { 1257 void InstARM32Mov::emit(const Cfg *Func) const {
1359 if (!BuildDefs::dump()) 1258 if (!BuildDefs::dump())
1360 return; 1259 return;
1361 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); 1260 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
1362 if (isMultiDest()) { 1261 if (isMultiDest()) {
1363 emitMultiDestSingleSource(Func); 1262 emitMultiDestSingleSource(Func);
1364 return; 1263 return;
1365 } 1264 }
1366 1265
1367 if (isMultiSource()) { 1266 if (isMultiSource()) {
1368 emitSingleDestMultiSource(Func); 1267 emitSingleDestMultiSource(Func);
1369 return; 1268 return;
1370 } 1269 }
1371 1270
1372 emitSingleDestSingleSource(Func); 1271 emitSingleDestSingleSource(Func);
1373 } 1272 }
1374 1273
1375 void InstARM32Mov::emitIAS(const Cfg *Func) const { 1274 void InstARM32Mov::emitIAS(const Cfg *Func) const {
1376 // TODO(kschimpf) Flatten this to a switch statement of dest type. That is,
1377 // combine code of emitIASSingleDestSingleSource, emitIASCoreVFPMove,
1378 // emitIASScalarVFPMove, emitDoubleToI64Move, and emitI64ToDoubleMove.
1379 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 1275 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1276 Variable *Dest = getDest();
1277 Operand *Src0 = getSrc(0);
1278 if (!Dest->hasReg()) {
1279 llvm::report_fatal_error("mov can't store.");
1280 }
1281 if (isMemoryAccess(Src0)) {
1282 llvm::report_fatal_error("mov can't load.");
1283 }
1284
1380 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); 1285 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
1381 if (isMultiDest()) 1286 if (isMultiDest()) {
1382 Asm->vmovrrd(getDest(), getDestHi(), getSrc(0), getPredicate()); 1287 Asm->vmovrrd(Dest, getDestHi(), Src0, getPredicate());
1383 else if (isMultiSource()) 1288 return;
1384 Asm->vmovdrr(getDest(), getSrc(0), getSrc(1), getPredicate()); 1289 }
1385 else 1290 if (isMultiSource()) {
1386 emitIASSingleDestSingleSource(Func); 1291 Asm->vmovdrr(Dest, Src0, getSrc(1), getPredicate());
1387 if (Asm->needsTextFixup()) 1292 return;
1293 }
1294
1295 const Type DestTy = Dest->getType();
1296 const Type SrcTy = Src0->getType();
1297 switch (DestTy) {
1298 case IceType_void:
Jim Stichnoth 2016/02/05 00:56:23 Consider just using "default:", for symmetry with
Karl 2016/02/05 15:27:08 Done.
1299 case IceType_NUM:
1300 break; // Error
1301 case IceType_i1:
1302 case IceType_i8:
1303 case IceType_i16:
1304 case IceType_i32:
1305 switch (SrcTy) {
1306 default:
1307 break; // Error
1308 case IceType_i1:
1309 case IceType_i8:
1310 case IceType_i16:
1311 case IceType_i32:
1312 case IceType_i64:
1313 Asm->mov(Dest, Src0, getPredicate());
1314 return;
1315 case IceType_f32:
1316 Asm->vmovrs(Dest, Src0, getPredicate());
1317 return;
1318 }
1319 break; // Error
1320 case IceType_i64:
1321 if (isScalarIntegerType(SrcTy)) {
1322 Asm->mov(Dest, Src0, getPredicate());
1323 return;
1324 }
1325 if (SrcTy == IceType_f64) {
1326 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1327 Asm->vmovdd(Dest, Var, getPredicate());
1328 return;
1329 } else if (const auto *FpImm =
Jim Stichnoth 2016/02/05 00:56:23 Don't use "else if" after a clause that ends with
Karl 2016/02/05 15:27:08 Done.
1330 llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1331 Asm->vmovd(Dest, FpImm, getPredicate());
1332 return;
1333 }
1334 }
1335 break; // Error
1336 case IceType_f32:
1337 switch (SrcTy) {
1338 default:
1339 break; // Error
1340 case IceType_i1:
1341 case IceType_i8:
1342 case IceType_i16:
1343 case IceType_i32:
1344 return Asm->vmovsr(Dest, Src0, getPredicate());
1345 case IceType_f32:
1346 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1347 Asm->vmovss(Dest, Var, getPredicate());
1348 return;
1349 } else if (const auto *FpImm =
1350 llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1351 Asm->vmovs(Dest, FpImm, getPredicate());
1352 return;
1353 }
1354 break; // Error
1355 }
1356 break; // Error
1357 case IceType_f64:
1358 if (SrcTy == IceType_f64) {
1359 if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
1360 Asm->vmovdd(Dest, Var, getPredicate());
1361 return;
1362 } else if (const auto *FpImm =
1363 llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
1364 Asm->vmovd(Dest, FpImm, getPredicate());
1365 return;
1366 }
1367 }
1368 break; // Error
1369 case IceType_v4i1:
1370 case IceType_v8i1:
1371 case IceType_v16i1:
1372 case IceType_v16i8:
1373 case IceType_v8i16:
1374 case IceType_v4i32:
1375 case IceType_v4f32:
1376 // TODO(kschimpf): Add vector moves.
1388 emitUsingTextFixup(Func); 1377 emitUsingTextFixup(Func);
1378 return;
1379 }
1380 llvm::report_fatal_error("Mov: don't know how to move " +
1381 typeIceString(SrcTy) + " to " +
1382 typeIceString(DestTy));
1389 } 1383 }
1390 1384
1391 void InstARM32Mov::dump(const Cfg *Func) const { 1385 void InstARM32Mov::dump(const Cfg *Func) const {
1392 if (!BuildDefs::dump()) 1386 if (!BuildDefs::dump())
1393 return; 1387 return;
1394 assert(getSrcSize() == 1 || getSrcSize() == 2); 1388 assert(getSrcSize() == 1 || getSrcSize() == 2);
1395 Ostream &Str = Func->getContext()->getStrDump(); 1389 Ostream &Str = Func->getContext()->getStrDump();
1396 Variable *Dest = getDest(); 1390 Variable *Dest = getDest();
1397 Variable *DestHi = getDestHi(); 1391 Variable *DestHi = getDestHi();
1398 Dest->dump(Func); 1392 Dest->dump(Func);
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 2541
2548 template class InstARM32FourAddrGPR<InstARM32::Mla>; 2542 template class InstARM32FourAddrGPR<InstARM32::Mla>;
2549 template class InstARM32FourAddrGPR<InstARM32::Mls>; 2543 template class InstARM32FourAddrGPR<InstARM32::Mls>;
2550 2544
2551 template class InstARM32CmpLike<InstARM32::Cmn>; 2545 template class InstARM32CmpLike<InstARM32::Cmn>;
2552 template class InstARM32CmpLike<InstARM32::Cmp>; 2546 template class InstARM32CmpLike<InstARM32::Cmp>;
2553 template class InstARM32CmpLike<InstARM32::Tst>; 2547 template class InstARM32CmpLike<InstARM32::Tst>;
2554 2548
2555 } // end of namespace ARM32 2549 } // end of namespace ARM32
2556 } // end of namespace Ice 2550 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstARM32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698