//===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Declares the InstARM32 and OperandARM32 classes and their subclasses.
///
/// This represents the machine instructions and operands used for ARM32 code
/// selection.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICEINSTARM32_H
#define SUBZERO_SRC_ICEINSTARM32_H

#include "IceConditionCodesARM32.h"
#include "IceDefs.h"
#include "IceInst.h"
#include "IceInstARM32.def"
#include "IceOperand.h"
#include "IceRegistersARM32.h"

namespace Ice {
namespace ARM32 {

/// Encoding of an ARM 32-bit instruction.
using IValueT = uint32_t;

/// An Offset value (+/-) used in an ARM 32-bit instruction.
using IOffsetT = int32_t;

class TargetARM32;

/// OperandARM32 extends the Operand hierarchy. Its subclasses are
/// OperandARM32Mem and OperandARM32Flex.
class OperandARM32 : public Operand {
  OperandARM32() = delete;
  OperandARM32(const OperandARM32 &) = delete;
  OperandARM32 &operator=(const OperandARM32 &) = delete;

public:
  enum OperandKindARM32 {
    k__Start = Operand::kTarget,
    kMem,
    kShAmtImm,
    kFlexStart,
    kFlexImm = kFlexStart,
    kFlexFpImm,
    kFlexFpZero,
    kFlexReg,
    kFlexEnd = kFlexReg
  };

  enum ShiftKind {
    kNoShift = -1,
#define X(enum, emit) enum,
    ICEINSTARM32SHIFT_TABLE
#undef X
  };

  using Operand::dump;
  void dump(const Cfg *, Ostream &Str) const override {
    if (BuildDefs::dump())
      Str << "<OperandARM32>";
  }

protected:
  OperandARM32(OperandKindARM32 Kind, Type Ty)
      : Operand(static_cast<OperandKind>(Kind), Ty) {}
};

/// OperandARM32Mem represents a memory operand in any of the various ARM32
/// addressing modes.
class OperandARM32Mem : public OperandARM32 {
  OperandARM32Mem() = delete;
  OperandARM32Mem(const OperandARM32Mem &) = delete;
  OperandARM32Mem &operator=(const OperandARM32Mem &) = delete;

public:
  /// Memory operand addressing mode.
  /// The enum value also carries the encoding.
  // TODO(jvoung): unify with the assembler.
  enum AddrMode {
    // bit encoding P U 0 W
    Offset = (8 | 4 | 0) << 21,      // offset (w/o writeback to base)
    PreIndex = (8 | 4 | 1) << 21,    // pre-indexed addressing with writeback
    PostIndex = (0 | 4 | 0) << 21,   // post-indexed addressing with writeback
    NegOffset = (8 | 0 | 0) << 21,   // negative offset (w/o writeback to base)
    NegPreIndex = (8 | 0 | 1) << 21, // negative pre-indexed with writeback
    NegPostIndex = (0 | 0 | 0) << 21 // negative post-indexed with writeback
  };

  /// Provide two constructors.
  /// NOTE: The Variable-typed operands have to be registers.
  ///
  /// (1) Reg + Imm. The Immediate actually has a limited number of bits
  /// for encoding, so check canHoldOffset first. It cannot handle general
  /// Constant operands like ConstantRelocatable, since a relocatable can
  /// potentially take up too many bits.
  static OperandARM32Mem *create(Cfg *Func, Type Ty, Variable *Base,
                                 ConstantInteger32 *ImmOffset,
                                 AddrMode Mode = Offset) {
    return new (Func->allocate<OperandARM32Mem>())
        OperandARM32Mem(Func, Ty, Base, ImmOffset, Mode);
  }
  /// (2) Reg +/- Reg with an optional shift of some kind and amount. Note that
  /// this mode is disallowed in the NaCl sandbox.
  static OperandARM32Mem *create(Cfg *Func, Type Ty, Variable *Base,
                                 Variable *Index, ShiftKind ShiftOp = kNoShift,
                                 uint16_t ShiftAmt = 0,
                                 AddrMode Mode = Offset) {
    return new (Func->allocate<OperandARM32Mem>())
        OperandARM32Mem(Func, Ty, Base, Index, ShiftOp, ShiftAmt, Mode);
  }
  Variable *getBase() const { return Base; }
  ConstantInteger32 *getOffset() const { return ImmOffset; }
  Variable *getIndex() const { return Index; }
  ShiftKind getShiftOp() const { return ShiftOp; }
  uint16_t getShiftAmt() const { return ShiftAmt; }
  AddrMode getAddrMode() const { return Mode; }

  bool isRegReg() const { return Index != nullptr; }
  bool isNegAddrMode() const {
    // Positive address modes have the "U" bit set, and negative modes don't.
    static_assert((PreIndex & (4 << 21)) != 0,
                  "Positive addr modes should have U bit set.");
    static_assert((NegPreIndex & (4 << 21)) == 0,
                  "Negative addr modes should have U bit clear.");
    return (Mode & (4 << 21)) == 0;
  }

  void emit(const Cfg *Func) const override;
  using OperandARM32::dump;
  void dump(const Cfg *Func, Ostream &Str) const override;

  static bool classof(const Operand *Operand) {
    return Operand->getKind() == static_cast<OperandKind>(kMem);
  }

  /// Return true if a load/store instruction for an element of type Ty can
  /// encode the Offset directly in the immediate field of the 32-bit ARM
  /// instruction. For some types, if the load is Sign extending, then the range
  /// is reduced.
  static bool canHoldOffset(Type Ty, bool SignExt, int32_t Offset);

private:
  OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base,
                  ConstantInteger32 *ImmOffset, AddrMode Mode);
  OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, Variable *Index,
                  ShiftKind ShiftOp, uint16_t ShiftAmt, AddrMode Mode);

  Variable *Base;
  ConstantInteger32 *ImmOffset;
  Variable *Index;
  ShiftKind ShiftOp;
  uint16_t ShiftAmt;
  AddrMode Mode;
};

/// OperandARM32ShAmtImm represents an Immediate that is used in one of the
/// shift-by-immediate instructions (lsl, lsr, and asr), and shift-by-immediate
/// shifted registers.
class OperandARM32ShAmtImm : public OperandARM32 {
  OperandARM32ShAmtImm() = delete;
  OperandARM32ShAmtImm(const OperandARM32ShAmtImm &) = delete;
  OperandARM32ShAmtImm &operator=(const OperandARM32ShAmtImm &) = delete;

public:
  static OperandARM32ShAmtImm *create(Cfg *Func, ConstantInteger32 *ShAmt) {
    return new (Func->allocate<OperandARM32ShAmtImm>())
        OperandARM32ShAmtImm(ShAmt);
  }

  static bool classof(const Operand *Operand) {
    return Operand->getKind() == static_cast<OperandKind>(kShAmtImm);
  }

  void emit(const Cfg *Func) const override;
  using OperandARM32::dump;
  void dump(const Cfg *Func, Ostream &Str) const override;

  uint32_t getShAmtImm() const { return ShAmt->getValue(); }

private:
  explicit OperandARM32ShAmtImm(ConstantInteger32 *SA);

  const ConstantInteger32 *const ShAmt;
};

