/* -*- mode: C; c-basic-offset: 3; -*- */

/*---------------------------------------------------------------*/
/*--- begin                                       ir_inject.c ---*/
/*---------------------------------------------------------------*/


/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2012-2017  Florian Krohm   (britzel@acm.org)

   This program 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 2 of the
   License, or (at your option) any later version.

   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#include "libvex_basictypes.h"
#include "libvex_ir.h"
#include "libvex.h"
#include "main_util.h"

/* Convenience macros for readibility */
#define mkU8(v)   IRExpr_Const(IRConst_U8(v))
#define mkU16(v)  IRExpr_Const(IRConst_U16(v))
#define mkU32(v)  IRExpr_Const(IRConst_U32(v))
#define mkU64(v)  IRExpr_Const(IRConst_U64(v))
#define unop(kind, a)  IRExpr_Unop(kind, a)
#define binop(kind, a1, a2)  IRExpr_Binop(kind, a1, a2)
#define triop(kind, a1, a2, a3)  IRExpr_Triop(kind, a1, a2, a3)
#define qop(kind, a1, a2, a3, a4)  IRExpr_Qop(kind, a1, a2, a3, a4)
#define stmt(irsb, st)  addStmtToIRSB(irsb, st)


/* The IR Injection Control Block. vex_inject_ir will query its contents
   to construct IR statements for testing purposes. */
static IRICB iricb;


void
LibVEX_InitIRI(const IRICB *iricb_in)
{
   iricb = *iricb_in;  // copy in
}


static IRExpr *
load_aux(IREndness endian, IRType type, IRExpr *addr)
{
   if (type == Ity_D64) {
      /* The insn selectors do not support loading a DFP value from memory.
         So we need to fix it here by loading an integer value and
         reinterpreting it as DFP. */
      return unop(Iop_ReinterpI64asD64,
                  IRExpr_Load(endian, Ity_I64, addr));
   }
   if (type == Ity_I1) {
      /* A Boolean value is stored as a 32-bit entity (see store_aux). */
      return unop(Iop_32to1, IRExpr_Load(endian, Ity_I32, addr));
   }

   return IRExpr_Load(endian, type, addr);
}


/* Load a value from memory. Loads of more than 8 byte are split into
   a series of 8-byte loads and combined using appropriate IROps. */
static IRExpr *
load(IREndness endian, IRType type, HWord haddr)
{
   IROp concat;
   IRExpr *addr, *next_addr;

   vassert(type == Ity_I1 || sizeofIRType(type) <= 16);

   if (VEX_HOST_WORDSIZE == 8) {
      addr = mkU64(haddr);
      next_addr = binop(Iop_Add64, addr, mkU64(8));
   } else if (VEX_HOST_WORDSIZE == 4) {
      addr = mkU32(haddr);
      next_addr = binop(Iop_Add32, addr, mkU32(8));
   } else {
      vpanic("invalid #bytes for address");
   }

   switch (type) {
   case Ity_I128: concat = Iop_64HLto128;   type = Ity_I64; goto load128;
   case Ity_F128: concat = Iop_F64HLtoF128; type = Ity_F64; goto load128;
   case Ity_D128: concat = Iop_D64HLtoD128; type = Ity_D64; goto load128;

   load128:
     /* Two loads of 64 bit each. */
      if (endian == Iend_BE) {
         /* The more significant bits are at the lower address. */
         return binop(concat,
                      load_aux(endian, type, addr),
                      load_aux(endian, type, next_addr));
      } else {
         /* The more significant bits are at the higher address. */
         return binop(concat,
                      load_aux(endian, type, next_addr),
                      load_aux(endian, type, addr));
      }

   default:
      return load_aux(endian, type, addr);
   }
}


