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

« back to all changes in this revision

Viewing changes to lib/hipe/sparc/hipe_sparc_linker.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
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
 
%%  Filename :  hipe_sparc_linker.erl
3
 
%%  Module   :  hipe_sparc_linker
4
 
%%  History  :  * 2000-10-30 Erik Johansson (happi@csd.uu.se): 
5
 
%%               Created.
6
 
%%  CVS      :
7
 
%%              $Author: pegu2945 $
8
 
%%              $Date: 2002/11/05 12:22:43 $
9
 
%%              $Revision: 1.22 $
10
 
%% ====================================================================
11
 
%%  Exports  :
12
 
%%
13
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
 
 
15
 
-module(hipe_sparc_linker).
16
 
-export([pack_constants/1, preprocess/5, assemble/3]).
17
 
 
18
 
-include("../../kernel/src/hipe_ext_format.hrl").
19
 
-include("../main/hipe.hrl").
20
 
-include("../rtl/hipe_literals.hrl").
21
 
%%=====================================================================
22
 
 
23
 
 
24
 
%% Move to sparc_assembler...
25
 
assemble(Code,Map,ConstMap) ->
26
 
  assemble1(Code,0,0,
27
 
            init_export_map(Map),      %% Convert to more efficent
28
 
            init_const_map(ConstMap),  %%  datastructures.
29
 
            [],[],[],[]).
30
 
 
31
 
assemble1([{MFA,Hot,Cold}|Rest],HAddr,CAddr,Map,ConstMap,AccHCode,AccCCode,AccHRefs,AccCRefs) ->
32
 
  %% io:format("Assembling ~w\n",[MFA]),
33
 
  {HCode,NewHAddr,HRefs} = 
34
 
    assemble(Hot,MFA,HAddr,
35
 
             local_labels(MFA,Map),
36
 
             ConstMap,AccHRefs,[],hot),
37
 
  {CCode,NewCAddr,CRefs} = assemble(Cold,MFA,CAddr,
38
 
                                    local_labels(MFA,Map),
39
 
                                    ConstMap,AccCRefs,[],cold),
40
 
  assemble1(Rest,NewHAddr,NewCAddr,Map,ConstMap,AccHCode++HCode,AccCCode++CCode,HRefs,CRefs);
41
 
assemble1([],HAddr,CAddr,_Map,_ConstMap,AccHCode,AccCCode,AccHRefs,AccCRefs) ->
42
 
  {HAddr,CAddr,AccHCode,AccCCode,AccHRefs,AccCRefs}.
43
 
 
44
 
assemble([I|Is],MFA,Addr,Map,ConstMap,Refs,Code,Seg) ->
45
 
  Type = hipe_sparc:type(I),
46
 
 
47
 
  case  
48
 
    case Type of
49
 
      call_link -> resolve_call_link(I,Addr,Refs,MFA,Map,Seg);
50
 
      b -> resolve_b(I,Addr,Refs,MFA,Map,Seg);
51
 
      goto -> resolve_goto(I,Addr,Refs,MFA,Map,Seg);
52
 
      load_address -> resolve_load_address(I,Addr,Refs,MFA,Map,ConstMap);
53
 
      load_atom -> resolve_load_atom(I,Addr,Refs,MFA,Map);
54
 
      load_word_index -> resolve_load_word_index(I,Addr,Refs,MFA,Map,ConstMap);
55
 
      alu -> {hipe_sparc_assemble:assemble_alu(I),Addr+4,Refs};
56
 
      alu_cc -> {hipe_sparc_assemble:assemble_alu_cc(I),Addr+4,Refs};
57
 
      store -> {hipe_sparc_assemble:assemble_store(I),Addr+4,Refs};
58
 
      move -> {hipe_sparc_assemble:assemble_move(I),Addr+4,Refs};
59
 
      load -> {hipe_sparc_assemble:assemble_load(I),Addr+4,Refs};
60
 
      store_fp -> {hipe_sparc_assemble:assemble_store_fp(I),Addr+4,Refs};
61
 
      load_fp -> {hipe_sparc_assemble:assemble_load_fp(I),Addr+4,Refs};
62
 
      fb -> {hipe_sparc_assemble:assemble_fb(I),Addr+4,Refs};
63
 
      fop -> {hipe_sparc_assemble:assemble_fop(I),Addr+4,Refs};