/// OperandARM32Flex represent the "flexible second operand" for data-processing
/// instructions. It can be a rotatable 8-bit constant, or a register with an
/// optional shift operand. The shift amount can even be a third register.
class OperandARM32Flex : public OperandARM32 {
  OperandARM32Flex() = delete;
  OperandARM32Flex(const OperandARM32Flex &) = delete;
  OperandARM32Flex &operator=(const OperandARM32Flex &) = delete;

public:
  static bool classof(const Operand *Operand) {
    return static_cast<OperandKind>(kFlexStart) <= Operand->getKind() &&
           Operand->getKind() <= static_cast<OperandKind>(kFlexEnd);
  }

protected:
  OperandARM32Flex(OperandKindARM32 Kind, Type Ty) : OperandARM32(Kind, Ty) {}
};

/// Rotated immediate variant.
class OperandARM32FlexImm : public OperandARM32Flex {
  OperandARM32FlexImm() = delete;
  OperandARM32FlexImm(const OperandARM32FlexImm &) = delete;
  OperandARM32FlexImm &operator=(const OperandARM32FlexImm &) = delete;

public:
  /// Immed_8 rotated by an even number of bits (2 * RotateAmt).
  static OperandARM32FlexImm *create(Cfg *Func, Type Ty, uint32_t Imm,
                                     uint32_t RotateAmt);

  void emit(const Cfg *Func) const override;
  using OperandARM32::dump;
  void dump(const Cfg *Func, Ostream &Str) const override;

  static bool classof(const Operand *Operand) {
    return Operand->getKind() == static_cast<OperandKind>(kFlexImm);
  }

  /// Return true if the Immediate can fit in the ARM flexible operand. Fills in
  /// the out-params RotateAmt and Immed_8 if Immediate fits.
  static bool canHoldImm(uint32_t Immediate, uint32_t *RotateAmt,
                         uint32_t *Immed_8);

  uint32_t getImm() const { return Imm; }
  uint32_t getRotateAmt() const { return RotateAmt; }

private:
  OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt);

  uint32_t Imm;
  uint32_t RotateAmt;
};

/// Modified Floating-point constant.
class OperandARM32FlexFpImm : public OperandARM32Flex {
  OperandARM32FlexFpImm() = delete;
  OperandARM32FlexFpImm(const OperandARM32FlexFpImm &) = delete;
  OperandARM32FlexFpImm &operator=(const OperandARM32FlexFpImm &) = delete;

public:
  static OperandARM32FlexFpImm *create(Cfg *Func, Type Ty,
                                       uint32_t ModifiedImm) {
    return new (Func->allocate<OperandARM32FlexFpImm>())
        OperandARM32FlexFpImm(Func, Ty, ModifiedImm);
  }

  void emit(const Cfg *Func) const override;
  using OperandARM32::dump;
  void dump(const Cfg *Func, Ostream &Str) const override;

  static bool classof(const Operand *Operand) {
    return Operand->getKind() == static_cast<OperandKind>(kFlexFpImm);
  }

  static bool canHoldImm(const Operand *C, uint32_t *ModifiedImm);

  uint32_t getModifiedImm() const { return ModifiedImm; }

private:
  OperandARM32FlexFpImm(Cfg *Func, Type Ty, uint32_t ModifiedImm);

  const uint32_t ModifiedImm;
};

/// An operand for representing the 0.0 immediate in vcmp.
class OperandARM32FlexFpZero : public OperandARM32Flex {
  OperandARM32FlexFpZero() = delete;
  OperandARM32FlexFpZero(const OperandARM32FlexFpZero &) = delete;
  OperandARM32FlexFpZero &operator=(const OperandARM32FlexFpZero &) = delete;

public:
  static OperandARM32FlexFpZero *create(Cfg *Func, Type Ty) {
    return new (Func->allocate<OperandARM32FlexFpZero>())
        OperandARM32FlexFpZero(Func, Ty);
  }

  void emit(const Cfg *Func) const override;
  using OperandARM32::dump;
  void dump(const Cfg *Func, Ostream &Str) const override;

  static bool classof(const Operand *Operand) {
    return Operand->getKind() == static_cast<OperandKind>(kFlexFpZero);
  }

private:
  OperandARM32FlexFpZero(Cfg *Func, Type Ty);
};

/// Shifted register variant.
class OperandARM32FlexReg : public OperandARM32Flex {
  OperandARM32FlexReg() = delete;
  OperandARM32FlexReg(const OperandARM32FlexReg &) = delete;
  OperandARM32FlexReg &operator=(const OperandARM32FlexReg &) = delete;

public:
  /// Register with immediate/reg shift amount and shift operation.
  static OperandARM32FlexReg *create(Cfg *Func, Type Ty, Variable *Reg,
                                     ShiftKind ShiftOp, Operand *ShiftAmt) {
    return new (Func->allocate<OperandARM32FlexReg>())
        OperandARM32FlexReg(Func, Ty, Reg, ShiftOp, ShiftAmt);
  }

  void emit(const Cfg *Func) const override;
  using OperandARM32::dump;
  void dump(const Cfg *Func, Ostream &Str) const override;

  static bool classof(const Operand *Operand) {
    return Operand->getKind() == static_cast<OperandKind>(kFlexReg);
  }

  Variable *getReg() const { return Reg; }
  ShiftKind getShiftOp() const { return ShiftOp; }
  /// ShiftAmt can represent an immediate or a register.
  Operand *getShiftAmt() const { return ShiftAmt; }

private:
  OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, ShiftKind ShiftOp,
                      Operand *ShiftAmt);

  Variable *Reg;
  ShiftKind ShiftOp;
  Operand *ShiftAmt;
};

/// StackVariable represents a Var that isn't assigned a register (stack-only).
/// It is assigned a stack slot, but the slot's offset may be too large to
/// represent in the native addressing mode, and so it has a separate base
/// register from SP/FP, where the offset from that base register is then in
/// range.
class StackVariable final : public Variable {
  StackVariable() = delete;
  StackVariable(const StackVariable &) = delete;
  StackVariable &operator=(const StackVariable &) = delete;

public:
  static StackVariable *create(Cfg *Func, Type Ty, SizeT Index) {
    return new (Func->allocate<StackVariable>()) StackVariable(Func, Ty, Index);
  }
  constexpr static auto StackVariableKind =
      static_cast<OperandKind>(kVariable_Target);
  static bool classof(const Operand *Operand) {
    return Operand->getKind() == StackVariableKind;
  }
  void setBaseRegNum(RegNumT RegNum) { BaseRegNum = RegNum; }
  RegNumT getBaseRegNum() const override { return BaseRegNum; }
  // Inherit dump() and emit() from Variable.

private:
  StackVariable(const Cfg *Func, Type Ty, SizeT Index)
      : Variable(Func, StackVariableKind, Ty, Index) {}
  RegNumT BaseRegNum;
};

/// Base class for ARM instructions. While most ARM instructions can be
/// conditionally executed, a few of them are not predicable (halt, memory
/// barriers, etc.).
class InstARM32 : public InstTarget {
  InstARM32() = delete;
  InstARM32(const InstARM32 &) = delete;
  InstARM32 &operator=(const InstARM32 &) = delete;

public:
  // Defines form that assembly instruction should be synthesized.
  enum EmitForm { Emit_Text, Emit_Binary };

