~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/hipe/x86/hipe_x86_ra_dummy.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
%%% -*- erlang-indent-level: 4 -*-
2
 
%%% $Id$
3
 
%%% simple local x86 regalloc
4
 
 
5
 
-module(hipe_x86_ra_dummy).
6
 
-export([ra/3]).
7
 
-include("hipe_x86.hrl").
8
 
-define(HIPE_INSTRUMENT_COMPILER, true). % enable instrumentation
9
 
-include("../main/hipe.hrl").
10
 
 
11
 
ra(X86Defun, Coloring_fp, Options) ->
12
 
    #defun{code=Code0} = X86Defun,
13
 
    Code1 = do_insns(Code0),
14
 
    %% Record all pseudos as spilled.
15
 
    %%     ?add_spills(Options, hipe_gensym:get_var() -
16
 
    %%          hipe_x86_registers:first_virtual()),
17
 
    NofSpilledFloats = count_non_float_spills(Coloring_fp),
18
 
    NofFloats = length(Coloring_fp),
19
 
    ?add_spills(Options, hipe_gensym:get_var() -
20
 
                hipe_x86_registers:first_virtual()-
21
 
                NofSpilledFloats -
22
 
                NofFloats),
23
 
    TempMap = [],
24
 
    {X86Defun#defun{code=Code1,
25
 
                    var_range={0, hipe_gensym:get_var()}},
26
 
     TempMap}.
27
 
 
28
 
count_non_float_spills(Coloring_fp)->
29
 
    count_non_float_spills(Coloring_fp,0).
30
 
count_non_float_spills([{_,To}|Tail], Num)->
31
 
    case hipe_x86_specific_fp:is_precolored(To) of
32
 
        true ->
33
 
            count_non_float_spills(Tail, Num);
34
 
        _ ->
35
 
            count_non_float_spills(Tail, Num+1)
36
 
    end;
37
 
count_non_float_spills([],Num) ->
38
 
    Num.
39
 
 
40
 
do_insns([I|Insns]) ->
41
 
    do_insn(I) ++ do_insns(Insns);
42
 
do_insns([]) ->
43
 
    [].
44
 
 
45
 
do_insn(I) ->   % Insn -> Insn list
46
 
    case I of
47
 
        #alu{} ->
48
 
            do_alu(I);
49
 
        #cmp{} ->
50
 
            do_cmp(I);
51
 
        #jmp_switch{} ->
52
 
            do_jmp_switch(I);
53
 
        #lea{} ->
54
 
            do_lea(I);
55
 
        #move{} ->
56
 
            do_move(I);
57
 
        #movzx{} ->
58
 
            do_movx(I);
59
 
        #movsx{} ->
60
 
            do_movx(I);
61
 
        #fmov{} ->
62
 
            do_fmov(I);
63
 
%       #fp_unop{} ->
64
 
%           do_fp_unop(I);
65
 
%       #fp_binop{} ->
66
 
%           do_fp_binop(I);
67
 
        #shift{} ->
68
 
            do_shift(I);
69
 
        _ ->
70
 
            %% comment, jmp*, label, pseudo_call, pseudo_jcc, pseudo_tailcall,
71
 
            %% pseudo_tailcall_prepare, push, ret
72
 
            [I]
73
 
    end.
74
 
 
75
 
%%% Fix an alu op.
76
 
 
77
 
do_alu(I) ->
78
 
    #alu{src=Src0,dst=Dst0} = I,
79
 
    {FixSrc,Src,FixDst,Dst} = do_binary(Src0, Dst0),