64
 
      fcmp -> {hipe_sparc_assemble:assemble_fcmp(I),Addr+4,Refs};
65
 
      fmov -> {hipe_sparc_assemble:assemble_fmov(I),Addr+4,Refs};
66
 
      conv_fp -> {hipe_sparc_assemble:assemble_conv_fp(I),Addr+4,Refs};
67
 
      jmp -> {hipe_sparc_assemble:assemble_jmp(I),Addr+4,Refs};
68
 
      nop -> {hipe_sparc_assemble:assemble_nop(I),Addr+4,Refs};
69
 
      sethi -> {hipe_sparc_assemble:assemble_sethi(I),Addr+4,Refs};
70
 
      Other -> exit({bad_type,Other})
71
 
    end of
72
 
    {[I1,I2],NewAddr,NewRefs} ->
73
 
      assemble(Is,MFA,NewAddr,Map,ConstMap,NewRefs,[I1,I2|Code],Seg);
74
 
    {C,NewAddr,NewRefs}  ->
75
 
      assemble(Is,MFA,NewAddr,Map,ConstMap,NewRefs,[C|Code],Seg)
76
 
  end;
77
 
assemble([],_,Addr,_,_,Refs,Code,_) ->
78
 
  {lists:reverse(Code),Addr,Refs}.
79
 
 
80
 
resolve_load_address(Instr,Addr,Refs,MFA,Map,ConstMap)->
81
 
  Dest = hipe_sparc:load_address_dest(Instr),
82
 
  Address = hipe_sparc:load_address_address(Instr),
83
 
  Ref = 
84
 
    case hipe_sparc:load_address_type(Instr) of
85
 
      label ->
86
 
        {Zone,Offset} = find(Address, Map),
87
 
        [{?PATCH_TYPE2EXT(load_address),
88
 
          Addr,
89
 
          {label,Zone,Offset,MFA}}]; 
90
 
      function -> 
91
 
        case lists:member(local,hipe_sparc:info(Instr)) of
92
 
          true -> %% local enter
93
 
            [{?PATCH_TYPE2EXT(load_address),
94
 
              Addr, {local_function,Address}}];
95
 
          false -> %% remote enter
96
 
            [{?PATCH_TYPE2EXT(load_address),
97
 
              Addr, {remote_function,Address}}]
98
 
        end;
99
 
      constant ->
100
 
        ConstNo = find_const({MFA,Address},ConstMap),
101
 
        [{?PATCH_TYPE2EXT(load_address),
102
 
          Addr, {const, ConstNo}}];
103
 
      closure ->
104
 
        [{?PATCH_TYPE2EXT(load_address),
105
 
                     Addr, {closure, Address}}];
106
 
      c_const ->
107
 
        [{?PATCH_TYPE2EXT(load_address),
108
 
                     Addr, {c_const, Address}}];
109
 
      Type ->     
110
 
        exit([{problem,{not_handled,{address,Type}}},{at,Instr}])
111
 
    end,
112
 
  
113
 
  Hi = hipe_sparc:mk_imm(0),
114
 
  Lo = hipe_sparc:mk_imm(0),
115
 
  I1 = hipe_sparc:sethi_create(Dest,Hi,[]),
116
 
  I2 = hipe_sparc:alu_create(Dest,Dest,'or',Lo,[]),
117
 
 
118
 
  {[
119
 
    hipe_sparc_assemble:assemble_instr(alu,I2),
120
 
    hipe_sparc_assemble:assemble_instr(sethi,I1)],
121
 
   Addr+8,
122
 
   Ref++Refs}.
123
 
 
124
 
resolve_goto(I,Addr,Refs,_MFA,Map,Seg) ->
125
 
  Dest = hipe_sparc:goto_label(I),
126
 
  {DestSeg,Address} = find(Dest,Map),
127
 
  RelDest = (Address - Addr) div 4,
128
 
  if DestSeg == Seg ->
129
 
      case catch hipe_sparc_assert:check_branch_length(RelDest) of
130
 
        true -> true;
131
 
        {'EXIT',{too_long_branch,Length}} ->
132
 
          exit([{problem,too_long_branch},
133
 
                {address,Addr},
134
 
                {length,Length}])
135
 
      end,