  enum InstKindARM32 {
    k__Start = Inst::Target,
    Adc,
    Add,
    And,
    Asr,
    Bic,
    Br,
    Call,
    Clz,
    Cmn,
    Cmp,
    Dmb,
    Eor,
    Extract,
    Insert,
    Label,
    Ldr,
    Ldrex,
    Lsl,
    Lsr,
    Nop,
    Mla,
    Mls,
    Mov,
    Movt,
    Movw,
    Mul,
    Mvn,
    Orr,
    Pop,
    Push,
    Rbit,
    Ret,
    Rev,
    Rsb,
    Rsc,
    Sbc,
    Sdiv,
    Str,
    Strex,
    Sub,
    Sxt,
    Trap,
    Tst,
    Udiv,
    Umull,
    Uxt,
    Vabs,
    Vadd,
    Vand,
    Vbsl,
    Vceq,
    Vcge,
    Vcgt,
    Vcmp,
    Vcvt,
    Vdiv,
    Vdup,
    Veor,
    Vldr1d,
    Vldr1q,
    Vmla,
    Vmlap,
    Vmls,
    Vmovl,
    Vmovh,
    Vmovhl,
    Vmovlh,
    Vmrs,
    Vmul,
    Vmulh,
    Vmvn,
    Vneg,
    Vorr,
    Vqadd,
    Vqmovn2,
    Vqsub,
    Vshl,
    Vshr,
    Vsqrt,
    Vstr1,
    Vsub,
    Vzip
  };

  static constexpr size_t InstSize = sizeof(uint32_t);

  static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond);

  /// Called inside derived methods emit() to communicate that multiple
  /// instructions are being generated. Used by emitIAS() methods to
  /// generate textual fixups for instructions that are not yet
  /// implemented.
  void startNextInst(const Cfg *Func) const;

  /// FPSign is used for certain vector instructions (particularly, right
  /// shifts) that require an operand sign specification.
  enum FPSign {
    FS_None,
    FS_Signed,
    FS_Unsigned,
  };
  /// Shared emit routines for common forms of instructions.
  /// @{
  static void emitThreeAddrFP(const char *Opcode, FPSign Sign,
                              const InstARM32 *Instr, const Cfg *Func,
                              Type OpType);
  static void emitFourAddrFP(const char *Opcode, FPSign Sign,
                             const InstARM32 *Instr, const Cfg *Func);
  /// @}

  void dump(const Cfg *Func) const override;

  void emitIAS(const Cfg *Func) const override;

protected:
  InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
      : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}

  static bool isClassof(const Inst *Instr, InstKindARM32 MyKind) {
    return Instr->getKind() == static_cast<InstKind>(MyKind);
  }

  // Generates text of assembly instruction using method emit(), and then adds
  // to the assembly buffer as a Fixup.
  void emitUsingTextFixup(const Cfg *Func) const;
};

/// A predicable ARM instruction.
class InstARM32Pred : public InstARM32 {
  InstARM32Pred() = delete;
  InstARM32Pred(const InstARM32Pred &) = delete;
  InstARM32Pred &operator=(const InstARM32Pred &) = delete;

public:
  InstARM32Pred(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest,
                CondARM32::Cond Predicate)
      : InstARM32(Func, Kind, Maxsrcs, Dest), Predicate(Predicate) {}

  CondARM32::Cond getPredicate() const { return Predicate; }
  void setPredicate(CondARM32::Cond Pred) { Predicate = Pred; }

  static const char *predString(CondARM32::Cond Predicate);
  void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const;

  /// Shared emit routines for common forms of instructions.
  static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Instr,
                             const Cfg *Func, bool NeedsWidthSuffix);
  static void emitUnaryopFP(const char *Opcode, FPSign Sign,
                            const InstARM32Pred *Instr, const Cfg *Func);
  static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Instr,
                          const Cfg *Func);
  static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Instr,
                            const Cfg *Func, bool SetFlags);
  static void emitFourAddr(const char *Opcode, const InstARM32Pred *Instr,
                           const Cfg *Func);
  static void emitCmpLike(const char *Opcode, const InstARM32Pred *Instr,
                          const Cfg *Func);

protected:
  CondARM32::Cond Predicate;
};

template <typename StreamType>
inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) {
  Stream << InstARM32Pred::predString(Predicate);
  return Stream;
}

/// Instructions of the form x := op(y).
template <InstARM32::InstKindARM32 K, bool NeedsWidthSuffix>
class InstARM32UnaryopGPR : public InstARM32Pred {
  InstARM32UnaryopGPR() = delete;
  InstARM32UnaryopGPR(const InstARM32UnaryopGPR &) = delete;
  InstARM32UnaryopGPR &operator=(const InstARM32UnaryopGPR &) = delete;

public:
  static InstARM32UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src,
                                     CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32UnaryopGPR>())
        InstARM32UnaryopGPR(Func, Dest, Src, Predicate);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitUnaryopGPR(Opcode, this, Func, NeedsWidthSuffix);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    Str << " = ";
    dumpOpcodePred(Str, Opcode, getDest()->getType());
    Str << " ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src,
                      CondARM32::Cond Predicate)
      : InstARM32Pred(Func, K, 1, Dest, Predicate) {
    addSource(Src);
  }

  static const char *Opcode;
};

/// Instructions of the form x := op(y), for vector/FP.
template <InstARM32::InstKindARM32 K>
class InstARM32UnaryopFP : public InstARM32Pred {
  InstARM32UnaryopFP() = delete;
  InstARM32UnaryopFP(const InstARM32UnaryopFP &) = delete;
  InstARM32UnaryopFP &operator=(const InstARM32UnaryopFP &) = delete;

public:
  static InstARM32UnaryopFP *create(Cfg *Func, Variable *Dest, Variable *Src,
                                    CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32UnaryopFP>())
        InstARM32UnaryopFP(Func, Dest, Src, Predicate);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitUnaryopFP(Opcode, Sign, this, Func);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    Str << " = ";
    dumpOpcodePred(Str, Opcode, getDest()->getType());
    Str << " ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

protected:
  InstARM32UnaryopFP(Cfg *Func, Variable *Dest, Operand *Src,
                     CondARM32::Cond Predicate)
      : InstARM32Pred(Func, K, 1, Dest, Predicate) {
    addSource(Src);
  }

  FPSign Sign = FS_None;
  static const char *Opcode;
};

template <InstARM32::InstKindARM32 K>
class InstARM32UnaryopSignAwareFP : public InstARM32UnaryopFP<K> {
  InstARM32UnaryopSignAwareFP() = delete;
  InstARM32UnaryopSignAwareFP(const InstARM32UnaryopSignAwareFP &) = delete;
  InstARM32UnaryopSignAwareFP &
  operator=(const InstARM32UnaryopSignAwareFP &) = delete;

public:
  static InstARM32UnaryopSignAwareFP *
  create(Cfg *Func, Variable *Dest, Variable *Src, CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32UnaryopSignAwareFP>())
        InstARM32UnaryopSignAwareFP(Func, Dest, Src, Predicate);
  }
  void emitIAS(const Cfg *Func) const override;
  void setSignType(InstARM32::FPSign SignType) { this->Sign = SignType; }

