/*
*===============================================================================
*
* d/wilson_d520/asm_code.h
*
*-------------------------------------------------------------------------------
*
* Copyright (C) 2010 Thomas Streuer 
*
* This file is part of BQCD -- Berlin Quantum ChromoDynamics program
*
* BQCD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BQCD is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BQCD.  If not, see <http:*www.gnu.org/licenses/>.
*
*-------------------------------------------------------------------------------
*/
#ifndef ASM_CODE_H

#define ASM_CODE_H

#include <string>
#include <vector>

class asm_code_element_t
{
public:
  bool jump;
  bool fixed;
  int n_res_mod, n_res_used, type;
  int* res_mod,* res_used;
  asm_code_element_t() {}
  asm_code_element_t(const std::string& str, const std::string& comment="")
    : str_(str), comm_(comment) {}
  asm_code_element_t& add_comment(const std::string& comment);
  void print() const;
private:
  std::string str_;
  std::string comm_;
};

class asm_code_t
{
public:
  asm_code_t() : el_(0) {}
  void init();
  void add(const asm_code_element_t& e);
  void optimize() {}
  void listing() const;
private:
  std::vector<asm_code_element_t> el_;
};

class register_file_t
{
public:
  register_file_t(unsigned n);
  void reset();
  void get_regs(unsigned num, std::vector<unsigned>& r);
  unsigned get_reg();
  void get_this_reg(unsigned r);
  void get_these_regs(std::vector<unsigned>& r);
  void release_regs(const std::vector<unsigned>& r);
  void release_reg(unsigned r);
  unsigned max_reg() { return max_; }
private:
  static const unsigned reg_free;
  static const unsigned reg_used;
  unsigned n_, max_;
  std::vector<unsigned> state_;
};

class asm_stack_t
{
public:
  asm_stack_t() : size_(0) {}
  int add(int sz);
  int get_size() { return size_; }
private:
  int size_;
};

class asm_label_t
{
public:
  asm_label_t(const std::string& base = std::string("")) : base_(base), count(0) {}
  std::string get_label();
  asm_code_element_t set_label(std::string& l);
  std::string& base() { return base_; }
private:
  std::string base_;
  unsigned count;
};


#endif
