2
* Copyright (c) 2000-2001 Stefan Kral
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
(* This module declares basic data types for virtual scalar floating-point
21
* instructions and common operations on them. *)
25
open Number (* Arbitrary Precision Number Type *)
26
open Variable (* Def.s of Variables and Arrays *)
28
type vfpcomplexarrayformat =
34
| ComplexArray of vfpcomplexarrayformat
36
let vfparraytypeIsReal = function
38
| ComplexArray _ -> false
40
let vfparraytypeIsComplex = function
42
| ComplexArray _ -> true
44
(****************************************************************************)
46
type vfpreg = V_FPReg of int (* VIRTUAL SCALAR FP REGISTER *******)
48
type vfpsummand = V_FPPlus of vfpreg | V_FPMinus of vfpreg
50
(* makeNewVfpreg () creates a new vfpreg. It uses Variable.make_temporary *
51
* so that the indices of vfpregs and temporary variables (that have been *
52
* created in the generator) are ``compatible''. *)
53
let makeNewVfpreg () =
54
match Variable.make_temporary () with
55
| Temporary t -> V_FPReg t
56
| _ -> failwith "VFPBasics.makeNewVfpreg: Unexpected failure!"
58
(* Sets and Maps with key type vfpreg *)
59
module VFPRegSet = Set.Make(struct type t = vfpreg let compare = compare end)
60
module VFPRegMap = Map.Make(struct type t = vfpreg let compare = compare end)
62
let vfpregmap_find k m = try Some(VFPRegMap.find k m) with Not_found -> None
64
(* The function vfpregmap_addE inserts a (key,value) pair into a multimap *
65
* m. All bindings bindings of key are stored in an unsorted list. *)
66
let vfpregmap_findE k m = try VFPRegMap.find k m with Not_found -> []
67
let vfpregmap_addE k v m = VFPRegMap.add k (v::(vfpregmap_findE k m)) m
69
(****************************************************************************)
77
| V_FPMulConst of number
86
type vfpinstr = (* VIRTUAL SCALAR FP INSTRUCTION ****)
110
(****************************************************************************)
112
let vfpbinopIsAddorsub = function
117
let vfpunaryopToNegated = function
118
| V_FPId -> V_FPNegate
119
| V_FPNegate -> V_FPId
120
| V_FPMulConst n -> V_FPMulConst (Number.negate n)
122
let vfpsummandToVfpreg = function
126
let vfpsummandIsPositive = function
128
| V_FPMinus _ -> false
130
let vfpsummandIsNegative = function
131
| V_FPPlus _ -> false
132
| V_FPMinus _ -> true
134
let vfpsummandToNegated = function
135
| V_FPPlus x -> V_FPMinus x
136
| V_FPMinus x -> V_FPPlus x
138
(****************************************************************************)
140
(* vfpinstrToSrcregs maps a vfpinstruction to its source register operands. *
141
* The output list may contain duplicates. *)
142
let vfpinstrToSrcregs = function
144
| V_FPStore(s,_,_,_) -> [s]
145
| V_FPUnaryOp(_,s,_) -> [s]
146
| V_FPBinOp(_,s1,s2,_) -> [s1;s2]
147
| V_FPAddL(srcs,_) -> map vfpsummandToVfpreg srcs
149
(* vfpinstrToDstreg maps a vfpinstr to its destination register operand. If *
150
* an instruction does not have a dest register-operand, None is returned. *)
151
let vfpinstrToDstreg = function
152
| V_FPStore _ -> None
153
| V_FPLoad(_,_,_,d) -> Some d
154
| V_FPUnaryOp(_,_,d) -> Some d
155
| V_FPBinOp(_,_,_,d) -> Some d
156
| V_FPAddL(_,d) -> Some d
158
let vfpinstrToVfpregs instr =
159
optionToListAndConcat (vfpinstrToSrcregs instr) (vfpinstrToDstreg instr)
161
let vfpinstrIsLoad = function
165
let vfpinstrIsStore = function
166
| V_FPStore _ -> true
169
let vfpinstrIsLoadOrStore i = vfpinstrIsLoad i || vfpinstrIsStore i
171
let vfpinstrToAddsubcount = function
175
| V_FPBinOp(op,_,_,_) -> if vfpbinopIsAddorsub op then 1 else 0
176
| V_FPAddL(xs,_) -> length xs
178
let vfpinstrIsBinMul = function
179
| V_FPBinOp(V_FPMul,_,_,_) -> true
182
let vfpinstrIsUnaryOp = function
183
| V_FPUnaryOp _ -> true
187
(****************************************************************************)
189
let addlistHelper2 dst = function
190
| (V_FPPlus x, V_FPPlus y) -> (V_FPBinOp(V_FPAdd,x,y,dst), V_FPPlus dst)
191
| (V_FPPlus x, V_FPMinus y) -> (V_FPBinOp(V_FPSub,x,y,dst), V_FPPlus dst)
192
| (V_FPMinus x, V_FPPlus y) -> (V_FPBinOp(V_FPSub,y,x,dst), V_FPPlus dst)
193
| (V_FPMinus x, V_FPMinus y) -> (V_FPBinOp(V_FPAdd,x,y,dst), V_FPMinus dst)
195
let addlistHelper3' dst tmp (x',y',z') =
196
let (i1, tmp') = addlistHelper2 tmp (x',y') in
197
let (i2, dst') = addlistHelper2 dst (tmp',z') in
200
let addlistHelper3 dst triple =
201
addlistHelper3' dst (makeNewVfpreg ()) triple