private:
  InstARM32UnaryopSignAwareFP(Cfg *Func, Variable *Dest, Operand *Src,
                              CondARM32::Cond Predicate)
      : InstARM32UnaryopFP<K>(Func, Dest, Src, Predicate) {}
};

/// Instructions of the form x := x op y.
template <InstARM32::InstKindARM32 K>
class InstARM32TwoAddrGPR : public InstARM32Pred {
  InstARM32TwoAddrGPR() = delete;
  InstARM32TwoAddrGPR(const InstARM32TwoAddrGPR &) = delete;
  InstARM32TwoAddrGPR &operator=(const InstARM32TwoAddrGPR &) = delete;

public:
  /// Dest must be a register.
  static InstARM32TwoAddrGPR *create(Cfg *Func, Variable *Dest, Operand *Src,
                                     CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32TwoAddrGPR>())
        InstARM32TwoAddrGPR(Func, Dest, Src, Predicate);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitTwoAddr(Opcode, this, Func);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    Str << " = ";
    dumpOpcodePred(Str, Opcode, getDest()->getType());
    Str << " ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src,
                      CondARM32::Cond Predicate)
      : InstARM32Pred(Func, K, 2, Dest, Predicate) {
    addSource(Dest);
    addSource(Src);
  }

  static const char *Opcode;
};

/// Base class for load instructions.
template <InstARM32::InstKindARM32 K>
class InstARM32LoadBase : public InstARM32Pred {
  InstARM32LoadBase() = delete;
  InstARM32LoadBase(const InstARM32LoadBase &) = delete;
  InstARM32LoadBase &operator=(const InstARM32LoadBase &) = delete;

public:
  static InstARM32LoadBase *create(Cfg *Func, Variable *Dest, Operand *Source,
                                   CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32LoadBase>())
        InstARM32LoadBase(Func, Dest, Source, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpOpcodePred(Str, Opcode, getDest()->getType());
    Str << " ";
    dumpDest(Func);
    Str << ", ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32LoadBase(Cfg *Func, Variable *Dest, Operand *Source,
                    CondARM32::Cond Predicate)
      : InstARM32Pred(Func, K, 1, Dest, Predicate) {
    addSource(Source);
  }

  static const char *Opcode;
};

/// Instructions of the form x := y op z. May have the side-effect of setting
/// status flags.
template <InstARM32::InstKindARM32 K>
class InstARM32ThreeAddrGPR : public InstARM32Pred {
  InstARM32ThreeAddrGPR() = delete;
  InstARM32ThreeAddrGPR(const InstARM32ThreeAddrGPR &) = delete;
  InstARM32ThreeAddrGPR &operator=(const InstARM32ThreeAddrGPR &) = delete;

public:
  /// Create an ordinary binary-op instruction like add, and sub. Dest and Src1
  /// must be registers.
  static InstARM32ThreeAddrGPR *create(Cfg *Func, Variable *Dest,
                                       Variable *Src0, Operand *Src1,
                                       CondARM32::Cond Predicate,
                                       bool SetFlags = false) {
    return new (Func->allocate<InstARM32ThreeAddrGPR>())
        InstARM32ThreeAddrGPR(Func, Dest, Src0, Src1, Predicate, SetFlags);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitThreeAddr(Opcode, this, Func, SetFlags);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    Str << " = ";
    dumpOpcodePred(Str, Opcode, getDest()->getType());
    Str << (SetFlags ? ".s " : " ");
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0,
                        Operand *Src1, CondARM32::Cond Predicate, bool SetFlags)
      : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) {
    HasSideEffects = SetFlags;
    addSource(Src0);
    addSource(Src1);
  }

  static const char *Opcode;
  bool SetFlags;
};

/// Instructions of the form x := y op z, for vector/FP. We leave these as
/// unconditional: "ARM deprecates the conditional execution of any instruction
/// encoding provided by the Advanced SIMD Extension that is not also provided
/// by the floating-point (VFP) extension". They do not set flags.
template <InstARM32::InstKindARM32 K>
class InstARM32ThreeAddrFP : public InstARM32 {
  InstARM32ThreeAddrFP() = delete;
  InstARM32ThreeAddrFP(const InstARM32ThreeAddrFP &) = delete;
  InstARM32ThreeAddrFP &operator=(const InstARM32ThreeAddrFP &) = delete;

public:
  /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything
  /// must be a register.
  static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0,
                                      Variable *Src1) {
    return new (Func->allocate<InstARM32ThreeAddrFP>())
        InstARM32ThreeAddrFP(Func, Dest, Src0, Src1);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    const Type OpType = (isVectorCompare() ? getSrc(0) : getDest())->getType();
    emitThreeAddrFP(Opcode, Sign, this, Func, OpType);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    const Type OpType = (isVectorCompare() ? getSrc(0) : getDest())->getType();
    Str << " = " << Opcode << "." << OpType << " ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

protected:
  FPSign Sign = FS_None;

  InstARM32ThreeAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Operand *Src1)
      : InstARM32(Func, K, 2, Dest) {
    addSource(Src0);
    addSource(Src1);
  }

  static const char *Opcode;

private:
  static constexpr bool isVectorCompare() {
    return K == InstARM32::Vceq || K == InstARM32::Vcgt || K == InstARM32::Vcge;
  }
};

template <InstARM32::InstKindARM32 K>
class InstARM32ThreeAddrSignAwareFP : public InstARM32ThreeAddrFP<K> {
  InstARM32ThreeAddrSignAwareFP() = delete;
  InstARM32ThreeAddrSignAwareFP(const InstARM32ThreeAddrSignAwareFP &) = delete;
  InstARM32ThreeAddrSignAwareFP &
  operator=(const InstARM32ThreeAddrSignAwareFP &) = delete;

public:
  /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything
  /// must be a register.
  static InstARM32ThreeAddrSignAwareFP *create(Cfg *Func, Variable *Dest,
                                               Variable *Src0, Variable *Src1) {
    return new (Func->allocate<InstARM32ThreeAddrSignAwareFP>())
        InstARM32ThreeAddrSignAwareFP(Func, Dest, Src0, Src1);
  }

  static InstARM32ThreeAddrSignAwareFP *
  create(Cfg *Func, Variable *Dest, Variable *Src0, ConstantInteger32 *Src1) {
    return new (Func->allocate<InstARM32ThreeAddrSignAwareFP>())
        InstARM32ThreeAddrSignAwareFP(Func, Dest, Src0, Src1);
  }

  void emitIAS(const Cfg *Func) const override;
  void setSignType(InstARM32::FPSign SignType) { this->Sign = SignType; }

private:
  InstARM32ThreeAddrSignAwareFP(Cfg *Func, Variable *Dest, Variable *Src0,
                                Operand *Src1)
      : InstARM32ThreeAddrFP<K>(Func, Dest, Src0, Src1) {}
};

