| Index: src/IceInstARM32.cpp
|
| diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
|
| index 64bdefa7224e75de7c8e4ed6c62aba0cc85d5564..9265515512ae3ac86954335bb09f4bd2cd896286 100644
|
| --- a/src/IceInstARM32.cpp
|
| +++ b/src/IceInstARM32.cpp
|
| @@ -1254,138 +1254,131 @@ void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
|
| Src0->emit(Func);
|
| }
|
|
|
| -void InstARM32Mov::emitIASScalarVFPMove(const Cfg *Func) const {
|
| - auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| - Operand *Src0 = getSrc(0);
|
| - Variable *Dest = getDest();
|
| - switch (Dest->getType()) {
|
| - default:
|
| - assert(false && "Do not know how to emit scalar FP move for type.");
|
| - break;
|
| - case IceType_f32:
|
| - if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
|
| - Asm->vmovss(Dest, Var, getPredicate());
|
| - return;
|
| - } else if (const auto *FpImm =
|
| - llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
|
| - Asm->vmovs(Dest, FpImm, getPredicate());
|
| - return;
|
| - }
|
| - assert(!Asm->needsTextFixup());
|
| +void InstARM32Mov::emit(const Cfg *Func) const {
|
| + if (!BuildDefs::dump())
|
| return;
|
| - case IceType_f64:
|
| - if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
|
| - Asm->vmovdd(Dest, Var, getPredicate());
|
| - return;
|
| - } else if (const auto *FpImm =
|
| - llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
|
| - Asm->vmovd(Dest, FpImm, getPredicate());
|
| - return;
|
| - }
|
| - assert(!Asm->needsTextFixup());
|
| + assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
|
| + if (isMultiDest()) {
|
| + emitMultiDestSingleSource(Func);
|
| return;
|
| }
|
| - // TODO(kschimpf) Handle register to register move.
|
| - Asm->setNeedsTextFixup();
|
| - return;
|
| -}
|
|
|
| -void InstARM32Mov::emitIASCoreVFPMove(const Cfg *Func) const {
|
| - auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| - Operand *Src0 = getSrc(0);
|
| - if (!llvm::isa<Variable>(Src0))
|
| - // TODO(kschimpf) Handle moving constants into registers.
|
| - return Asm->setNeedsTextFixup();
|
| -
|
| - // Move register to register.
|
| - Variable *Dest = getDest();
|
| - // TODO(kschimpf) Consider merging methods emitIAS.. methods into
|
| - // a single case statement.
|
| - switch (Dest->getType()) {
|
| - default:
|
| - // TODO(kschimpf): Fill this out more.
|
| - return Asm->setNeedsTextFixup();
|
| - case IceType_i1:
|
| - case IceType_i8:
|
| - case IceType_i16:
|
| - case IceType_i32:
|
| - assert(Src0->getType() == IceType_f32 && "Expected int to float move");
|
| - Asm->vmovrs(Dest, Src0, getPredicate());
|
| - return;
|
| - case IceType_i64:
|
| - assert(false && "i64 to float moves not handled here!");
|
| + if (isMultiSource()) {
|
| + emitSingleDestMultiSource(Func);
|
| return;
|
| - case IceType_f32:
|
| - switch (Src0->getType()) {
|
| - default:
|
| - assert(false && "Expected float to int move");
|
| - return;
|
| - case IceType_i1:
|
| - case IceType_i8:
|
| - case IceType_i16:
|
| - case IceType_i32:
|
| - return Asm->vmovsr(Dest, Src0, getPredicate());
|
| - }
|
| }
|
| +
|
| + emitSingleDestSingleSource(Func);
|
| }
|
|
|
| -void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const {
|
| +void InstARM32Mov::emitIAS(const Cfg *Func) const {
|
| + auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| Variable *Dest = getDest();
|
| Operand *Src0 = getSrc(0);
|
| -
|
| if (!Dest->hasReg()) {
|
| llvm::report_fatal_error("mov can't store.");
|
| }
|
| -
|
| if (isMemoryAccess(Src0)) {
|
| llvm::report_fatal_error("mov can't load.");
|
| }
|
|
|
| - if (isMoveBetweenCoreAndVFPRegisters(Dest, Src0))
|
| - return emitIASCoreVFPMove(Func);
|
| -
|
| - const Type DestTy = Dest->getType();
|
| - if (isScalarFloatingType(DestTy))
|
| - return emitIASScalarVFPMove(Func);
|
| -
|
| - auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| - if (isVectorType(DestTy))
|
| - return Asm->setNeedsTextFixup();
|
| -
|
| - return Asm->mov(Dest, Src0, getPredicate());
|
| -}
|
| -
|
| -void InstARM32Mov::emit(const Cfg *Func) const {
|
| - if (!BuildDefs::dump())
|
| - return;
|
| assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
|
| if (isMultiDest()) {
|
| - emitMultiDestSingleSource(Func);
|
| + Asm->vmovrrd(Dest, getDestHi(), Src0, getPredicate());
|
| return;
|
| }
|
| -
|
| if (isMultiSource()) {
|
| - emitSingleDestMultiSource(Func);
|
| + Asm->vmovdrr(Dest, Src0, getSrc(1), getPredicate());
|
| return;
|
| }
|
|
|
| - emitSingleDestSingleSource(Func);
|
| -}
|
| -
|
| -void InstARM32Mov::emitIAS(const Cfg *Func) const {
|
| - // TODO(kschimpf) Flatten this to a switch statement of dest type. That is,
|
| - // combine code of emitIASSingleDestSingleSource, emitIASCoreVFPMove,
|
| - // emitIASScalarVFPMove, emitDoubleToI64Move, and emitI64ToDoubleMove.
|
| - auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| - assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
|
| - if (isMultiDest())
|
| - Asm->vmovrrd(getDest(), getDestHi(), getSrc(0), getPredicate());
|
| - else if (isMultiSource())
|
| - Asm->vmovdrr(getDest(), getSrc(0), getSrc(1), getPredicate());
|
| - else
|
| - emitIASSingleDestSingleSource(Func);
|
| - if (Asm->needsTextFixup())
|
| + const Type DestTy = Dest->getType();
|
| + const Type SrcTy = Src0->getType();
|
| + switch (DestTy) {
|
| + default:
|
| + break; // Error
|
| + case IceType_i1:
|
| + case IceType_i8:
|
| + case IceType_i16:
|
| + case IceType_i32:
|
| + switch (SrcTy) {
|
| + default:
|
| + break; // Error
|
| + case IceType_i1:
|
| + case IceType_i8:
|
| + case IceType_i16:
|
| + case IceType_i32:
|
| + case IceType_i64:
|
| + Asm->mov(Dest, Src0, getPredicate());
|
| + return;
|
| + case IceType_f32:
|
| + Asm->vmovrs(Dest, Src0, getPredicate());
|
| + return;
|
| + }
|
| + break; // Error
|
| + case IceType_i64:
|
| + if (isScalarIntegerType(SrcTy)) {
|
| + Asm->mov(Dest, Src0, getPredicate());
|
| + return;
|
| + }
|
| + if (SrcTy == IceType_f64) {
|
| + if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
|
| + Asm->vmovdd(Dest, Var, getPredicate());
|
| + return;
|
| + }
|
| + if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
|
| + Asm->vmovd(Dest, FpImm, getPredicate());
|
| + return;
|
| + }
|
| + }
|
| + break; // Error
|
| + case IceType_f32:
|
| + switch (SrcTy) {
|
| + default:
|
| + break; // Error
|
| + case IceType_i1:
|
| + case IceType_i8:
|
| + case IceType_i16:
|
| + case IceType_i32:
|
| + return Asm->vmovsr(Dest, Src0, getPredicate());
|
| + case IceType_f32:
|
| + if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
|
| + Asm->vmovss(Dest, Var, getPredicate());
|
| + return;
|
| + }
|
| + if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
|
| + Asm->vmovs(Dest, FpImm, getPredicate());
|
| + return;
|
| + }
|
| + break; // Error
|
| + }
|
| + break; // Error
|
| + case IceType_f64:
|
| + if (SrcTy == IceType_f64) {
|
| + if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
|
| + Asm->vmovdd(Dest, Var, getPredicate());
|
| + return;
|
| + }
|
| + if (const auto *FpImm = llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
|
| + Asm->vmovd(Dest, FpImm, getPredicate());
|
| + return;
|
| + }
|
| + }
|
| + break; // Error
|
| + case IceType_v4i1:
|
| + case IceType_v8i1:
|
| + case IceType_v16i1:
|
| + case IceType_v16i8:
|
| + case IceType_v8i16:
|
| + case IceType_v4i32:
|
| + case IceType_v4f32:
|
| + // TODO(kschimpf): Add vector moves.
|
| emitUsingTextFixup(Func);
|
| + return;
|
| + }
|
| + llvm::report_fatal_error("Mov: don't know how to move " +
|
| + typeIceString(SrcTy) + " to " +
|
| + typeIceString(DestTy));
|
| }
|
|
|
| void InstARM32Mov::dump(const Cfg *Func) const {
|
|
|