#include "mir/MIR.h"

#include <stdexcept>
#include <vector>

#include "utils/Log.h"

namespace mir {
namespace {

int AlignTo(int value, int align) {
  return ((value + align - 1) / align) * align;
}

}  // namespace

void RunFrameLowering(MachineFunction& function) {
  int cursor = 0;
  for (const auto& slot : function.GetFrameSlots()) {
    cursor += slot.size;
    if (-cursor < -256) {
      throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
    }
  }

  cursor = 0;
  for (const auto& slot : function.GetFrameSlots()) {
    cursor += slot.size;
    function.GetFrameSlot(slot.index).offset = -cursor;
  }
  function.SetFrameSize(AlignTo(cursor, 16));

  auto& insts = function.GetEntry().GetInstructions();
  std::vector<MachineInstr> lowered;
  lowered.emplace_back(Opcode::Prologue);
  for (const auto& inst : insts) {
    if (inst.GetOpcode() == Opcode::Ret) {
      lowered.emplace_back(Opcode::Epilogue);
    }
    lowered.push_back(inst);
  }
  insts = std::move(lowered);
}

}  // namespace mir