/// Instructions of the form x := a op1 (y op2 z). E.g., multiply accumulate.
template <InstARM32::InstKindARM32 K>
class InstARM32FourAddrGPR : public InstARM32Pred {
  InstARM32FourAddrGPR() = delete;
  InstARM32FourAddrGPR(const InstARM32FourAddrGPR &) = delete;
  InstARM32FourAddrGPR &operator=(const InstARM32FourAddrGPR &) = delete;

public:
  // Every operand must be a register.
  static InstARM32FourAddrGPR *create(Cfg *Func, Variable *Dest, Variable *Src0,
                                      Variable *Src1, Variable *Src2,
                                      CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32FourAddrGPR>())
        InstARM32FourAddrGPR(Func, Dest, Src0, Src1, Src2, Predicate);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitFourAddr(Opcode, this, Func);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    Str << " = ";
    dumpOpcodePred(Str, Opcode, getDest()->getType());
    Str << " ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32FourAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0,
                       Variable *Src1, Variable *Src2,
                       CondARM32::Cond Predicate)
      : InstARM32Pred(Func, K, 3, Dest, Predicate) {
    addSource(Src0);
    addSource(Src1);
    addSource(Src2);
  }

  static const char *Opcode;
};

/// Instructions of the form x := x op1 (y op2 z). E.g., multiply accumulate.
/// We leave these as unconditional: "ARM deprecates the conditional execution
/// of any instruction encoding provided by the Advanced SIMD Extension that is
/// not also provided by the floating-point (VFP) extension". They do not set
/// flags.
template <InstARM32::InstKindARM32 K>
class InstARM32FourAddrFP : public InstARM32 {
  InstARM32FourAddrFP() = delete;
  InstARM32FourAddrFP(const InstARM32FourAddrFP &) = delete;
  InstARM32FourAddrFP &operator=(const InstARM32FourAddrFP &) = delete;

public:
  // Every operand must be a register.
  static InstARM32FourAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0,
                                     Variable *Src1) {
    return new (Func->allocate<InstARM32FourAddrFP>())
        InstARM32FourAddrFP(Func, Dest, Src0, Src1);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitFourAddrFP(Opcode, Sign, this, Func);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpDest(Func);
    Str << " = ";
    Str << Opcode << "." << getDest()->getType() << " ";
    dumpDest(Func);
    Str << ", ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32FourAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1)
      : InstARM32(Func, K, 3, Dest) {
    addSource(Dest);
    addSource(Src0);
    addSource(Src1);
  }

  FPSign Sign = FS_None;
  static const char *Opcode;
};

/// Instructions of the form x cmpop y (setting flags).
template <InstARM32::InstKindARM32 K>
class InstARM32CmpLike : public InstARM32Pred {
  InstARM32CmpLike() = delete;
  InstARM32CmpLike(const InstARM32CmpLike &) = delete;
  InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete;

public:
  static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1,
                                  CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32CmpLike>())
        InstARM32CmpLike(Func, Src0, Src1, Predicate);
  }
  void emit(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    emitCmpLike(Opcode, this, Func);
  }
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override {
    if (!BuildDefs::dump())
      return;
    Ostream &Str = Func->getContext()->getStrDump();
    dumpOpcodePred(Str, Opcode, getSrc(0)->getType());
    Str << " ";
    dumpSources(Func);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, K); }

private:
  InstARM32CmpLike(Cfg *Func, Variable *Src0, Operand *Src1,
                   CondARM32::Cond Predicate)
      : InstARM32Pred(Func, K, 2, nullptr, Predicate) {
    HasSideEffects = true;
    addSource(Src0);
    addSource(Src1);
  }

  static const char *Opcode;
};

using InstARM32Adc = InstARM32ThreeAddrGPR<InstARM32::Adc>;
using InstARM32Add = InstARM32ThreeAddrGPR<InstARM32::Add>;
using InstARM32And = InstARM32ThreeAddrGPR<InstARM32::And>;
using InstARM32Asr = InstARM32ThreeAddrGPR<InstARM32::Asr>;
using InstARM32Bic = InstARM32ThreeAddrGPR<InstARM32::Bic>;
using InstARM32Eor = InstARM32ThreeAddrGPR<InstARM32::Eor>;
using InstARM32Lsl = InstARM32ThreeAddrGPR<InstARM32::Lsl>;
using InstARM32Lsr = InstARM32ThreeAddrGPR<InstARM32::Lsr>;
using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>;
using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>;
using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>;
using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>;
using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>;
using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>;
using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>;
using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>;
using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>;
using InstARM32Vand = InstARM32ThreeAddrFP<InstARM32::Vand>;
using InstARM32Vbsl = InstARM32ThreeAddrFP<InstARM32::Vbsl>;
using InstARM32Vceq = InstARM32ThreeAddrFP<InstARM32::Vceq>;
using InstARM32Vcge = InstARM32ThreeAddrSignAwareFP<InstARM32::Vcge>;
using InstARM32Vcgt = InstARM32ThreeAddrSignAwareFP<InstARM32::Vcgt>;
using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>;
using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>;
using InstARM32Vmla = InstARM32FourAddrFP<InstARM32::Vmla>;
using InstARM32Vmls = InstARM32FourAddrFP<InstARM32::Vmls>;
using InstARM32Vmovl = InstARM32ThreeAddrFP<InstARM32::Vmovl>;
using InstARM32Vmovh = InstARM32ThreeAddrFP<InstARM32::Vmovh>;
using InstARM32Vmovhl = InstARM32ThreeAddrFP<InstARM32::Vmovhl>;
using InstARM32Vmovlh = InstARM32ThreeAddrFP<InstARM32::Vmovlh>;
using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>;
using InstARM32Vmvn = InstARM32UnaryopFP<InstARM32::Vmvn>;
using InstARM32Vneg = InstARM32UnaryopSignAwareFP<InstARM32::Vneg>;
using InstARM32Vorr = InstARM32ThreeAddrFP<InstARM32::Vorr>;
using InstARM32Vqadd = InstARM32ThreeAddrSignAwareFP<InstARM32::Vqadd>;
using InstARM32Vqsub = InstARM32ThreeAddrSignAwareFP<InstARM32::Vqsub>;
using InstARM32Vqmovn2 = InstARM32ThreeAddrSignAwareFP<InstARM32::Vqmovn2>;
using InstARM32Vmulh = InstARM32ThreeAddrSignAwareFP<InstARM32::Vmulh>;
using InstARM32Vmlap = InstARM32ThreeAddrFP<InstARM32::Vmlap>;
using InstARM32Vshl = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshl>;
using InstARM32Vshr = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshr>;
using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>;
using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>;
using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>;
using InstARM32Vldr1d = InstARM32LoadBase<InstARM32::Vldr1d>;
using InstARM32Vldr1q = InstARM32LoadBase<InstARM32::Vldr1q>;
using InstARM32Vzip = InstARM32ThreeAddrFP<InstARM32::Vzip>;
/// MovT leaves the bottom bits alone so dest is also a source. This helps
/// indicate that a previous MovW setting dest is not dead code.
using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>;
using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>;
using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>;
using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>;
using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>;
using InstARM32Rev = InstARM32UnaryopGPR<InstARM32::Rev, false>;
// Technically, the uxt{b,h} and sxt{b,h} instructions have a rotation operand
// as well (rotate source by 8, 16, 24 bits prior to extending), but we aren't
// using that for now, so just model as a Unaryop.
using InstARM32Sxt = InstARM32UnaryopGPR<InstARM32::Sxt, true>;
using InstARM32Uxt = InstARM32UnaryopGPR<InstARM32::Uxt, true>;
using InstARM32Vsqrt = InstARM32UnaryopFP<InstARM32::Vsqrt>;
using InstARM32Mla = InstARM32FourAddrGPR<InstARM32::Mla>;
using InstARM32Mls = InstARM32FourAddrGPR<InstARM32::Mls>;
using InstARM32Cmn = InstARM32CmpLike<InstARM32::Cmn>;
using InstARM32Cmp = InstARM32CmpLike<InstARM32::Cmp>;
using InstARM32Tst = InstARM32CmpLike<InstARM32::Tst>;