80
 
    FixSrc ++ FixDst ++ [I#alu{src=Src,dst=Dst}].
81
 
 
82
 
%%% Fix a cmp op.
83
 
 
84
 
do_cmp(I) ->
85
 
    #cmp{src=Src0,dst=Dst0} = I,
86
 
    {FixSrc, Src, FixDst, Dst} = do_binary(Src0, Dst0),
87
 
    FixSrc ++ FixDst ++ [I#cmp{src=Src,dst=Dst}].
88
 
 
89
 
%%% Fix a jmp_switch op.
90
 
 
91
 
do_jmp_switch(I) ->
92
 
    #jmp_switch{temp=Temp} = I,
93
 
    case temp_is_pseudo(Temp) of
94
 
        false ->
95
 
            [I];
96
 
        true ->
97
 
            Reg = hipe_x86:mk_temp(hipe_x86_registers:temp0(), 'untagged'),
98
 
            [hipe_x86:mk_move(Temp, Reg), I#jmp_switch{temp=Reg}]
99
 
    end.
100
 
 
101
 
%%% Fix a lea op.
102
 
 
103
 
do_lea(I) ->
104
 
    #lea{temp=Temp} = I,
105
 
    case temp_is_pseudo(Temp) of
106
 
        false ->
107
 
            [I];
108
 
        true ->
109
 
            Reg = hipe_x86:mk_temp(hipe_x86_registers:temp0(), 'untagged'),
110
 
            [I#lea{temp=Reg}, hipe_x86:mk_move(Reg, Temp)]
111
 
    end.
112
 
 
113
 
%%% Fix a move op.
114
 
 
115
 
do_move(I) ->
116
 
    #move{src=Src0,dst=Dst0} = I,
117
 
    {FixSrc, Src, FixDst, Dst} = do_binary(Src0, Dst0),
118
 
    FixSrc ++ FixDst ++ [I#move{src=Src,dst=Dst}].
119
 
 
120
 
do_movx(I) ->
121
 
    {FixSrc, Src} =
122
 
        case I of
123
 
            #movsx{src=Src0,dst=Dst0} ->
124
 
                fix_src_operand(Src0);
125
 
            #movzx{src=Src0,dst=Dst0} ->
126
 
                fix_src_operand(Src0)
127
 
        end,
128
 
    {FixDst, Dst} = fix_dst_operand(Dst0),
129
 
    Reg = hipe_x86_registers:temp0(),
130
 
    Dst2 = clone(Dst, Reg),
131
 
    I2 =
132
 
        case is_mem_opnd(Dst) of
133
 
            true ->
134
 
                Reg = hipe_x86_registers:temp0(),
135
 
                Dst2 = clone(Dst, Reg),
136
 
                case I of
137
 
                    #movsx{} ->
138
 
                        [hipe_x86:mk_movsx(Src, Dst2), hipe_x86:mk_move(Dst2, Dst)];
139
 
                    #movzx{} ->
140
 
                        [hipe_x86:mk_movzx(Src, Dst2), hipe_x86:mk_move(Dst2, Dst)]
141
 
                end;
142
 
            false ->
143
 
                case I of
144
 
                    #movsx{} ->
145
 
                        [hipe_x86:mk_movsx(Src, Dst)];
146
 
                    #movzx{} ->
147
 
                        [hipe_x86:mk_movzx(Src, Dst)]
148
 
                end
149
 
        end,
150
 
 
151
 
    FixSrc ++ FixDst ++ I2.
152
 
 
153
 
 
154
 
 
155
 
%%% Fix a fmov op.
156
 
 
157
 
do_fmov(I) ->
158
 
    #fmov{src=Src0,dst=Dst0} = I,
159
 
    {FixSrc, Src, FixDst, Dst} = do_binary(Src0, Dst0),
160
 
    FixSrc ++ FixDst ++ [I#fmov{src=Src,dst=Dst}].
161
 
 
162
 
do_shift(I) ->
163
 
    #shift{src=Src0,dst=Dst0} = I,
164
 
    {FixDst, Dst} = fix_dst_operand(Dst0),
165
 
    Reg = hipe_x86_registers:ecx(),
166
 
    case Src0 of
167
 
        #x86_imm{} ->
168
 
            FixDst ++ [I#shift{dst=Dst}];
169
 
        #x86_temp{reg=Reg}  ->
170
 
            FixDst ++ [I#shift{dst=Dst}]
171
 
    end.
172
 
 
173
 
%%% Fix the operands of a binary op.
174
 
%%% 1. remove pseudos from any explicit memory operands
175
 
%%% 2. if both operands are (implicit or explicit) memory operands,
176
 
%%%    move src to a reg and use reg as src in the original insn
177
 
 
178
 
do_binary(Src0, Dst0) ->
179
 
    {FixSrc, Src} = fix_src_operand(Src0),
180
 
    {FixDst, Dst} = fix_dst_operand(Dst0),
181
 
    {FixSrc3, Src3} =
182
 
        case is_mem_opnd(Src) of
183
 
            false ->
184
 
                {FixSrc, Src};
185
 
            true ->
186
 
                case is_mem_opnd(Dst) of
187
 
                    false ->
188
 
                        {FixSrc, Src};
189
 
                    true ->
190
 
                        Reg = hipe_x86_registers:temp0(),
191
 
                        Src2 = clone(Src, Reg),
192
 
                        FixSrc2 = FixSrc ++ [hipe_x86:mk_move(Src, Src2)],
193
 
                        {FixSrc2, Src2}
194
 
                end
195
 
        end,
196
 
    {FixSrc3, Src3, FixDst, Dst}.
197
 
 
198
 
%%% Fix any x86_mem operand to not refer to any pseudos.
199
 
%%% The fixup may use additional instructions and registers.
200
 
%%% 'src' operands may clobber '%temp0'.
201
 
%%% 'dst' operands may clobber '%temp1'.
202
 
%%% (This is not arbitrary. The translation of restore_catch does a
203
 
%%% "move %eax,<dst>", and fail_to does a "move <src>,%eax".)
204
 
 
205
 
fix_src_operand(Opnd) ->
206
 
    fix_mem_operand(Opnd, hipe_x86_registers:temp0()).
207
 
 
208
 
fix_dst_operand(Opnd) ->
209
 
    fix_mem_operand(Opnd, hipe_x86_registers:temp1()).
210
 
 
211
 
fix_mem_operand(Opnd, Reg) ->   % -> {[fixupcode], newop}
212
 
    case Opnd of
213
 
        #x86_mem{base=Base,off=Off} ->
214
 
            case is_mem_opnd(Base) of
215
 
                false ->
216
 
                    case src_is_pseudo(Off) of
217
 
                        false ->
218
 
                            {[], Opnd};
219
 
                        true ->         % pseudo(reg)
220
 
                            Temp = clone(Off, Reg),
221
 
                            {[hipe_x86:mk_move(Off, Temp)],
222
 
                             Opnd#x86_mem{off=Temp}}
223
 
                    end;
224
 
                true ->
225
 
                    Temp = clone(Base, Reg),
226
 
                    case src_is_pseudo(Off) of
227
 
                        false ->        % imm/reg(pseudo)
228
 
                            {[hipe_x86:mk_move(Base, Temp)],
229
 
                             Opnd#x86_mem{base=Temp}};
230
 
                        true ->         % pseudo1(pseudo0)
231
 
                            {[hipe_x86:mk_move(Base, Temp),
232
 
                              hipe_x86:mk_alu('add', Off, Temp)],
233
 
                             Opnd#x86_mem{base=Temp, off=hipe_x86:mk_imm(0)}}
234
 
                    end
235
 
            end;
236
 
        _ ->
237
 
            {[], Opnd}
238
 
    end.
239
 
 
240
 
%%% Check if an operand denotes a memory cell (mem or pseudo).
241
 
 
242
 
is_mem_opnd(Opnd) ->
243
 
    case Opnd of
244
 
        #x86_mem{} -> true;
245
 
        #x86_temp{} -> temp_is_pseudo(Opnd);
246
 
        _ -> false
247
 
    end.
248
 
 
249
 
%%% Check if an operand is a pseudo-Temp.
250
 
 
251
 
src_is_pseudo(Src) ->
252
 
    case hipe_x86:is_temp(Src) of
253
 
        true -> temp_is_pseudo(Src);
254
 
        false -> false
255
 
    end.
256
 
 
257
 
temp_is_pseudo(Temp = #x86_temp{type=Type}) ->
258
 
    if Type == 'double'-> false;
259
 
       true ->
260
 
            not(hipe_x86_registers:is_precoloured(hipe_x86:temp_reg(Temp)))
261
 
    end.
262
 
 
263
 
%%% Make Reg a clone of Dst (attach Dst's type to Reg).
264
 
 
265
 
clone(Dst, Reg) ->
266
 
    Type =
267
 
        case Dst of
268
 
            #x86_mem{} -> hipe_x86:mem_type(Dst);
269
 
            #x86_temp{} -> hipe_x86:temp_type(Dst)
270
 
        end,
271
 
    hipe_x86:mk_temp(Reg, Type).