#include "mir/MIR.h"

#include <stdexcept>
#include <vector>

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.frame_slots()) {
    cursor += slot.size;
    if (-cursor < -256) {
      throw std::runtime_error(
          "Lab3 MVP 后端暂不支持超过 64 个 i32 栈槽的函数");
    }
  }

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

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

}  // namespace mir
