(*
 * Copyright (c) 2000-2001 Stefan Kral
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *)


type p4stack = P4_INTStack | P4_MMXStack
and p4memop =
    P4_MConst of string
  | P4_MVar of string
  | P4_MFunArg of int
  | P4_MStackCell of p4stack * int
and p4intunaryop =
    P4_IPush
  | P4_IPop
  | P4_INegate
  | P4_IClear
  | P4_IInc
  | P4_IDec
  | P4_IAddImm of int
  | P4_ISubImm of int
  | P4_IShlImm of int
  | P4_IShrImm of int
  | P4_ILoadValue of int
and p4intcpyunaryop = P4_ICopy | P4_IMulImm of int
and p4intbinop = P4_IAdd | P4_ISub

open Number
open VSimdBasics

type p4simdunaryop = 			(* P4 FP-SIMD UNARY OPERATION *******)
  | P4_FPChs of vsimdpos		(*   Change Sign 		    *)
  | P4_FPMulC1 of 			(*   Scalar Mul with Constant:      *) 
	number				(*	= constant c		    *)
  | P4_FPMulC2 of			(*   2-way SIMD Mul w/Constant:     *)
	number *			(*	= lower part of constant    *)
	number				(*	= upper part of constant    *)

type p4simdcpyunaryop =			(* P4 FP-SIMD COPYING UNARY OP ******)
  | P4_FPId				(*   Copy Simd Register		    *)

type p4simdbinop = 			(* P4 SIMD BINARY OPERATION *********)
  | P4_FPAdd1 				(*   FP Addition (Scalar)	    *)
  | P4_FPAdd2				(*   FP Addition (2-way SIMD)	    *)
  | P4_FPSub1				(*   FP Subtraction (Scalar)	    *)
  | P4_FPSub2				(*   FP Subtraction (2-way SIMD)    *)
  | P4_FPMul1				(*   FP Multiplication (Scalar)	    *)
  | P4_FPMul2				(*   FP Multiplication (2-way SIMD) *)
  | P4_UnpckLo				(*   Join Lo Parts of 2 Simd Words  *)
  | P4_UnpckHi				(*   Join Hi Parts of 2 Simd Words  *)
  | P4_Shuffle of int

and p4operandsize = P4_QWord | P4_OWord
and p4branchcondition =
    P4_BCond_NotZero
  | P4_BCond_Zero
  | P4_BCond_GreaterZero
  | P4_BCond_EqualZero
and p4vaddr =
    P4V_RID of VSimdBasics.vintreg * int
  | P4V_SID of VSimdBasics.vintreg * int * int
  | P4V_RISID of VSimdBasics.vintreg * VSimdBasics.vintreg * int * int
and p4vbranchtarget = P4V_BTarget_Named of string
and p4vinstr =
    P4V_IntLoadMem of p4memop * VSimdBasics.vintreg
  | P4V_IntStoreMem of VSimdBasics.vintreg * p4memop
  | P4V_IntLoadEA of p4vaddr * VSimdBasics.vintreg
  | P4V_IntUnaryOp of p4intunaryop * VSimdBasics.vintreg
  | P4V_IntUnaryOpMem of p4intunaryop * p4memop
  | P4V_IntCpyUnaryOp of p4intcpyunaryop * VSimdBasics.vintreg *
      VSimdBasics.vintreg
  | P4V_IntBinOp of p4intbinop * VSimdBasics.vintreg * VSimdBasics.vintreg
  | P4V_IntBinOpMem of p4intbinop * p4memop * VSimdBasics.vintreg
  | P4V_SimdLoad of p4operandsize * p4vaddr * VSimdBasics.vsimdreg
  | P4V_SimdStore of VSimdBasics.vsimdreg * p4operandsize * p4vaddr
  | P4V_SimdLoad1 of p4vaddr * vsimdpos * vsimdreg
  | P4V_SimdStore1 of vsimdpos * vsimdreg * p4vaddr
  | P4V_SimdUnaryOp of p4simdunaryop * VSimdBasics.vsimdreg
  | P4V_SimdCpyUnaryOp of p4simdcpyunaryop * VSimdBasics.vsimdreg *
      VSimdBasics.vsimdreg
  | P4V_SimdCpyUnaryOpMem of p4simdcpyunaryop * p4memop *
      VSimdBasics.vsimdreg
  | P4V_SimdBinOp of p4simdbinop * VSimdBasics.vsimdreg *
      VSimdBasics.vsimdreg
  | P4V_SimdBinOpMem of p4simdbinop * p4memop * VSimdBasics.vsimdreg
  | P4V_SimdLoadStoreBarrier
  | P4V_RefInts of VSimdBasics.vintreg list
  | P4V_Label of string
  | P4V_Jump of p4vbranchtarget
  | P4V_CondBranch of p4branchcondition * p4vbranchtarget
  | P4V_SimdPromiseCellSize of p4operandsize
and p4rmmxreg = P4R_MMXReg of string
and p4rintreg = P4R_IntReg of string

val toP4rintreg : string -> p4rintreg
val toP4rmmxreg : string -> p4rmmxreg

