2
* Copyright (c) 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 includes definitions of data types and functions that are used
21
* within the instruction scheduler. *)
27
type k7rflag = (* K7 FLAGS *************************)
28
| K7RFlag_Zero (* Zero Flag *)
30
type k7rop = (* K7 REAL OPERAND ******************)
31
| K7ROp_MMXReg of k7rmmxreg (* MMX Register (SIMD) *)
32
| K7ROp_IntReg of k7rintreg (* Integer Register *)
33
| K7ROp_MemOp of k7memop (* Memory Operand *)
34
| K7ROp_IP (* Instruction Pointer *)
35
| K7ROp_Flag of k7rflag (* Flag (eg. zero) *)
36
| K7ROp_MMXState (* Floating-Point Mode (x87/MMX) *)
37
| K7ROp_MemoryState (* for preserving Ld/St order *)
38
| K7ROp_Stack (* stack operations (push/pop) *)
40
let zeroflag = K7ROp_Flag (K7RFlag_Zero)
41
let mmxstackcell i = K7ROp_MemOp(K7_MStackCell(K7_MMXStack, i))
43
module ResMap = Map.Make(struct type t = k7rop let compare = compare end)
45
let resmap_findE k m = try ResMap.find k m with Not_found -> []
46
let resmap_addE k v m = ResMap.add k (v::resmap_findE k m) m
47
let resmap_addE' value key = resmap_addE key value
49
let resmap_find k m = try Some (ResMap.find k m) with Not_found -> None
52
(* READING OF K7ROPS ********************************************************)
54
let raddrToRops = function
55
| K7R_RID(base,_) -> [K7ROp_IntReg base]
56
| K7R_SID(index,_,_) -> [K7ROp_IntReg index]
57
| K7R_RISID(base,index,_,_) -> [K7ROp_IntReg base; K7ROp_IntReg index]
59
let intuopToSrcrops sd = function
60
| K7_IPush -> [K7ROp_IntReg k7rintreg_stackpointer; sd]
61
| K7_IPop -> [K7ROp_IntReg k7rintreg_stackpointer]
63
| K7_ILoadValue _ -> []
67
| K7_IAddImm _ -> [sd]
68
| K7_ISubImm _ -> [sd]
69
| K7_IShlImm _ -> [sd]
70
| K7_IShrImm _ -> [sd]
72
let intcpyuopToSrcrops = function
76
let branchconditionToSrcrops = function
77
| K7_BCond_NotZero -> [zeroflag]
78
| K7_BCond_Zero -> [zeroflag]
79
| K7_BCond_GreaterZero -> [zeroflag]
80
| K7_BCond_EqualZero -> [zeroflag]
82
let simduopToSrcrops sd = function
84
| K7_FPMulConst _ -> [sd]
86
let simdcpyuopToSrcrops = function
90
let k7memopToSrcrops = function
93
| K7_MFunArg _ -> [K7ROp_IntReg k7rintreg_stackpointer]
94
| K7_MStackCell _ -> [K7ROp_IntReg k7rintreg_stackpointer]
96
let rinstrToSrcrops' = function
97
| K7R_IntLoadMem(s,_) -> k7memopToSrcrops s @ [K7ROp_MemOp s]
98
| K7R_IntStoreMem(s,d) -> k7memopToSrcrops d @ [K7ROp_IntReg s]
99
| K7R_IntLoadEA(s,_) -> raddrToRops s
100
| K7R_IntUnaryOp(op,sd) -> intuopToSrcrops (K7ROp_IntReg sd) op
101
| K7R_IntUnaryOpMem(op,sd) -> k7memopToSrcrops sd @
102
intuopToSrcrops (K7ROp_MemOp sd) op
103
| K7R_IntCpyUnaryOp(op,s,_) -> (K7ROp_IntReg s)::(intcpyuopToSrcrops op)
104
| K7R_IntBinOp(_,s,sd) -> [K7ROp_IntReg s; K7ROp_IntReg sd]
105
| K7R_IntBinOpMem(_,s,sd) -> k7memopToSrcrops s @
106
[K7ROp_MemOp s; K7ROp_IntReg sd]
107
| K7R_CondBranch(cond,_) -> branchconditionToSrcrops cond
108
| K7R_SimdLoad(_,s,_) -> K7ROp_MemoryState::(raddrToRops s)
109
| K7R_SimdStore(s,_,d) -> K7ROp_MemoryState::
110
(K7ROp_MMXReg s)::(raddrToRops d)
111
| K7R_SimdSpill(s,_) -> [K7ROp_MMXReg s;
112
K7ROp_IntReg k7rintreg_stackpointer]
114
| K7R_SimdCpyUnaryOpMem(op,s,_) -> k7memopToSrcrops s @
115
((K7ROp_MemOp s)::(simdcpyuopToSrcrops op))
116
| K7R_SimdUnaryOp(op,sd) -> simduopToSrcrops (K7ROp_MMXReg sd) op
117
| K7R_SimdCpyUnaryOp(op,s,_) -> (K7ROp_MMXReg s)::(simdcpyuopToSrcrops op)
119
| K7R_SimdBinOpMem(_,s,sd) -> k7memopToSrcrops s @
120
[K7ROp_MemOp s; K7ROp_MMXReg sd]
121
| K7R_SimdBinOp(_,s,sd) -> [K7ROp_MMXReg s; K7ROp_MMXReg sd]
126
| K7R_SimdLoadStoreBarrier -> [K7ROp_MemoryState]
127
| K7R_SimdPromiseCellSize _ -> []
129
(* WRITING OF K7ROPS ********************************************************)
131
let intuopToDstrops d = function
132
| K7_IPush -> [(K7ROp_IntReg k7rintreg_stackpointer,1)]
133
| K7_IPop -> [(K7ROp_IntReg k7rintreg_stackpointer,1); (d,1)]
134
| K7_IClear -> [(d,1); (zeroflag, 1)]
135
| K7_IInc -> [(d,1); (zeroflag, 1)]
136
| K7_IDec -> [(d,1); (zeroflag, 1)]
137
| K7_IAddImm _ -> [(d,1); (zeroflag, 1)]
138
| K7_ISubImm _ -> [(d,1); (zeroflag, 1)]
139
| K7_IShlImm _ -> [(d,1); (zeroflag, 1)]
140
| K7_IShrImm _ -> [(d,1); (zeroflag, 1)]
141
| K7_INegate -> [(d,1); (zeroflag, 1)]
142
| K7_ILoadValue _ -> [(d,1)]
144
let intcpyuopToDstrops d = function
145
| K7_ICopy -> [(d,1)]
146
| K7_IMulImm _ -> [(d,5)]
148
let simduopToLatency = function
150
| K7_FPMulConst _ -> 6
152
let simdbopToLatency = function
164
(* EXPORTED FUNCTIONS *******************************************************)
166
let k7rinstrToSrck7rops instr =
167
let reads = rinstrToSrcrops' instr in
168
K7ROp_IP::(if k7rinstrIsMMX instr then K7ROp_MMXState::reads else reads)
170
let k7rinstrToDstk7rops = function
171
| K7R_FEMMS -> [(K7ROp_MMXState, 2)]
172
| K7R_Ret -> [(K7ROp_IP, 4)]
173
| K7R_Label _ -> [(K7ROp_IP, 2); (K7ROp_MemoryState, 0)]
174
| K7R_Jump d -> [(K7ROp_IP, 4)]
175
| K7R_IntLoadMem(_,d) -> [(K7ROp_IntReg d, 4)]
176
| K7R_IntStoreMem(_,d) -> [(K7ROp_MemOp d, 4)]
177
| K7R_IntLoadEA(_,d) -> [(K7ROp_IntReg d, 2)]
178
| K7R_IntUnaryOp(op,sd) -> intuopToDstrops (K7ROp_IntReg sd) op
179
| K7R_IntUnaryOpMem(op,sd) -> intuopToDstrops (K7ROp_MemOp sd) op
180
| K7R_IntCpyUnaryOp(op,_,d) -> intcpyuopToDstrops (K7ROp_IntReg d) op
181
| K7R_IntBinOp(_,_,sd) -> [(K7ROp_IntReg sd, 1); (zeroflag, 1)]
182
| K7R_IntBinOpMem(_,_,sd) -> [(K7ROp_IntReg sd, 4); (zeroflag, 1)]
183
| K7R_CondBranch(_,d) -> [(K7ROp_IP, 4)]
184
| K7R_SimdLoad(_,_,d) -> [(K7ROp_MMXReg d, 4)]
185
| K7R_SimdStore _ -> []
186
| K7R_SimdSpill(_,d) -> [(mmxstackcell d, 4)]
187
| K7R_SimdUnaryOp(op,sd) -> [(K7ROp_MMXReg sd, simduopToLatency op)]
188
| K7R_SimdCpyUnaryOp(op,_,d) -> [(K7ROp_MMXReg d, 2)]
189
| K7R_SimdCpyUnaryOpMem(op,_,d) -> [(K7ROp_MMXReg d, 4)]
190
| K7R_SimdBinOp(op,_,sd) -> [(K7ROp_MMXReg sd, simdbopToLatency op)]
191
| K7R_SimdBinOpMem(op,_,sd) -> [(K7ROp_MMXReg sd, simdbopToLatency op+2)]
192
| K7R_SimdLoadStoreBarrier -> [(K7ROp_MemoryState, 0)]
193
| K7R_SimdPromiseCellSize _ -> [(K7ROp_IP, 0)]
195
let k7rinstrToMaxlatency instr = max_list (map snd (k7rinstrToDstk7rops instr))
198
(* returns true, if instruction x cannot roll over instruction y. *)
199
let k7rinstrCannotRollOverK7rinstr x y =
200
let (xR, xW) = (k7rinstrToSrck7rops x, map fst (k7rinstrToDstk7rops x))
201
and (yR, yW) = (k7rinstrToSrck7rops y, map fst (k7rinstrToDstk7rops y)) in
202
(* RAW *) lists_overlap xW yR ||
203
(* WAW *) lists_overlap xW yW ||
204
(* WAR *) lists_overlap xR yW