| Index: src/IceInstARM32.cpp
|
| diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
|
| index 7c3e2885e2bb6e9cccbdb359f408b3b9635303ca..4bd530ce39b6db462c52b094660f89c8f1d5ae41 100644
|
| --- a/src/IceInstARM32.cpp
|
| +++ b/src/IceInstARM32.cpp
|
| @@ -228,13 +228,13 @@ void InstARM32Pred::emitThreeAddr(const char *Opcode,
|
| }
|
|
|
| void InstARM32::emitThreeAddrFP(const char *Opcode, FPSign SignType,
|
| - const InstARM32 *Instr, const Cfg *Func) {
|
| + const InstARM32 *Instr, const Cfg *Func,
|
| + Type OpType) {
|
| if (!BuildDefs::dump())
|
| return;
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| assert(Instr->getSrcSize() == 2);
|
| - Str << "\t" << Opcode
|
| - << getVWidthString(Instr->getDest()->getType(), SignType) << "\t";
|
| + Str << "\t" << Opcode << getVWidthString(OpType, SignType) << "\t";
|
| Instr->getDest()->emit(Func);
|
| Str << ", ";
|
| Instr->getSrc(0)->emit(Func);
|
| @@ -704,6 +704,95 @@ template <> void InstARM32Vand::emitIAS(const Cfg *Func) const {
|
| assert(!Asm->needsTextFixup());
|
| }
|
|
|
| +template <> void InstARM32Vceq::emitIAS(const Cfg *Func) const {
|
| + auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| + const Variable *Dest = getDest();
|
| + const Type SrcTy = getSrc(0)->getType();
|
| + switch (SrcTy) {
|
| + default:
|
| + llvm::report_fatal_error("Vceq not defined on type " +
|
| + typeStdString(SrcTy));
|
| + case IceType_v4i1:
|
| + case IceType_v8i1:
|
| + case IceType_v16i1:
|
| + case IceType_v16i8:
|
| + case IceType_v8i16:
|
| + case IceType_v4i32:
|
| + Asm->vceqqi(typeElementType(SrcTy), Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + case IceType_v4f32:
|
| + Asm->vceqqs(Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + }
|
| + assert(!Asm->needsTextFixup());
|
| +}
|
| +
|
| +template <> void InstARM32Vcge::emitIAS(const Cfg *Func) const {
|
| + auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| + const Variable *Dest = getDest();
|
| + const Type SrcTy = getSrc(0)->getType();
|
| + switch (SrcTy) {
|
| + default:
|
| + llvm::report_fatal_error("Vcge not defined on type " +
|
| + typeStdString(Dest->getType()));
|
| + case IceType_v4i1:
|
| + case IceType_v8i1:
|
| + case IceType_v16i1:
|
| + case IceType_v16i8:
|
| + case IceType_v8i16:
|
| + case IceType_v4i32: {
|
| + const Type ElmtTy = typeElementType(SrcTy);
|
| + assert(Sign != InstARM32::FS_None);
|
| + switch (Sign) {
|
| + case InstARM32::FS_None: // defaults to unsigned.
|
| + llvm_unreachable("Sign should not be FS_None.");
|
| + case InstARM32::FS_Unsigned:
|
| + Asm->vcugeqi(ElmtTy, Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + case InstARM32::FS_Signed:
|
| + Asm->vcgeqi(ElmtTy, Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + }
|
| + } break;
|
| + case IceType_v4f32:
|
| + Asm->vcgeqs(Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +template <> void InstARM32Vcgt::emitIAS(const Cfg *Func) const {
|
| + auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| + const Variable *Dest = getDest();
|
| + const Type SrcTy = getSrc(0)->getType();
|
| + switch (SrcTy) {
|
| + default:
|
| + llvm::report_fatal_error("Vcgt not defined on type " +
|
| + typeStdString(Dest->getType()));
|
| + case IceType_v4i1:
|
| + case IceType_v8i1:
|
| + case IceType_v16i1:
|
| + case IceType_v16i8:
|
| + case IceType_v8i16:
|
| + case IceType_v4i32: {
|
| + const Type ElmtTy = typeElementType(SrcTy);
|
| + assert(Sign != InstARM32::FS_None);
|
| + switch (Sign) {
|
| + case InstARM32::FS_None: // defaults to unsigned.
|
| + llvm_unreachable("Sign should not be FS_None.");
|
| + case InstARM32::FS_Unsigned:
|
| + Asm->vcugtqi(ElmtTy, Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + case InstARM32::FS_Signed:
|
| + Asm->vcgtqi(ElmtTy, Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + }
|
| + } break;
|
| + case IceType_v4f32:
|
| + Asm->vcgtqs(Dest, getSrc(0), getSrc(1));
|
| + break;
|
| + }
|
| +}
|
| +
|
| template <> void InstARM32Vbsl::emitIAS(const Cfg *Func) const {
|
| auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| const Variable *Dest = getDest();
|
| @@ -795,6 +884,25 @@ template <> void InstARM32Vmls::emitIAS(const Cfg *Func) const {
|
| }
|
| }
|
|
|
| +template <> void InstARM32Vmvn::emitIAS(const Cfg *Func) const {
|
| + auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| + const Variable *Dest = getDest();
|
| + switch (Dest->getType()) {
|
| + default:
|
| + llvm::report_fatal_error("Vmvn not defined on type " +
|
| + typeStdString(Dest->getType()));
|
| + case IceType_v4i1:
|
| + case IceType_v8i1:
|
| + case IceType_v16i1:
|
| + case IceType_v16i8:
|
| + case IceType_v8i16:
|
| + case IceType_v4i32:
|
| + case IceType_v4f32: {
|
| + Asm->vmvnq(Dest, getSrc(0));
|
| + } break;
|
| + }
|
| +}
|
| +
|
| template <> void InstARM32Vneg::emitIAS(const Cfg *Func) const {
|
| auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
|
| const Variable *Dest = getDest();
|
| @@ -842,6 +950,8 @@ template <> void InstARM32Vshl::emitIAS(const Cfg *Func) const {
|
| default:
|
| llvm::report_fatal_error("Vshl not defined on type " +
|
| typeStdString(Dest->getType()));
|
| + // TODO(jpp): handle i1 vectors in terms of element count instead of element
|
| + // type.
|
| case IceType_v4i1:
|
| case IceType_v8i1:
|
| case IceType_v16i1:
|
| @@ -879,6 +989,8 @@ template <> void InstARM32Vshr::emitIAS(const Cfg *Func) const {
|
| default:
|
| llvm::report_fatal_error("Vshr not defined on type " +
|
| typeStdString(Dest->getType()));
|
| + // TODO(jpp): handle i1 vectors in terms of element count instead of element
|
| + // type.
|
| case IceType_v4i1:
|
| case IceType_v8i1:
|
| case IceType_v16i1:
|
| @@ -1515,11 +1627,15 @@ template <> const char *InstARM32Udiv::Opcode = "udiv";
|
| template <> const char *InstARM32Vadd::Opcode = "vadd";
|
| template <> const char *InstARM32Vand::Opcode = "vand";
|
| template <> const char *InstARM32Vbsl::Opcode = "vbsl";
|
| +template <> const char *InstARM32Vceq::Opcode = "vceq";
|
| +template <> const char *InstARM32ThreeAddrFP<InstARM32::Vcge>::Opcode = "vcge";
|
| +template <> const char *InstARM32ThreeAddrFP<InstARM32::Vcgt>::Opcode = "vcgt";
|
| template <> const char *InstARM32Vdiv::Opcode = "vdiv";
|
| template <> const char *InstARM32Veor::Opcode = "veor";
|
| template <> const char *InstARM32Vmla::Opcode = "vmla";
|
| template <> const char *InstARM32Vmls::Opcode = "vmls";
|
| template <> const char *InstARM32Vmul::Opcode = "vmul";
|
| +template <> const char *InstARM32Vmvn::Opcode = "vmvn";
|
| template <> const char *InstARM32Vorr::Opcode = "vorr";
|
| template <> const char *InstARM32UnaryopFP<InstARM32::Vneg>::Opcode = "vneg";
|
| template <> const char *InstARM32ThreeAddrFP<InstARM32::Vshl>::Opcode = "vshl";
|
| @@ -1758,6 +1874,7 @@ void InstARM32Mov::emitIAS(const Cfg *Func) const {
|
| }
|
| }
|
| break; // Error
|
| + // TODO(jpp): Remove vectors of i1.
|
| case IceType_v4i1:
|
| case IceType_v8i1:
|
| case IceType_v16i1:
|
| @@ -2984,6 +3101,8 @@ template class InstARM32ThreeAddrGPR<InstARM32::Sub>;
|
| template class InstARM32ThreeAddrGPR<InstARM32::Udiv>;
|
|
|
| template class InstARM32ThreeAddrFP<InstARM32::Vadd>;
|
| +template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vcge>;
|
| +template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vcgt>;
|
| template class InstARM32ThreeAddrFP<InstARM32::Vdiv>;
|
| template class InstARM32ThreeAddrFP<InstARM32::Veor>;
|
| template class InstARM32FourAddrFP<InstARM32::Vmla>;
|
|
|