static void
store_aux(IRSB *irsb, IREndness endian, IRExpr *addr, IRExpr *data)
{
   if (typeOfIRExpr(irsb->tyenv, data) == Ity_D64) {
      /* The insn selectors do not support writing a DFP value to memory.
         So we need to fix it here by reinterpreting the DFP value as an
         integer and storing that. */
      data = unop(Iop_ReinterpD64asI64, data);
   }
   if (typeOfIRExpr(irsb->tyenv, data) == Ity_I1) {
      /* We cannot store a single bit. So we store it in a 32-bit container.
         See also load_aux. */
      data = unop(Iop_1Uto32, data);
   }
   stmt(irsb, IRStmt_Store(endian, addr, data));
}


/* Store a value to memory. If a value requires more than 8 bytes a series
   of 8-byte stores will be generated. */
static __inline__ void
store(IRSB *irsb, IREndness endian, HWord haddr, IRExpr *data)
{
   IROp high, low;
   IRExpr *addr, *next_addr;

   if (VEX_HOST_WORDSIZE == 8) {
      addr = mkU64(haddr);
      next_addr = binop(Iop_Add64, addr, mkU64(8));
   } else if (VEX_HOST_WORDSIZE == 4) {
      addr = mkU32(haddr);
      next_addr = binop(Iop_Add32, addr, mkU32(8));
   } else {
      vpanic("invalid #bytes for address");
   }

   IRType type = typeOfIRExpr(irsb->tyenv, data);

   vassert(type == Ity_I1 || sizeofIRType(type) <= 16);

   switch (type) {
   case Ity_I128: high = Iop_128HIto64;   low = Iop_128to64;     goto store128;
   case Ity_F128: high = Iop_F128HItoF64; low = Iop_F128LOtoF64; goto store128;
   case Ity_D128: high = Iop_D128HItoD64; low = Iop_D128LOtoD64; goto store128;

   store128:
     /* Two stores of 64 bit each. */
      if (endian == Iend_BE) {
         /* The more significant bits are at the lower address. */
         store_aux(irsb, endian, addr, unop(high, data));
         store_aux(irsb, endian, next_addr, unop(low, data));
      } else {
         /* The more significant bits are at the higher address. */
         store_aux(irsb, endian, addr, unop(low, data));
         store_aux(irsb, endian, next_addr, unop(high, data));
      }
      return;

   default:
      store_aux(irsb, endian, addr, data);
      return;
   }
}


/* Inject IR stmts depending on the data provided in the control
   block iricb. */