136
 
      NewI = hipe_sparc:goto_label_update(I,RelDest),
137
 
      Code = hipe_sparc_assemble:assemble_instr(goto,NewI),
138
 
      {Code,Addr+4,Refs};
139
 
     true ->
140
 
      NewI = hipe_sparc:goto_label_update(I,0),
141
 
      Code = hipe_sparc_assemble:assemble_instr(goto,NewI),
142
 
      {Code,Addr+4,[{goto,Addr,{DestSeg,Address}}|Refs]}
143
 
  end.
144
 
  
145
 
resolve_b(I,Addr,Refs,_MFA,Map,Seg) ->
146
 
  Dest = hipe_sparc:b_label(I),
147
 
  {DestSeg,Address} = find(Dest,Map),
148
 
  RelDest = (Address - Addr) div 4,
149
 
  if DestSeg == Seg ->
150
 
      case catch hipe_sparc_assert:check_branch_length(RelDest) of
151
 
        true -> true;
152
 
        {'EXIT',{too_long_branch,Length}} ->
153
 
          exit([{problem,too_long_branch},
154
 
                {address,Addr},
155
 
                {length,Length}])
156
 
      end,
157
 
      NewI = hipe_sparc:b_label_update(I,RelDest),
158
 
      Code = hipe_sparc_assemble:assemble_instr(b,NewI),
159
 
      {Code,Addr+4,Refs};
160
 
     true ->
161
 
      NewI = hipe_sparc:b_label_update(I,0),
162
 
      Code = hipe_sparc_assemble:assemble_instr(b,NewI),
163
 
      {Code,Addr+4,[{b,Addr,{DestSeg,Address}}|Refs]}
164
 
  end.
165
 
 
166
 
resolve_load_atom(Instr,Addr,Refs,_MFA,_Map)->
167
 
  Atom = hipe_sparc:load_atom_atom(Instr),
168
 
  Dest = hipe_sparc:load_atom_dest(Instr),
169
 
  Info = hipe_sparc:info(Instr),
170
 
  I1 = hipe_sparc:sethi_create(Dest,
171
 
                               hipe_sparc:mk_imm(0),Info),
172
 
  I2 = hipe_sparc:alu_create(Dest,Dest, 'or', 
173
 
                             hipe_sparc:mk_imm(0),Info),
174
 
  {[hipe_sparc_assemble:assemble_instr(alu,I2),
175
 
    hipe_sparc_assemble:assemble_instr(sethi,I1)],
176
 
   Addr+8,[{?PATCH_TYPE2EXT(load_atom),Addr, Atom}|Refs]}.
177
 
 
178
 
resolve_load_word_index(_Instr,_Addr,_Refs,_MFA,_Map,_ConstMap) ->
179
 
  ?EXIT({nyi,resolve_load_word_index}).
180
 
%%  Index =hipe_sparc:load_word_index_index(Instr),
181
 
%%  Block =hipe_sparc:load_word_index_block(Instr),
182
 
%% Dest = hipe_sparc:load_word_index_dest(Instr),
183
 
%%  Info = hipe_sparc:info(Instr),
184
 
%%
185
 
%%  ConstNo = find_const({MFA,Block},ConstMap),
186
 
%%  I1 = hipe_sparc:sethi_create(Dest,
187
 
%%                             hipe_sparc:mk_imm(0),Info),
188
 
%%  I2 = hipe_sparc:alu_create(Dest,Dest, 'or', 
189
 
%%                           hipe_sparc:mk_imm(0),Info),
190
 
%%  {[hipe_sparc_assemble:assemble_instr(alu,I2),
191
 
%%    hipe_sparc_assemble:assemble_instr(sethi,I1)],
192
 
%%   Addr+8,[{?PATCH_TYPE2EXT(load_word_index),Addr, {word_index, ConstNo, Index}}|Refs]}.
193
 
   
194
 
resolve_call_link(Instr,Addr,OldRefs,_MFA,Map,_Seg)->
195
 
  Target = hipe_sparc:call_link_target(Instr),
196
 
  ExnLab = hipe_sparc:call_link_fail(Instr),
197
 
 
198
 
 
199
 
  %% Get the stack descriptor information
200
 
  SD = hipe_sparc:call_link_stack_desc(Instr),
201
 
  FSize = hipe_sparc_stack_descriptors:get_size(SD),
