/*
*===============================================================================
*
* d/wilson_d520/bgp_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 BGP_ASM_CODE_H

#define BGP_ASM_CODE_H

#include "asm_code.h"

#include <string>

class bgp_code_element_t :public asm_code_element_t
{
public:
  bgp_code_element_t(const std::string& s, const std::string& c="")
    : asm_code_element_t(s, c) {}
  static bgp_code_element_t comment(const std::string& s);
// fixed-point operations
  static bgp_code_element_t add(unsigned dest, unsigned src1, unsigned src2);
  static bgp_code_element_t sub(unsigned dest, unsigned src1, unsigned src2);
  static bgp_code_element_t andd(unsigned dest, unsigned src1, unsigned src2, bool upd_cr=false);
  static bgp_code_element_t add_i(unsigned dest, unsigned src, int imm);
  static bgp_code_element_t mul_i(unsigned dest, unsigned src, int imm);
  static bgp_code_element_t and_i(unsigned dest, unsigned src, int imm, bool shifted=false, bool upd_cr=false);
  static bgp_code_element_t xor_i(unsigned dest, unsigned src, int imm, bool shifted=false, bool upd_cr=false);
  static bgp_code_element_t crand(unsigned field_dest, unsigned field1, unsigned field2, unsigned bit);
  static bgp_code_element_t crset(unsigned field_dest, unsigned bit, unsigned val);
  static bgp_code_element_t mac(unsigned target, unsigned src1, unsigned src2, bool high1=false,
				bool high2=false, bool sign=true, bool upd_cr=false);
  static bgp_code_element_t rlwinm(unsigned dest, unsigned src, int shift, int begin, int end);
  static bgp_code_element_t rlwimi(unsigned dest, unsigned src, int shift, int begin, int end);
  static bgp_code_element_t select(unsigned target, unsigned src1, unsigned src2, unsigned cr);
  static bgp_code_element_t load_i(unsigned dest, int imm);
  static bgp_code_element_t load_i32(unsigned target, unsigned imm);
  static bgp_code_element_t load_hi(unsigned target, unsigned src, const std::string& src);
  static bgp_code_element_t load_lo(unsigned target, unsigned src, const std::string& src);
  static bgp_code_element_t load_hword_a(unsigned target, int offs, unsigned src, bool upd=false);
  static bgp_code_element_t load(unsigned dest, unsigned src, int offs, bool upd=false);
  static bgp_code_element_t prefetch(unsigned src1, unsigned src2);
  static bgp_code_element_t clear_cache(unsigned src1, unsigned src2);
  static bgp_code_element_t store(unsigned src, unsigned dest, int offs, bool upd=false);
// floating point operations
  static bgp_code_element_t fload(unsigned dest, unsigned src1, unsigned src2,
				  bool par=false, bool upd=false, bool cross=false);
  static bgp_code_element_t fstore(
    unsigned src, unsigned dest1, unsigned dest2, bool par=false,
    bool upd=false, bool cross=false);
  static bgp_code_element_t fadd(unsigned dest, unsigned a, unsigned b, bool par=false);
  static bgp_code_element_t fadd_isign(
    unsigned dest, unsigned src, unsigned isign, unsigned freg_i, int acc=-1);
  static bgp_code_element_t cplxmul(unsigned dest, unsigned a, unsigned b, unsigned pass,
				    bool add=true, bool cj=false, bool negate=false, int acc=-1);
// branches
  static bgp_code_element_t jump_ctr(const std::string& label);
  static bgp_code_element_t jump_cond(const std::string& label, unsigned field, unsigned bit, unsigned val, bool link=false, bool ctr=false);
  static bgp_code_element_t jump(const std::string& l, bool link=false);
  static bgp_code_element_t jump_lr();
// special purpose regs
  static bgp_code_element_t mflr(unsigned r);
  static bgp_code_element_t mtlr(unsigned r);
  static bgp_code_element_t mfctr(unsigned r);
  static bgp_code_element_t mtctr(unsigned r);
  static bgp_code_element_t mfcr(unsigned r);
  static bgp_code_element_t mbar();
  static const unsigned cr_field_lt = 0;
  static const unsigned cr_field_gt = 1;
  static const unsigned cr_field_eq = 2;
  static const unsigned cr_field_so = 3;
};
#endif
