1 : |
monnier |
221 |
(* shuffle.sml -- implements the parallel copy instruction as a sequence
|
2 : |
|
|
* of moves. Makes use of asmTmpR from CELLS.
|
3 : |
|
|
*
|
4 : |
|
|
* COPYRIGHT (c) 1996 Bell Laboratories.
|
5 : |
|
|
*
|
6 : |
|
|
*)
|
7 : |
|
|
|
8 : |
|
|
|
9 : |
|
|
functor Shuffle(I : INSTRUCTIONS) :
|
10 : |
|
|
sig
|
11 : |
|
|
val shuffle :
|
12 : |
|
|
{mvInstr : {dst:I.ea, src:I.ea} -> I.instruction list,
|
13 : |
|
|
ea : int -> I.ea}
|
14 : |
|
|
->
|
15 : |
|
|
{regMap: int -> int,
|
16 : |
|
|
temp : I.ea option,
|
17 : |
|
|
dst : int list,
|
18 : |
|
|
src : int list}
|
19 : |
|
|
-> I.instruction list
|
20 : |
|
|
end =
|
21 : |
|
|
struct
|
22 : |
|
|
datatype reg = REG of int | TEMP
|
23 : |
|
|
fun equal (REG r1, REG r2) = r1 = r2
|
24 : |
|
|
| equal (TEMP, TEMP) = true
|
25 : |
|
|
| equal _ = false
|
26 : |
|
|
|
27 : |
|
|
fun shuffle{mvInstr, ea} {regMap, temp, dst, src} = let
|
28 : |
|
|
fun opnd (REG dst) = ea dst
|
29 : |
|
|
| opnd TEMP = Option.valOf temp
|
30 : |
|
|
|
31 : |
|
|
(* perform unconstrained moves *)
|
32 : |
|
|
fun loop((p as (rd,rs))::rest, changed, used, done, instrs) =
|
33 : |
|
|
if List.exists (fn r => equal(r, rd)) used then
|
34 : |
|
|
loop(rest, changed, used, p::done, instrs)
|
35 : |
|
|
else loop(rest, true, used, done, mvInstr{dst=opnd rd, src=opnd rs}@instrs)
|
36 : |
|
|
| loop([], changed, _, done, instrs) = (changed, done, instrs)
|
37 : |
|
|
|
38 : |
|
|
fun cycle([], instrs) = instrs
|
39 : |
|
|
| cycle(moves, instrs) =
|
40 : |
|
|
(case loop(moves, false, map #2 moves, [], instrs)
|
41 : |
|
|
of (_, [], instrs) => instrs
|
42 : |
|
|
| (true, acc, instrs) => cycle(acc, instrs)
|
43 : |
|
|
| (false, (rd,rs)::acc, instrs) => let
|
44 : |
|
|
fun rename(p as (a,b)) = if equal(rd, b) then (a, TEMP) else p
|
45 : |
|
|
val acc' = (rd, rs) :: map rename acc
|
46 : |
|
|
val instrs' = mvInstr{dst=Option.valOf temp, src=opnd rd}@instrs
|
47 : |
|
|
val (_, acc'', instrs'') =
|
48 : |
|
|
loop(acc', false, map #2 acc', [], instrs')
|
49 : |
|
|
in cycle(acc'', instrs'')
|
50 : |
|
|
end
|
51 : |
|
|
(*esac*))
|
52 : |
|
|
|
53 : |
|
|
(* remove moves that have been coalesced. *)
|
54 : |
|
|
fun rmvCoalesced(rd::rds, rs::rss) = let
|
55 : |
|
|
val dst = regMap rd
|
56 : |
|
|
val src = regMap rs
|
57 : |
|
|
in
|
58 : |
|
|
if dst = src then rmvCoalesced(rds, rss)
|
59 : |
|
|
else (REG dst, REG src)::rmvCoalesced(rds, rss)
|
60 : |
|
|
end
|
61 : |
|
|
| rmvCoalesced([], []) = []
|
62 : |
|
|
in rev (cycle (rmvCoalesced(dst, src), []))
|
63 : |
|
|
end
|
64 : |
|
|
end
|
65 : |
|
|
|
66 : |
|
|
(*
|
67 : |
|
|
* $Log: shuffle.sml,v $
|
68 : |
|
|
* Revision 1.1.1.1 1998/11/16 21:48:41 george
|
69 : |
|
|
* Version 110.10
|
70 : |
|
|
*
|
71 : |
|
|
* Revision 1.1.1.1 1998/04/08 18:39:02 george
|
72 : |
|
|
* Version 110.5
|
73 : |
|
|
*
|
74 : |
|
|
*)
|