202
 
  Live =  list_to_tuple(hipe_sparc_stack_descriptors:get_live(SD)),
203
 
  Arity = case hipe_sparc_stack_descriptors:get_arity(SD) of
204
 
            N when N > ?SPARC_ARGS_IN_REGS -> N - ?SPARC_ARGS_IN_REGS;
205
 
            _ -> 0
206
 
          end,
207
 
  ExnRA =
208
 
    case ExnLab of
209
 
      [] -> []; % don't cons up a new one
210
 
      _ -> find(ExnLab,Map)
211
 
    end,
212
 
 
213
 
  %% The stack descriptor needs to be inserted into the system at load-time.
214
 
  Refs = 
215
 
    [{?PATCH_TYPE2EXT(sdesc),
216
 
      Addr,
217
 
      ?STACK_DESC(ExnRA, FSize, Arity, Live)} | OldRefs],
218
 
 
219
 
  case hipe_sparc:call_link_type(Instr) of
220
 
    closure -> 
221
 
      NewI = hipe_sparc:jmp_link_create(
222
 
               hipe_sparc:call_link_target(Instr),
223
 
               hipe_sparc:mk_imm(0), 
224
 
               hipe_sparc:mk_reg(hipe_sparc_registers:return_address()),
225
 
               hipe_sparc:call_link_args(Instr),
226
 
               hipe_sparc:info(Instr)),
227
 
      Code =  hipe_sparc_assemble:assemble_instr(jmp_link,NewI),
228
 
      {Code,Addr+4, Refs};
229
 
    _ -> 
230
 
      NewRefs =
231
 
        case lists:member(local,hipe_sparc:info(Instr)) of
232
 
          true -> %%  local call
233
 
            [{?PATCH_TYPE2EXT(call_local),
234
 
              Addr, Target} | Refs];
235
 
          _ -> %% Remote call
236
 
            [{?PATCH_TYPE2EXT(call_remote),
237
 
              Addr, Target} | Refs]
238
 
        end,
239
 
      NewI = hipe_sparc:call_link_target_update(Instr,0),
240
 
      Code = hipe_sparc_assemble:assemble_instr(call_link,NewI),
241
 
      {Code,Addr+4,NewRefs}
242
 
  end.
243
 
 
244
 
 
245
 
 
246
 
 
247
 
 
248
 
  
249
 
preprocess({{Block,Entry},Rest},MFA,HotAddress,ColdAddress,Map) ->
250
 
%%  io:format("~w at ~w ~w\n",[MFA,HotAddress,ColdAddress]),
251
 
  process([{Block,Entry}|Rest],[],[],HotAddress,ColdAddress,
252
 
              [{{MFA,entry},Block,
253
 
                case Block of
254
 
                  hot ->
255
 
                    HotAddress;
256
 
                 cold ->
257
 
                   ColdAddress
258
 
                end}|Map],
259
 
          MFA).
260
 
 
261
 
 
262
 
process([{Block,Code}|Rest],Hot,Cold,HotSize,ColdSize,Map,MFA) ->
263
 
 
264
 
  case Block of
265
 
    hot ->
266
 
      {NewCode,NewSize,NewMap} = process_instr(Code,HotSize,Map,MFA,[],hot),
267
 
      process(Rest,NewCode++Hot,Cold,NewSize,ColdSize,NewMap,MFA);
268
 
    cold ->
269
 
      {NewCode,NewSize,NewMap} = process_instr(Code,ColdSize,Map,MFA,[],cold),
270
 
      process(Rest,Hot,NewCode++Cold,HotSize,NewSize,NewMap,MFA)
271
 
  end;
272
 
process([],Hot,Cold,HotSize,ColdSize,Map,_) ->
273
 
  {Hot,Cold,HotSize,ColdSize,Map}.
274
 
 
275
 
process_instr([I|Is],Size,Map,MFA,AccCode,Block) ->
276
 
  case hipe_sparc:type(I) of
277
 
    label ->
278
 
      process_instr(Is,Size,[{{MFA,hipe_sparc:label_name(I)},Block,Size}|Map],MFA,AccCode,Block);
279
 
    comment ->
280
 
      process_instr(Is,Size,Map,MFA,AccCode,Block);
281
 
    load_address ->