void
vex_inject_ir(IRSB *irsb, IREndness endian)
{
   IRExpr *data, *rounding_mode, *opnd1, *opnd2, *opnd3, *opnd4;

   rounding_mode = NULL;
   if (iricb.rounding_mode != NO_ROUNDING_MODE) {
      rounding_mode = mkU32(iricb.rounding_mode);
   }

   switch (iricb.num_operands) {
   case 1:
      opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
      if (rounding_mode)
         data = binop(iricb.op, rounding_mode, opnd1);
      else
         data = unop(iricb.op, opnd1);
      break;

   case 2:
      opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
      /* HACK, compiler warning ‘opnd2’ may be used uninitialized */
      opnd2 = opnd1;

      /* immediate_index = 0  immediate value is not used.
       * immediate_index = 2  opnd2 is an immediate value.
       */
      vassert(iricb.immediate_index == 0 || iricb.immediate_index == 2);

      if (iricb.immediate_index == 2) {
         vassert((iricb.t_opnd2 == Ity_I8) || (iricb.t_opnd2 == Ity_I16)
                 || (iricb.t_opnd2 == Ity_I32));

         /* Interpret the memory as an ULong. */
         if (iricb.immediate_type == Ity_I8) {
            opnd2 = mkU8(*((ULong *)iricb.opnd2));
         } else if (iricb.immediate_type == Ity_I16) {
            opnd2 = mkU16(*((ULong *)iricb.opnd2));
         } else if (iricb.immediate_type == Ity_I32) {
            opnd2 = mkU32(*((ULong *)iricb.opnd2));
         }
      } else {
         opnd2 = load(endian, iricb.t_opnd2, iricb.opnd2);
      }

      if (rounding_mode)
         data = triop(iricb.op, rounding_mode, opnd1, opnd2);
      else
         data = binop(iricb.op, opnd1, opnd2);
      break;

   case 3:
      opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
      opnd2 = load(endian, iricb.t_opnd2, iricb.opnd2);
      /* HACK, compiler warning ‘opnd3’ may be used uninitialized */
      opnd3 = opnd2;

      /* immediate_index = 0  immediate value is not used.
       * immediate_index = 3  opnd3 is an immediate value.
       */
      vassert(iricb.immediate_index == 0 || iricb.immediate_index == 3);

      if (iricb.immediate_index == 3) {
         vassert((iricb.t_opnd3 == Ity_I8) || (iricb.t_opnd3 == Ity_I16)
                 || (iricb.t_opnd2 == Ity_I32));

         if (iricb.immediate_type == Ity_I8) {
            opnd3 = mkU8(*((ULong *)iricb.opnd3));
         } else if (iricb.immediate_type == Ity_I16) {
            opnd3 = mkU16(*((ULong *)iricb.opnd3));
         } else if (iricb.immediate_type == Ity_I32) {
            opnd3 = mkU32(*((ULong *)iricb.opnd3));
         }
      } else {
         opnd3 = load(endian, iricb.t_opnd3, iricb.opnd3);
      }
      if (rounding_mode)
         data = qop(iricb.op, rounding_mode, opnd1, opnd2, opnd3);
      else
         data = triop(iricb.op, opnd1, opnd2, opnd3);
      break;

   case 4:
      vassert(rounding_mode == NULL);
      opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
      opnd2 = load(endian, iricb.t_opnd2, iricb.opnd2);
      opnd3 = load(endian, iricb.t_opnd3, iricb.opnd3);
      /* HACK, compiler warning ‘opnd4’ may be used uninitialized */
      opnd4 = opnd3;

      /* immediate_index = 0  immediate value is not used.
       * immediate_index = 4  opnd4 is an immediate value.
       */
      vassert(iricb.immediate_index == 0 || iricb.immediate_index == 4);

      if (iricb.immediate_index == 4) {
         vassert((iricb.t_opnd3 == Ity_I8) || (iricb.t_opnd3 == Ity_I16)
                 || (iricb.t_opnd2 == Ity_I32));

         if (iricb.immediate_type == Ity_I8) {
            opnd4 = mkU8(*((ULong *)iricb.opnd4));
         } else if (iricb.immediate_type == Ity_I16) {
            opnd4 = mkU16(*((ULong *)iricb.opnd4));
         } else if (iricb.immediate_type == Ity_I32) {
            opnd4 = mkU32(*((ULong *)iricb.opnd4));
         }
      } else {
         opnd4 = load(endian, iricb.t_opnd4, iricb.opnd4);
      }
      data = qop(iricb.op, opnd1, opnd2, opnd3, opnd4);
      break;

   default:
      vpanic("unsupported operator");
   }

   store(irsb, endian, iricb.result, data);

   if (0) {
      vex_printf("BEGIN inject\n");
      if (iricb.t_result == Ity_I1 || sizeofIRType(iricb.t_result) <= 8) {
         ppIRStmt(irsb->stmts[irsb->stmts_used - 1]);
      } else if (sizeofIRType(iricb.t_result) == 16) {
         ppIRStmt(irsb->stmts[irsb->stmts_used - 2]);
         vex_printf("\n");
         ppIRStmt(irsb->stmts[irsb->stmts_used - 1]);
      }
      vex_printf("\nEND inject\n");
   }
}

/*---------------------------------------------------------------*/
/*--- end                                         ir_inject.c ---*/
/*---------------------------------------------------------------*/