// InstARM32Label represents an intra-block label that is the target of an
// intra-block branch. The offset between the label and the branch must be fit
// in the instruction immediate (considered "near").
class InstARM32Label : public InstARM32 {
  InstARM32Label() = delete;
  InstARM32Label(const InstARM32Label &) = delete;
  InstARM32Label &operator=(const InstARM32Label &) = delete;

public:
  static InstARM32Label *create(Cfg *Func, TargetARM32 *Target) {
    return new (Func->allocate<InstARM32Label>()) InstARM32Label(Func, Target);
  }
  uint32_t getEmitInstCount() const override { return 0; }
  GlobalString getLabelName() const { return Name; }
  SizeT getNumber() const { return Number; }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  void setRelocOffset(RelocOffset *Value) { OffsetReloc = Value; }

private:
  InstARM32Label(Cfg *Func, TargetARM32 *Target);

  RelocOffset *OffsetReloc = nullptr;
  SizeT Number; // used for unique label generation.
  GlobalString Name;
};

/// Direct branch instruction.
class InstARM32Br : public InstARM32Pred {
  InstARM32Br() = delete;
  InstARM32Br(const InstARM32Br &) = delete;
  InstARM32Br &operator=(const InstARM32Br &) = delete;

public:
  /// Create a conditional branch to one of two nodes.
  static InstARM32Br *create(Cfg *Func, CfgNode *TargetTrue,
                             CfgNode *TargetFalse, CondARM32::Cond Predicate) {
    assert(Predicate != CondARM32::AL);
    constexpr InstARM32Label *NoLabel = nullptr;
    return new (Func->allocate<InstARM32Br>())
        InstARM32Br(Func, TargetTrue, TargetFalse, NoLabel, Predicate);
  }
  /// Create an unconditional branch to a node.
  static InstARM32Br *create(Cfg *Func, CfgNode *Target) {
    constexpr CfgNode *NoCondTarget = nullptr;
    constexpr InstARM32Label *NoLabel = nullptr;
    return new (Func->allocate<InstARM32Br>())
        InstARM32Br(Func, NoCondTarget, Target, NoLabel, CondARM32::AL);
  }
  /// Create a non-terminator conditional branch to a node, with a fallthrough
  /// to the next instruction in the current node. This is used for switch
  /// lowering.
  static InstARM32Br *create(Cfg *Func, CfgNode *Target,
                             CondARM32::Cond Predicate) {
    assert(Predicate != CondARM32::AL);
    constexpr CfgNode *NoUncondTarget = nullptr;
    constexpr InstARM32Label *NoLabel = nullptr;
    return new (Func->allocate<InstARM32Br>())
        InstARM32Br(Func, Target, NoUncondTarget, NoLabel, Predicate);
  }
  // Create a conditional intra-block branch (or unconditional, if
  // Condition==AL) to a label in the current block.
  static InstARM32Br *create(Cfg *Func, InstARM32Label *Label,
                             CondARM32::Cond Predicate) {
    constexpr CfgNode *NoCondTarget = nullptr;
    constexpr CfgNode *NoUncondTarget = nullptr;
    return new (Func->allocate<InstARM32Br>())
        InstARM32Br(Func, NoCondTarget, NoUncondTarget, Label, Predicate);
  }
  const CfgNode *getTargetTrue() const { return TargetTrue; }
  const CfgNode *getTargetFalse() const { return TargetFalse; }
  bool optimizeBranch(const CfgNode *NextNode);
  uint32_t getEmitInstCount() const override {
    uint32_t Sum = 0;
    if (Label)
      ++Sum;
    if (getTargetTrue())
      ++Sum;
    if (getTargetFalse())
      ++Sum;
    return Sum;
  }
  bool isUnconditionalBranch() const override {
    return getPredicate() == CondARM32::AL;
  }
  bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Br); }

private:
  InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
              const InstARM32Label *Label, CondARM32::Cond Predicate);

  const CfgNode *TargetTrue;
  const CfgNode *TargetFalse;
  const InstARM32Label *Label; // Intra-block branch target
};

/// Call instruction (bl/blx). Arguments should have already been pushed.
/// Technically bl and the register form of blx can be predicated, but we'll
/// leave that out until needed.
class InstARM32Call : public InstARM32 {
  InstARM32Call() = delete;
  InstARM32Call(const InstARM32Call &) = delete;
  InstARM32Call &operator=(const InstARM32Call &) = delete;

public:
  static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
    return new (Func->allocate<InstARM32Call>())
        InstARM32Call(Func, Dest, CallTarget);
  }
  Operand *getCallTarget() const { return getSrc(0); }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Call); }

private:
  InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
};

class InstARM32RegisterStackOp : public InstARM32 {
  InstARM32RegisterStackOp() = delete;
  InstARM32RegisterStackOp(const InstARM32RegisterStackOp &) = delete;
  InstARM32RegisterStackOp &
  operator=(const InstARM32RegisterStackOp &) = delete;

public:
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;

protected:
  InstARM32RegisterStackOp(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs,
                           Variable *Dest)
      : InstARM32(Func, Kind, Maxsrcs, Dest) {}
  void emitUsingForm(const Cfg *Func, const EmitForm Form) const;
  void emitGPRsAsText(const Cfg *Func) const;
  void emitSRegsAsText(const Cfg *Func, const Variable *BaseReg,
                       SizeT Regcount) const;
  void emitSRegsOp(const Cfg *Func, const EmitForm, const Variable *BaseReg,
                   SizeT RegCount, SizeT InstIndex) const;
  virtual const char *getDumpOpcode() const { return getGPROpcode(); }
  virtual const char *getGPROpcode() const = 0;
  virtual const char *getSRegOpcode() const = 0;
  virtual Variable *getStackReg(SizeT Index) const = 0;
  virtual SizeT getNumStackRegs() const = 0;
  virtual void emitSingleGPR(const Cfg *Func, const EmitForm Form,
                             const Variable *Reg) const = 0;
  virtual void emitMultipleGPRs(const Cfg *Func, const EmitForm Form,
                                IValueT Registers) const = 0;
  virtual void emitSRegs(const Cfg *Func, const EmitForm Form,
                         const Variable *BaseReg, SizeT RegCount) const = 0;
};

/// Pops a list of registers. It may be a list of GPRs, or a list of VFP "s"
/// regs, but not both. In any case, the list must be sorted.
class InstARM32Pop final : public InstARM32RegisterStackOp {
  InstARM32Pop() = delete;
  InstARM32Pop(const InstARM32Pop &) = delete;
  InstARM32Pop &operator=(const InstARM32Pop &) = delete;

public:
  static InstARM32Pop *create(Cfg *Func, const VarList &Dests) {
    return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, Pop); }