282
 
      process_instr(Is,Size+8,Map,MFA,[I|AccCode],Block);
283
 
    load_atom ->
284
 
      process_instr(Is,Size+8,Map,MFA,[I|AccCode],Block);
285
 
    load_word_index ->
286
 
      process_instr(Is,Size+8,Map,MFA,[I|AccCode],Block);
287
 
    _Other ->
288
 
      process_instr(Is,Size+4,Map,MFA,[I|AccCode],Block)
289
 
  end;
290
 
process_instr([],Size,Map,_,Code,_) ->
291
 
  {lists:reverse(Code),Size,Map}.
292
 
 
293
 
 
294
 
 
295
 
 
296
 
pack_constants(Data) ->
297
 
  pack_constants(Data,0,0,[],[]).
298
 
 
299
 
pack_constants([{MFA,_,ConstTab}|Rest],AccSize,ConstNo,Acc,Refs) ->
300
 
  Labels = hipe_consttab:labels(ConstTab),
301
 
  %% RefToLabels = hipe_consttab:referred_labels(ConstTab),
302
 
  {Size, Map, NewConstNo, RefToLabels} = 
303
 
    pack_labels(Labels,MFA,ConstTab,AccSize, ConstNo,[], []),
304
 
  NewRefs =
305
 
    case  RefToLabels of 
306
 
      [] -> Refs;
307
 
      _ -> [{MFA,RefToLabels}| Refs]
308
 
    end,
309
 
 
310
 
  pack_constants(Rest, Size, NewConstNo, 
311
 
                 Map++Acc, NewRefs);
312
 
pack_constants([], Size, _, Acc, Refs) -> {Size, Acc, Refs}.
313
 
 
314
 
pack_labels([{_Label,ref}|Labels],MFA,ConstTab,AccSize, ConstNo, Acc, Refs) ->
315
 
  pack_labels(Labels,MFA,ConstTab,AccSize, ConstNo, Acc, Refs);
316
 
pack_labels([Label|Labels],MFA,ConstTab,AccSize, ConstNo, Acc, Refs) ->
317
 
  Const = hipe_consttab:lookup(Label,ConstTab),
318
 
  Size = hipe_consttab:const_size(Const),
319
 
  Align = hipe_consttab:const_align(Const),
320
 
  Start = 
321
 
    case AccSize rem Align of
322
 
      0 -> AccSize;
323
 
 
324
 
      N -> AccSize + (Align -N)
325
 
    end,
326
 
  Need = Size, %% Do we need to consider alignment?
327
 
  %% io:format("Const ~w, Size ~w, Need ~w\n",[Const,Size,Need]),
328
 
  RawType = hipe_consttab:const_type(Const),
329
 
  Type = ?CONST_TYPE2EXT(RawType),
330
 
  RawData = hipe_consttab:const_data(Const),
331
 
  {Data, NewRefs} = 
332
 
    case RawType of
333
 
      term -> {RawData,[]};
334
 
      sorted_block -> {RawData, []};
335
 
      block -> 
336
 
        case RawData of
337
 
          {ElementType, ElementData} ->
338
 
            decompose_block(ElementType, ElementData, Start);
339
 
          {ElementType, ElementData, SortOrder} ->
340
 
            {TblData, TblRefs} = get_sorted_refs(ElementData, SortOrder),
341
 
            {hipe_consttab:decompose({ElementType, TblData}), [{sorted,Start,TblRefs}]}
342
 
        end
343
 
            
344
 
    end,
345
 
                
346
 
  pack_labels(Labels,MFA,ConstTab,Start+Need,ConstNo+1,
347
 
              [{MFA,Label,ConstNo,
348
 
                Start,Need,
349
 
                Type, Data,
350
 
                ?BOOL2EXT(hipe_consttab:const_exported(Const))}|
351
 
               Acc],
352
 
              NewRefs++Refs);
353
 
pack_labels([],_,_,AccSize,ConstNo,Acc,Refs) ->
354
 
  {AccSize,Acc, ConstNo, Refs}.
355
 
 
356
 
decompose_block(ElementType, Data, Addr) ->
357
 
  ElementSize = hipe_consttab:size_of(ElementType),
358
 
  {NewData, Refs} = get_refs(Data,Addr,ElementSize),
359
 
  {hipe_consttab:decompose({ElementType, NewData}), Refs}.
