(*
 * 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
 *
 *)

(* This module contains code for hashing vsimdinstrs.  This feature is
 * used extensively in the code optimizer (VP4Optimization) to speedup
 * the code-optimization process. 					
 *)

open VSimdBasics

(* for hashing purposes *)
type vsimdinstrcategory = 
  | VSIC_Load
  | VSIC_Store
  | VSIC_UnaryMulConst
  | VSIC_UnaryCopy
  | VSIC_UnarySwap
  | VSIC_UnaryChsLo
  | VSIC_UnaryChsHi
  | VSIC_UnaryChsLoHi
  | VSIC_BinAdd1
  | VSIC_BinSub1
  | VSIC_BinMul1
  | VSIC_BinAdd2
  | VSIC_BinSub2
  | VSIC_BinMul2
  | VSIC_BinPPAcc
  | VSIC_BinNNAcc
  | VSIC_BinNPAcc
  | VSIC_BinPNAcc
  | VSIC_BinShuffle

(* vsimdinstr category map *)
module VSICMap = Map.Make(struct 
			    type t = vsimdinstrcategory
			    let compare = compare
			  end)

let vsicmap_findE k m = try VSICMap.find k m with Not_found -> []
let vsicmap_addE k v m = VSICMap.add k (v::(vsicmap_findE k m)) m

(****************************************************************************)

let vsimdunaryopcategories_chs = 
  [VSIC_UnaryChsLo; VSIC_UnaryChsHi; VSIC_UnaryChsLoHi]

let vsimdunaryopcategories_nocopy = 
  VSIC_UnarySwap::VSIC_UnaryMulConst::vsimdunaryopcategories_chs

let vsimdunaryopcategories_all = 
  VSIC_UnaryCopy::vsimdunaryopcategories_nocopy

let vsimdbinopcategories_par = 
  [VSIC_BinAdd2; VSIC_BinSub2; VSIC_BinMul2]

let vsimdbinopcategories_all =
  vsimdbinopcategories_par @
  [
   VSIC_BinPPAcc;
   VSIC_BinNNAcc;
   VSIC_BinNPAcc;
   VSIC_BinPNAcc;
   VSIC_BinShuffle
  ]


let vsimdallcategories = 
  [VSIC_Load; VSIC_Store] @ 
  vsimdunaryopcategories_all @ 
  vsimdbinopcategories_all

(****************************************************************************)

let vsimdunaryopToCategory = function
  | V_Id	 -> VSIC_UnaryCopy
  | V_Swap	 -> VSIC_UnarySwap
  | V_Chs V_Lo	 -> VSIC_UnaryChsLo
  | V_Chs V_Hi	 -> VSIC_UnaryChsHi
  | V_Chs V_LoHi -> VSIC_UnaryChsLoHi
  | V_MulC1 _    -> VSIC_UnaryMulConst
  | V_MulC2 _    -> VSIC_UnaryMulConst


let vsimdbinopToCategory = function
  | V_PPAcc   -> VSIC_BinPPAcc
  | V_NNAcc   -> VSIC_BinNNAcc
  | V_NPAcc   -> VSIC_BinNPAcc
  | V_PNAcc   -> VSIC_BinPNAcc
  | V_UnpckLo -> VSIC_BinShuffle
  | V_UnpckHi -> VSIC_BinShuffle
  | V_Shuffle _ -> VSIC_BinShuffle
  | V_Sub1    -> VSIC_BinSub1
  | V_Sub2    -> VSIC_BinSub2
  | V_Add1    -> VSIC_BinAdd1
  | V_Add2    -> VSIC_BinAdd2
  | V_Mul1    -> VSIC_BinMul1
  | V_Mul2    -> VSIC_BinMul2

let vsimdinstrToCategory = function
  | V_SimdLoadD _	  -> VSIC_Load
  | V_SimdLoadQ _	  -> VSIC_Load
  | V_SimdStoreD _ 	  -> VSIC_Store
  | V_SimdStoreQ _ 	  -> VSIC_Store
  | V_SimdUnaryOp(op,_,_) -> vsimdunaryopToCategory op
  | V_SimdBinOp(op,_,_,_) -> vsimdbinopToCategory op

let vsimdinstrToCategories i = [vsimdinstrToCategory i]