private:
  InstARM32Pop(Cfg *Func, const VarList &Dests);
  virtual const char *getGPROpcode() const final;
  virtual const char *getSRegOpcode() const final;
  Variable *getStackReg(SizeT Index) const final;
  SizeT getNumStackRegs() const final;
  void emitSingleGPR(const Cfg *Func, const EmitForm Form,
                     const Variable *Reg) const final;
  void emitMultipleGPRs(const Cfg *Func, const EmitForm Form,
                        IValueT Registers) const final;
  void emitSRegs(const Cfg *Func, const EmitForm Form, const Variable *BaseReg,
                 SizeT RegCount) const final;
  VarList Dests;
};

/// Pushes a list of registers. Just like Pop (see above), the list may be of
/// GPRs, or VFP "s" registers, but not both.
class InstARM32Push final : public InstARM32RegisterStackOp {
  InstARM32Push() = delete;
  InstARM32Push(const InstARM32Push &) = delete;
  InstARM32Push &operator=(const InstARM32Push &) = delete;

public:
  static InstARM32Push *create(Cfg *Func, const VarList &Srcs) {
    return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs);
  }
  static bool classof(const Inst *Instr) { return isClassof(Instr, Push); }

private:
  InstARM32Push(Cfg *Func, const VarList &Srcs);
  const char *getGPROpcode() const final;
  const char *getSRegOpcode() const final;
  Variable *getStackReg(SizeT Index) const final;
  SizeT getNumStackRegs() const final;
  void emitSingleGPR(const Cfg *Func, const EmitForm Form,
                     const Variable *Reg) const final;
  void emitMultipleGPRs(const Cfg *Func, const EmitForm Form,
                        IValueT Registers) const final;
  void emitSRegs(const Cfg *Func, const EmitForm Form, const Variable *BaseReg,
                 SizeT RegCount) const final;
};

/// Ret pseudo-instruction. This is actually a "bx" instruction with an "lr"
/// register operand, but epilogue lowering will search for a Ret instead of a
/// generic "bx". This instruction also takes a Source operand (for non-void
/// returning functions) for liveness analysis, though a FakeUse before the ret
/// would do just as well.
///
/// NOTE: Even though "bx" can be predicated, for now leave out the predication
/// since it's not yet known to be useful for Ret. That may complicate finding
/// the terminator instruction if it's not guaranteed to be executed.
class InstARM32Ret : public InstARM32 {
  InstARM32Ret() = delete;
  InstARM32Ret(const InstARM32Ret &) = delete;
  InstARM32Ret &operator=(const InstARM32Ret &) = delete;

public:
  static InstARM32Ret *create(Cfg *Func, Variable *LR,
                              Variable *Source = nullptr) {
    return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Ret); }

private:
  InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source);
};

/// Store instruction. It's important for liveness that there is no Dest operand
/// (OperandARM32Mem instead of Dest Variable).
class InstARM32Str final : public InstARM32Pred {
  InstARM32Str() = delete;
  InstARM32Str(const InstARM32Str &) = delete;
  InstARM32Str &operator=(const InstARM32Str &) = delete;

public:
  /// Value must be a register.
  static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
                              CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Str>())
        InstARM32Str(Func, Value, Mem, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Str); }

private:
  InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
               CondARM32::Cond Predicate);
};

/// Exclusive Store instruction. Like its non-exclusive sibling, it's important
/// for liveness that there is no Dest operand (OperandARM32Mem instead of Dest
/// Variable).
class InstARM32Strex final : public InstARM32Pred {
  InstARM32Strex() = delete;
  InstARM32Strex(const InstARM32Strex &) = delete;
  InstARM32Strex &operator=(const InstARM32Strex &) = delete;

public:
  /// Value must be a register.
  static InstARM32Strex *create(Cfg *Func, Variable *Dest, Variable *Value,
                                OperandARM32Mem *Mem,
                                CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Strex>())
        InstARM32Strex(Func, Dest, Value, Mem, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Strex); }

private:
  InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value,
                 OperandARM32Mem *Mem, CondARM32::Cond Predicate);
};

/// Sub-vector store instruction. It's important for liveness that there is no
///  Dest operand (OperandARM32Mem instead of Dest Variable).
class InstARM32Vstr1 final : public InstARM32Pred {
  InstARM32Vstr1() = delete;
  InstARM32Vstr1(const InstARM32Vstr1 &) = delete;
  InstARM32Vstr1 &operator=(const InstARM32Vstr1 &) = delete;

public:
  /// Value must be a register.
  static InstARM32Vstr1 *create(Cfg *Func, Variable *Value,
                                OperandARM32Mem *Mem, CondARM32::Cond Predicate,
                                SizeT Size) {
    return new (Func->allocate<InstARM32Vstr1>())
        InstARM32Vstr1(Func, Value, Mem, Predicate, Size);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Vstr1); }

private:
  InstARM32Vstr1(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
                 CondARM32::Cond Predicate, SizeT Size);

  SizeT Size;
};

/// Vector element duplication/replication instruction.
class InstARM32Vdup final : public InstARM32Pred {
  InstARM32Vdup() = delete;
  InstARM32Vdup(const InstARM32Vdup &) = delete;
  InstARM32Vdup &operator=(const InstARM32Vdup &) = delete;

public:
  /// Value must be a register.
  static InstARM32Vdup *create(Cfg *Func, Variable *Dest, Variable *Src,
                               IValueT Idx) {
    return new (Func->allocate<InstARM32Vdup>())
        InstARM32Vdup(Func, Dest, Src, Idx);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Vdup); }

private:
  InstARM32Vdup(Cfg *Func, Variable *Dest, Variable *Src, IValueT Idx);

  const IValueT Idx;
};

class InstARM32Trap : public InstARM32 {
  InstARM32Trap() = delete;
  InstARM32Trap(const InstARM32Trap &) = delete;
  InstARM32Trap &operator=(const InstARM32Trap &) = delete;

public:
  static InstARM32Trap *create(Cfg *Func) {
    return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Trap); }

private:
  explicit InstARM32Trap(Cfg *Func);
};

/// Unsigned Multiply Long: d.lo, d.hi := x * y
class InstARM32Umull : public InstARM32Pred {
  InstARM32Umull() = delete;
  InstARM32Umull(const InstARM32Umull &) = delete;
  InstARM32Umull &operator=(const InstARM32Umull &) = delete;

public:
  /// Everything must be a register.
  static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi,
                                Variable *Src0, Variable *Src1,
                                CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Umull>())
        InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Umull); }

private:
  InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0,
                 Variable *Src1, CondARM32::Cond Predicate);

  Variable *DestHi;
};

/// Handles fp2int, int2fp, and fp2fp conversions.
class InstARM32Vcvt final : public InstARM32Pred {
  InstARM32Vcvt() = delete;
  InstARM32Vcvt(const InstARM32Vcvt &) = delete;
  InstARM32Vcvt &operator=(const InstARM32Vcvt &) = delete;

public:
  enum VcvtVariant {
    S2si,
    S2ui,
    Si2s,
    Ui2s,
    D2si,
    D2ui,
    Si2d,
    Ui2d,
    S2d,
    D2s,
    Vs2si,
    Vs2ui,
    Vsi2s,
    Vui2s,
  };
  static InstARM32Vcvt *create(Cfg *Func, Variable *Dest, Variable *Src,
                               VcvtVariant Variant, CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Vcvt>())
        InstARM32Vcvt(Func, Dest, Src, Variant, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Vcvt); }