360
 
 
361
 
get_refs([{label,L}|Rest],Pos,4) ->
362
 
  {NewData, Refs} = get_refs(Rest, Pos+4, 4),
363
 
  {[0|NewData],[{L,Pos}|Refs]};
364
 
get_refs([D|Rest],Pos, Size) ->
365
 
  {NewData, Refs} = get_refs(Rest, Pos+Size, Size),
366
 
  {[D|NewData],Refs};
367
 
get_refs([],_,_) ->
368
 
  {[],[]}.
369
 
 
370
 
get_sorted_refs([{label,L}|Rest], [Ordering|Os]) ->
371
 
  {NewData, Refs} = get_sorted_refs(Rest, Os),
372
 
  {[0|NewData],[{L,Ordering}|Refs]};
373
 
get_sorted_refs([D|Rest], [_Ordering|Os]) ->
374
 
  {NewData, Refs} = get_sorted_refs(Rest, Os),
375
 
  {[D|NewData],Refs};
376
 
get_sorted_refs([],[]) ->
377
 
  {[],[]}.
378
 
 
379
 
 
380
 
%% ------------------------------------------------------------------
381
 
%% Constant map
382
 
%%
383
 
 
384
 
find_const(Name, Tree) ->
385
 
  case gb_trees:lookup(Name,Tree) of
386
 
    {value,V} -> V;
387
 
    none -> ?EXIT({could_not_find_constant, Name, Tree})
388
 
  end.
389
 
 
390
 
init_const_map(List) ->
391
 
  init_const_map(List, gb_trees:empty()).
392
 
init_const_map([{MFA,Label,ConstNo,_,_, _, _,_} | List], Tree) ->
393
 
  init_const_map(List,gb_trees:insert({MFA,Label}, ConstNo ,Tree));
394
 
init_const_map([], Tree) -> Tree.
395
 
 
396
 
 
397
 
%% ------------------------------------------------------------------
398
 
%% Label map
399
 
%%
400
 
 
401
 
-ifdef(LISTMAP).
402
 
find(Name,[{Name,Seg,Addr}|_]) ->
403
 
  {Seg,Addr};
404
 
find(Name,[_|Rest]) ->
405
 
  find(Name,Rest);
406
 
find({Name,entry},[]) -> %% This function is not being compiled.
407
 
  {none, 0}.
408
 
init_export_map(List) ->
409
 
  List.
410
 
-else.
411
 
 
412
 
-ifdef(GBTREEMAP).
413
 
find(Name, Tree) ->
414
 
  case gb_trees:lookup(Name,Tree) of
415
 
    {value,V} -> V;
416
 
    none -> {none,0}  %% This function is not being compiled.
417
 
  end.
418
 
 
419
 
init_export_map(List) ->
420
 
  init_export_map(List, gb_trees:empty()).
421
 
init_export_map([{Name,Seg,Addr}|List], Tree) ->
422
 
  init_export_map(List,gb_trees:insert(Name,{Seg,Addr},Tree));
423
 
init_export_map([], Tree) -> Tree.
424
 
-else.
425
 
 
426
 
 
427
 
-ifdef(DICTMAP).
428
 
 
429
 
find(Name, Tree) ->
430
 
  case dict:find(Name,Tree) of
431
 
    {ok,V} -> V;
432
 
    error -> {none,0}  %% This Label is not being compiled.
433
 
  end.
434
 
init_export_map(List) ->
435
 
  init_export_map(List, dict:new()).
436
 
% init_export_map3([{Name,Seg,Addr}|List], Tree) ->
437
 
%   init_export_map3(List,dict:store(Name,{Seg,Addr},Tree));
438
 
% init_export_map3([], Tree) -> Tree.
439
 
 
440
 
-else.
441
 
-ifdef(DOUBLEDICTMAP).
442
 
find({M,L}, Tree) ->
443
 
  case dict:find(M,Tree) of
444
 
    {ok,D} -> 
445
 
      case dict:find(L,D) of
446
 
        {ok,V} -> V;
447
 
        error -> {none,0}  
448
 
      end;
449
 
    error -> {none,0}  %% This Label is not being compiled.
450
 
  end.
451
 
 
452
 
init_export_map(List) ->
453
 
  init_export_map(List, dict:new()).