module RIntRegMap :
  sig
    type key = p4rintreg
    and (+'a) t
    val empty : 'a t
    val add : key -> 'a -> 'a t -> 'a t
    val find : key -> 'a t -> 'a
    val remove : key -> 'a t -> 'a t
    val mem : key -> 'a t -> bool
    val iter : (key -> 'a -> unit) -> 'a t -> unit
    val map : ('a -> 'b) -> 'a t -> 'b t
    val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
    val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
  end

module RSimdRegMap :
  sig
    type key = p4rmmxreg
    and (+'a) t
    val empty : 'a t
    val add : key -> 'a -> 'a t -> 'a t
    val find : key -> 'a t -> 'a
    val remove : key -> 'a t -> 'a t
    val mem : key -> 'a t -> bool
    val iter : (key -> 'a -> unit) -> 'a t -> unit
    val map : ('a -> 'b) -> 'a t -> 'b t
    val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
    val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
  end

type p4raddr =
    P4R_RID of p4rintreg * int
  | P4R_SID of p4rintreg * int * int
  | P4R_RISID of p4rintreg * p4rintreg * int * int
and p4rbranchtarget = P4R_BTarget_Named of string
and p4rinstr =
    P4R_IntLoadMem of p4memop * p4rintreg
  | P4R_IntStoreMem of p4rintreg * p4memop
  | P4R_IntLoadEA of p4raddr * p4rintreg
  | P4R_IntUnaryOp of p4intunaryop * p4rintreg
  | P4R_IntUnaryOpMem of p4intunaryop * p4memop
  | P4R_IntCpyUnaryOp of p4intcpyunaryop * p4rintreg * p4rintreg
  | P4R_IntBinOp of p4intbinop * p4rintreg * p4rintreg
  | P4R_IntBinOpMem of p4intbinop * p4memop * p4rintreg
  | P4R_SimdLoad of p4operandsize * p4raddr * p4rmmxreg
  | P4R_SimdStore of p4rmmxreg * p4operandsize * p4raddr
  | P4R_SimdLoad1 of p4raddr * vsimdpos * p4rmmxreg
  | P4R_SimdStore1 of vsimdpos * p4rmmxreg * p4raddr
  | P4R_SimdSpill of p4rmmxreg * int
  | P4R_SimdUnaryOp of p4simdunaryop * p4rmmxreg
  | P4R_SimdCpyUnaryOp of p4simdcpyunaryop * p4rmmxreg * p4rmmxreg
  | P4R_SimdCpyUnaryOpMem of p4simdcpyunaryop * p4memop * p4rmmxreg
  | P4R_SimdBinOp of p4simdbinop * p4rmmxreg * p4rmmxreg
  | P4R_SimdBinOpMem of p4simdbinop * p4memop * p4rmmxreg
  | P4R_SimdLoadStoreBarrier
  | P4R_Label of string
  | P4R_Jump of p4rbranchtarget
  | P4R_CondBranch of p4branchcondition * p4rbranchtarget
  | P4R_Ret
  | P4R_SimdPromiseCellSize of p4operandsize

val p4rmmxregs_names : string list
val p4rintregs_names : string list
val p4rintregs_calleesaved_names : string list
val p4rintreg_stackpointer_name : string
val p4rmmxregs : p4rmmxreg list
val p4rintregs : p4rintreg list
val p4rintregs_calleesaved : p4rintreg list
val p4rintreg_stackpointer : p4rintreg

val p4operandsizeToString : p4operandsize -> string
val p4operandsizeToInteger : p4operandsize -> int

val p4simdbinopIsParallel : p4simdbinop -> bool

val p4simdbinopIsCommutative : p4simdbinop -> bool
val p4simdbinopToCommutativeCounterpart : p4simdbinop -> p4simdbinop


val vsimdunaryopToP4simdcpyunaryop :
  VSimdBasics.vsimdunaryop -> p4simdcpyunaryop

val vsimdbinopToP4simdbinop : VSimdBasics.vsimdbinop -> p4simdbinop

val p4vaddrToP4raddr :
  (VSimdBasics.vintreg -> p4rintreg) -> p4vaddr -> p4raddr

val p4vaddrToSimplified : p4vaddr -> p4vaddr
val p4vaddrToVintregs : p4vaddr -> VSimdBasics.vintreg list

val p4vbranchtargetToVintregs : p4vbranchtarget -> 'a list

val p4vinstrToSrcvregs :
  p4vinstr -> VSimdBasics.vsimdreg list * VSimdBasics.vintreg list

val p4vinstrToDstvregs :
  p4vinstr -> VSimdBasics.vsimdreg list * VSimdBasics.vintreg list

val p4vinstrToVregs :
  p4vinstr ->
  (VSimdBasics.vsimdreg list * VSimdBasics.vintreg list) *
  (VSimdBasics.vsimdreg list * VSimdBasics.vintreg list) *
  (VSimdBasics.vsimdreg list * VSimdBasics.vintreg list)

val p4raddrToP4rintregs : p4raddr -> p4rintreg list

val p4raddrToSimplified : p4raddr -> p4raddr

val p4rinstrToSrcp4rregs : p4rinstr -> p4rmmxreg list * p4rintreg list
val p4rinstrToDstp4rregs : p4rinstr -> p4rmmxreg list * p4rintreg list

val p4rinstrIsMMX : p4rinstr -> bool

val p4rinstrReadsP4rreg :
  (p4rmmxreg list * p4rintreg list -> 'a list) -> 'a -> p4rinstr -> bool
val p4rinstrWritesP4rreg :
  (p4rmmxreg list * p4rintreg list -> 'a list) -> 'a -> p4rinstr -> bool

val p4rinstrReadsP4rmmxreg : p4rmmxreg -> p4rinstr -> bool
val p4rinstrReadsP4rintreg : p4rintreg -> p4rinstr -> bool

val p4rinstrWritesP4rmmxreg : p4rmmxreg -> p4rinstr -> bool
val p4rinstrWritesP4rintreg : p4rintreg -> p4rinstr -> bool

val p4rinstrUsesP4rmmxreg : p4rmmxreg -> p4rinstr -> bool
val p4rinstrUsesP4rintreg : p4rintreg -> p4rinstr -> bool
