ASM.hpp 10.84 KiB
#pragma once
#include "IR/IR.hpp"
#include "Util/List.hpp"
#include <cassert>
#include <utility>
#include <variant>
#include <vector>
#include <map>
namespace SyOC::ARMv7a {
struct Register {
  enum IntRegs {
#define FirstIntReg(x) INTEGER_REG_BEGIN = x,
#define TargetIntegralRegister(x, y, z) x = z,
#define LastIntReg(x) INTEGER_REG_END = x,
#include "Common/TargetInfo.def"
  enum VFPRegs {
#define FirstVFPReg(x) VFP_REG_BEGIN = x,
#define TargetFloatRegister(x, y, z) x = z,
#define LastVFPReg(x) VFP_REG_END = x,
#include "Common/TargetInfo.def"
  enum StatusRegs {
#define FirstStatusReg(x) STATUS_REG_BEGIN = x,
#define TargetStatusRegister(x, y, z) x = z,
#define LastStatusReg(x) STATUS_REG_END = x,
#include "Common/TargetInfo.def"
  enum VirtualRegs {
#define FirstVirtualReg(x) VREG_BEGIN = x,
#include "Common/TargetInfo.def"
  enum Type {
    Int,
    Float,
  int id = -1;
  Type type = Int;
  inline bool isInvalid() const { return id == -1; }
  inline bool isVirtual() const { return !(isInteger() || isFloat() || isStatus()) && id > 0; }
  inline bool isInteger() const { return id >= INTEGER_REG_BEGIN && id <= INTEGER_REG_END; }
  inline bool isFloat() const { return id >= VFP_REG_BEGIN && id <= VFP_REG_END; }
  inline bool isStatus() const { return id >= STATUS_REG_BEGIN && id <= STATUS_REG_END; }
struct RegisterList {
  typedef uint32_t RegVector;
  static const int RegCount = 32;
  RegVector ls = 0; // vmov, vpush requires 32 bit.
  // std::bitset<RegCount> ls;
struct FrameObject {
  int32_t Offset;
  size_t Size;
  const Instruction* Alloca;
  bool isSpill;
  FrameObject(int32_t Offset, size_t Size,
              Instruction *Alloca = nullptr, bool isSpill = false) :
    Offset(Offset), Size(Size), Alloca(Alloca), isSpill(isSpill) { }
// llvm MachineFrameInfo.
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
struct CalleeSaved { Register Reg; union { int FrameIdx; unsigned DstReg; } Locate; bool SpilledToReg = false; }; // 4 byte literal pool struct LiteralPool { int id; uint32_t Literal; }; enum class Opcode : unsigned char { #define ARMv7aOpcodeDefine(x, y, z) x, #include "Common/Common.def" #undef ARMv7aOpcodeDefine }; enum class Format { #define ARMv7aInsnFormatDefine(x) x, #include "Common/Common.def" #undef ARMv7aInsnFormatDefine }; inline Format get_op_format(Opcode op) { #define ARMv7aOpcodeDefine(x, y, z) \ if (op == Opcode::x) \ return Format::z; #include "Common/Common.def" #undef ARMv7aOpcodeDefine return Format::IF_Other; } struct Shift { enum class Type : unsigned char { #define ShiftTypeDefine(x, y) x, #include "Common/Common.def" #undef ShiftTypeDefine } type; Register reg; int32_t imm; // pure Imm or shift bits static Shift GetDefaultShift(Register r) { return Shift {Type::SF_None, r, 0}; } static Shift GetImm(int32_t Imm) { return Shift {Type::SF_None, Register{-1}, Imm}; } bool isPureReg() const { return reg.id != -1 && imm == 0;} bool isPureImm() const { return reg.id == -1; } }; enum class Condition : unsigned char { #define ConditionTypeDefine(x, y, v) x = (v), #include "Common/Common.def" #undef ConditionTypeDefine }; struct MBasicBlock; struct MInstruction; struct MFunction; struct MModule; struct Address { std::variant<int, Register> base; // global / stack object