private:
  InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant,
                CondARM32::Cond Predicate);

  const VcvtVariant Variant;
};

/// Handles (some of) vmov's various formats.
class InstARM32Mov final : public InstARM32Pred {
  InstARM32Mov() = delete;
  InstARM32Mov(const InstARM32Mov &) = delete;
  InstARM32Mov &operator=(const InstARM32Mov &) = delete;

public:
  static InstARM32Mov *create(Cfg *Func, Variable *Dest, Operand *Src,
                              CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Mov>())
        InstARM32Mov(Func, Dest, Src, Predicate);
  }
  bool isRedundantAssign() const override {
    return !isMultiDest() && !isMultiSource() &&
           getPredicate() == CondARM32::AL &&
           checkForRedundantAssign(getDest(), getSrc(0));
  }
  bool isVarAssign() const override { return llvm::isa<Variable>(getSrc(0)); }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Mov); }

  bool isMultiDest() const { return DestHi != nullptr; }

  bool isMultiSource() const {
    assert(getSrcSize() == 1 || getSrcSize() == 2);
    return getSrcSize() == 2;
  }

  Variable *getDestHi() const { return DestHi; }

private:
  InstARM32Mov(Cfg *Func, Variable *Dest, Operand *Src,
               CondARM32::Cond Predicate);
  void emitMultiDestSingleSource(const Cfg *Func) const;
  void emitSingleDestMultiSource(const Cfg *Func) const;
  void emitSingleDestSingleSource(const Cfg *Func) const;

  Variable *DestHi = nullptr;
};

/// Generates vmov Rd, Dn[x] instructions, and their related floating point
/// versions.
class InstARM32Extract final : public InstARM32Pred {
  InstARM32Extract() = delete;
  InstARM32Extract(const InstARM32Extract &) = delete;
  InstARM32Extract &operator=(const InstARM32Extract &) = delete;

public:
  static InstARM32Extract *create(Cfg *Func, Variable *Dest, Variable *Src0,
                                  uint32_t Index, CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Extract>())
        InstARM32Extract(Func, Dest, Src0, Index, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  static bool classof(const Inst *Inst) { return isClassof(Inst, Extract); }

private:
  InstARM32Extract(Cfg *Func, Variable *Dest, Variable *Src0, uint32_t Index,
                   CondARM32::Cond Predicate)
      : InstARM32Pred(Func, InstARM32::Extract, 1, Dest, Predicate),
        Index(Index) {
    assert(Index < typeNumElements(Src0->getType()));
    addSource(Src0);
  }

  const uint32_t Index;
};

/// Generates vmov Dn[x], Rd instructions, and their related floating point
/// versions.
class InstARM32Insert final : public InstARM32Pred {
  InstARM32Insert() = delete;
  InstARM32Insert(const InstARM32Insert &) = delete;
  InstARM32Insert &operator=(const InstARM32Insert &) = delete;

public:
  static InstARM32Insert *create(Cfg *Func, Variable *Dest, Variable *Src0,
                                 uint32_t Index, CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Insert>())
        InstARM32Insert(Func, Dest, Src0, Index, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  static bool classof(const Inst *Inst) { return isClassof(Inst, Insert); }

private:
  InstARM32Insert(Cfg *Func, Variable *Dest, Variable *Src0, uint32_t Index,
                  CondARM32::Cond Predicate)
      : InstARM32Pred(Func, InstARM32::Insert, 1, Dest, Predicate),
        Index(Index) {
    assert(Index < typeNumElements(Dest->getType()));
    addSource(Src0);
  }

  const uint32_t Index;
};

class InstARM32Vcmp final : public InstARM32Pred {
  InstARM32Vcmp() = delete;
  InstARM32Vcmp(const InstARM32Vcmp &) = delete;
  InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete;

public:
  static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1,
                               CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Vcmp>())
        InstARM32Vcmp(Func, Src0, Src1, Predicate);
  }
  static InstARM32Vcmp *create(Cfg *Func, Variable *Src0,
                               OperandARM32FlexFpZero *Src1,
                               CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Vcmp>())
        InstARM32Vcmp(Func, Src0, Src1, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Vcmp); }

private:
  InstARM32Vcmp(Cfg *Func, Variable *Src0, Operand *Src1,
                CondARM32::Cond Predicate);
};

/// Copies the FP Status and Control Register the core flags.
class InstARM32Vmrs final : public InstARM32Pred {
  InstARM32Vmrs() = delete;
  InstARM32Vmrs(const InstARM32Vmrs &) = delete;
  InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete;

public:
  static InstARM32Vmrs *create(Cfg *Func, CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Vmrs>()) InstARM32Vmrs(Func, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Vmrs); }

private:
  InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate);
};

class InstARM32Vabs final : public InstARM32Pred {
  InstARM32Vabs() = delete;
  InstARM32Vabs(const InstARM32Vabs &) = delete;
  InstARM32Vabs &operator=(const InstARM32Vabs &) = delete;

public:
  static InstARM32Vabs *create(Cfg *Func, Variable *Dest, Variable *Src,
                               CondARM32::Cond Predicate) {
    return new (Func->allocate<InstARM32Vabs>())
        InstARM32Vabs(Func, Dest, Src, Predicate);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Vabs); }

private:
  InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src,
                CondARM32::Cond Predicate);
};

class InstARM32Dmb final : public InstARM32Pred {
  InstARM32Dmb() = delete;
  InstARM32Dmb(const InstARM32Dmb &) = delete;
  InstARM32Dmb &operator=(const InstARM32Dmb &) = delete;

public:
  static InstARM32Dmb *create(Cfg *Func) {
    return new (Func->allocate<InstARM32Dmb>()) InstARM32Dmb(Func);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Dmb); }

private:
  explicit InstARM32Dmb(Cfg *Func);
};

class InstARM32Nop final : public InstARM32Pred {
  InstARM32Nop() = delete;
  InstARM32Nop(const InstARM32Nop &) = delete;
  InstARM32Nop &operator=(const InstARM32Nop &) = delete;

public:
  static InstARM32Nop *create(Cfg *Func) {
    return new (Func->allocate<InstARM32Nop>()) InstARM32Nop(Func);
  }
  void emit(const Cfg *Func) const override;
  void emitIAS(const Cfg *Func) const override;
  void dump(const Cfg *Func) const override;
  static bool classof(const Inst *Instr) { return isClassof(Instr, Nop); }

private:
  explicit InstARM32Nop(Cfg *Func);
};

// Declare partial template specializations of emit() methods that already have
// default implementations. Without this, there is the possibility of ODR
// violations and link errors.

template <> void InstARM32Ldr::emit(const Cfg *Func) const;
template <> void InstARM32Movw::emit(const Cfg *Func) const;
template <> void InstARM32Movt::emit(const Cfg *Func) const;
template <> void InstARM32Vldr1d::emit(const Cfg *Func) const;
template <> void InstARM32Vldr1q::emit(const Cfg *Func) const;

} // end of namespace ARM32
} // end of namespace Ice

#endif // SUBZERO_SRC_ICEINSTARM32_H