454
 
 
455
 
init_export_map([{{M,L},Seg,Addr}|List], Tree) ->
456
 
  init_export_map(List,init_dm(M,L,{Seg,Addr},Tree));
457
 
init_export_map([], Tree) -> Tree.
458
 
init_dm(M,L,Data,Tree) ->
459
 
  case dict:find(M,Tree) of
460
 
    {ok, T2} ->
461
 
      dict:store(M, dict:store(L,Data,T2), Tree);
462
 
    error ->
463
 
      dict:store(M, dict:store(L,Data,dict:new()), Tree)
464
 
  end.
465
 
-else.
466
 
 
467
 
-ifdef(ARRAYMAP).
468
 
local_labels(MFA, Map) ->
469
 
  case gb_trees:lookup(MFA, Map) of
470
 
    {value,T} -> T;
471
 
    none -> ?EXIT({mfa_not_in_map,MFA,Map})
472
 
  end.
473
 
  
474
 
 
475
 
find(L, Arr) ->
476
 
  {hot,hipe_bifs:array_sub(Arr,L)}.
477
 
 
478
 
init_export_map(List) ->
479
 
  MaxL = highestl(List,0),
480
 
  init_export_map(List, gb_trees:empty(), MaxL).
481
 
init_export_map([{{M,L},Seg,Addr}|List], Tree, MaxL) ->
482
 
  init_export_map(List,init_m(M,L,Addr,Tree, MaxL), MaxL);
483
 
init_export_map([], Tree, _) -> 
484
 
  Tree.
485
 
 
486
 
highestl([{{_,entry},_,_}|List], Max) ->
487
 
  highestl(List, Max);
488
 
 
489
 
highestl([{{_,L},_,_}|List], Max) ->
490
 
  if L > Max ->
491
 
      highestl(List, L);
492
 
     true ->
493
 
      highestl(List,Max)
494
 
  end;
495
 
highestl([], Max) -> Max+1.
496
 
 
497
 
init_m(M,entry,Data,Tree, MaxL) -> Tree;
498
 
init_m(M,L,Data,Tree, MaxL) ->
499
 
  case gb_trees:lookup(M,Tree) of
500
 
    {value, T2} ->
501
 
      hipe_bifs:array_update(T2,L,Data),
502
 
      Tree;
503
 
    none ->
504
 
      Arr = hipe_bifs:array(MaxL,0),
505
 
      hipe_bifs:array_update(Arr,L,Data),
506
 
      gb_trees:insert(M, Arr, Tree)
507
 
  end.
508
 
 
509
 
-else.
510
 
 
511
 
%% ----------------------------------------------------
512
 
%% DEFAULT
513
 
%% DOUBLTREESMAP
514
 
 
515
 
local_labels(MFA, Map) ->
516
 
  case gb_trees:lookup(MFA, Map) of
517
 
    {value,T} -> T;
518
 
    none -> ?EXIT({mfa_not_in_map,MFA,Map})
519
 
  end.
520
 
  
521
 
 
522
 
find(L, Tree) ->
523
 
  case gb_trees:lookup(L,Tree) of
524
 
    {value,V} -> V;
525
 
    none -> ?EXIT({label_not_in_map,L,Tree})
526
 
  end.
527
 
 
528
 
init_export_map(List) ->
529
 
  init_export_map(List, gb_trees:empty()).
530
 
init_export_map([{{M,L},Seg,Addr}|List], Tree) ->
531
 
  init_export_map(List,init_m(M,L,{Seg,Addr},Tree));
532
 
init_export_map([], Tree) -> Tree.
533
 
 
534
 
 
535
 
init_m(M,L,Data,Tree) ->
536
 
  case gb_trees:lookup(M,Tree) of
537
 
    {value, T2} ->
538
 
      gb_trees:update(M, gb_trees:insert(L,Data,T2), Tree);
539
 
    none ->
540
 
      gb_trees:insert(M, gb_trees:insert(L,Data,gb_trees:empty()), Tree)
541
 
  end.
542
 
 
543
 
 
544
 
 
545
 
 
546
 
-endif.
547
 
-endif.
548
 
-endif.
549
 
-endif.
550
 
-endif.
551
 
 
552
 
 
553
 
 
554
 
 
555
 
                      
556
 
 
557
 
 
558
 
 
559