1%% -*- erlang-indent-level: 2 -*-
2
3-module(hipe_rtl_to_llvm).
4-author("Chris Stavrakakis, Yiannis Tsiouris").
5
6-export([translate/2]).    % the main function of this module
7-export([fix_mfa_name/1]). % a help function used in hipe_llvm_main
8
9-include("../rtl/hipe_rtl.hrl").
10-include("../rtl/hipe_literals.hrl").
11-include("hipe_llvm_arch.hrl").
12
13-define(BITS_IN_WORD, (?bytes_to_bits(hipe_rtl_arch:word_size()))).
14-define(BITS_IN_BYTE, (?bytes_to_bits(1))).
15-define(BRANCH_META_TAKEN, "0").
16-define(BRANCH_META_NOT_TAKEN, "1").
17-define(FIRST_FREE_META_NO, 2).
18-define(HIPE_LITERALS_META, "hipe.literals").
19
20%%------------------------------------------------------------------------------
21%% @doc Main function for translating an RTL function to LLVM Assembly. Takes as
22%%      input the RTL code and the variable indexes of possible garbage
23%%      collection roots and returns the corresponing LLVM, a dictionary with
24%%      all the relocations in the code and a hipe_consttab() with informaton
25%%      about data.
26%%------------------------------------------------------------------------------
27translate(RTL, Roots) ->
28  Fun = hipe_rtl:rtl_fun(RTL),
29  Params = hipe_rtl:rtl_params(RTL),
30  Data = hipe_rtl:rtl_data(RTL),
31  Code = hipe_rtl:rtl_code(RTL),
32  %% Init unique symbol generator and initialize the label counter to the last
33  %% RTL label.
34  hipe_gensym:init(llvm),
35  {_, MaxLabel} = hipe_rtl:rtl_label_range(RTL),
36  put({llvm,label_count}, MaxLabel + 1),
37  %% Put first label of RTL code in process dictionary
38  find_code_entry_label(Code),
39  %% Initialize relocations symbol dictionary
40  Relocs = dict:new(),
41  %% Print RTL to file
42  %% {ok, File_rtl} = file:open("rtl_" ++integer_to_list(random:uniform(2000))
43  %%                            ++ ".rtl", [write]),
44  %% hipe_rtl:pp(File_rtl, RTL),
45  %% file:close(File_rtl),
46
47  %% Pass on RTL code to handle exception handling and identify labels of Fail
48  %% Blocks
49  {Code1, FailLabels} = fix_code(Code),
50  %% Allocate stack slots for each virtual register and declare gc roots
51  AllocaStackCode = alloca_stack(Code1, Params, Roots),
52  %% Translate Code
53  {LLVM_Code1, Relocs1, NewData} =
54    translate_instr_list(Code1, [], Relocs, Data),
55  %% Create LLVM code to declare relocation symbols as external symbols along
56  %% with local variables in order to use them as just any other variable
57  {FinalRelocs, ExternalDecl0, LocalVars} =
58    handle_relocations(Relocs1, Data, Fun),
59  ExternalDecl = add_literals_metadata(ExternalDecl0),
60  %% Pass on LLVM code in order to create Fail blocks and a landingpad
61  %% instruction to each one
62  LLVM_Code2 = add_landingpads(LLVM_Code1, FailLabels),
63  %% Create LLVM Code for the compiled function
64  LLVM_Code3 = create_function_definition(Fun, Params, LLVM_Code2,
65                                          AllocaStackCode ++ LocalVars),
66  %% Final Code = CompiledFunction + External Declarations
67  FinalLLVMCode = [LLVM_Code3 | ExternalDecl],
68  {FinalLLVMCode, FinalRelocs, NewData}.
69
70find_code_entry_label([]) ->
71  exit({?MODULE, find_code_entry_label, "Empty code"});
72find_code_entry_label([I|_]) ->
73  case hipe_rtl:is_label(I) of
74    true ->
75      put(first_label, hipe_rtl:label_name(I));
76    false ->
77      exit({?MODULE, find_code_entry_label, "First instruction is not a label"})
78  end.
79
80%% @doc Create a stack slot for each virtual register. The stack slots
81%%      that correspond to possible garbage collection roots must be
82%%      marked as such.
83alloca_stack(Code, Params, Roots) ->
84  %% Find all assigned virtual registers
85  Destinations = collect_destinations(Code),
86  %% Declare virtual registers, and declare garbage collection roots
87  do_alloca_stack(Destinations++Params, Params, Roots).
88
89collect_destinations(Code) ->
90  lists:usort(lists:flatmap(fun insn_dst/1, Code)).
91
92do_alloca_stack(Destinations, Params, Roots) ->
93  do_alloca_stack(Destinations, Params, Roots, []).
94
95do_alloca_stack([], _, _, Acc) ->
96  Acc;
97do_alloca_stack([D|Ds], Params, Roots, Acc) ->
98  {Name, _I} = trans_dst(D),
99  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
100  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
101  ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
102  case hipe_rtl:is_var(D) of
103    true ->
104      Num = hipe_rtl:var_index(D),
105      I1 = hipe_llvm:mk_alloca(Name, WordTy, [], []),
106      case lists:member(Num, Roots) of
107        true -> %% Variable is a possible Root
108          T1 = mk_temp(),
109          BYTE_TYPE_PP = hipe_llvm:mk_pointer(ByteTyPtr),
110          I2 =
111            hipe_llvm:mk_conversion(T1, bitcast, WordTyPtr, Name, BYTE_TYPE_PP),
112          GcRootArgs = [{BYTE_TYPE_PP, T1}, {ByteTyPtr, "@gc_metadata"}],
113          I3 = hipe_llvm:mk_call([], false, [], [], hipe_llvm:mk_void(),
114                                 "@llvm.gcroot", GcRootArgs, []),
115          I4 = case lists:member(D, Params) of
116                 false ->
117		   hipe_llvm:mk_store(WordTy, "-5", WordTyPtr, Name,
118				      [], [], false);
119                 true -> []
120               end,
121          do_alloca_stack(Ds, Params, Roots, [I1, I2, I3, I4 | Acc]);
122        false ->
123          do_alloca_stack(Ds, Params, Roots, [I1|Acc])
124      end;
125    false ->
126      case hipe_rtl:is_reg(D) andalso isPrecoloured(D) of
127        true -> %% Precoloured registers are mapped to "special" stack slots
128          do_alloca_stack(Ds, Params, Roots,  Acc);
129        false ->
130          I1 = case hipe_rtl:is_fpreg(D) of
131		 true ->
132		   FloatTy = hipe_llvm:mk_double(),
133		   hipe_llvm:mk_alloca(Name, FloatTy, [], []);
134		 false -> hipe_llvm:mk_alloca(Name, WordTy, [], [])
135	       end,
136	  do_alloca_stack(Ds, Params, Roots, [I1|Acc])
137      end
138  end.
139
140%%------------------------------------------------------------------------------
141%% @doc Translation of the linearized RTL Code. Each RTL instruction is
142%%      translated to a list of LLVM Assembly instructions. The relocation
143%%      dictionary is updated when needed.
144%%------------------------------------------------------------------------------
145translate_instr_list([], Acc, Relocs, Data) ->
146  {lists:reverse(lists:flatten(Acc)), Relocs, Data};
147translate_instr_list([I | Is], Acc, Relocs, Data) ->
148  {Acc1, NewRelocs, NewData} = translate_instr(I, Relocs, Data),
149  translate_instr_list(Is, [Acc1 | Acc], NewRelocs, NewData).
150
151translate_instr(I, Relocs, Data) ->
152  case I of
153    #alu{} ->
154      {I2, Relocs2} = trans_alu(I, Relocs),
155      {I2, Relocs2, Data};
156    #alub{} ->
157      {I2, Relocs2} = trans_alub(I, Relocs),
158      {I2, Relocs2, Data};
159    #call{} ->
160      {I2, Relocs2} =
161        case hipe_rtl:call_fun(I) of
162          %% In AMD64 this instruction does nothing!
163          %% TODO: chech use of fwait in other architectures!
164          fwait ->
165            {[], Relocs};
166          _ ->
167            trans_call(I, Relocs)
168        end,
169      {I2, Relocs2, Data};
170    #comment{} ->
171      {I2, Relocs2} = trans_comment(I, Relocs),
172      {I2, Relocs2, Data};
173    #enter{} ->
174      {I2, Relocs2} = trans_enter(I, Relocs),
175      {I2, Relocs2, Data};
176    #fconv{} ->
177      {I2, Relocs2} = trans_fconv(I, Relocs),
178      {I2, Relocs2, Data};
179    #fload{} ->
180      {I2, Relocs2} = trans_fload(I, Relocs),
181      {I2, Relocs2, Data};
182    #fmove{} ->
183      {I2, Relocs2} = trans_fmove(I, Relocs),
184      {I2, Relocs2, Data};
185    #fp{} ->
186      {I2, Relocs2} = trans_fp(I, Relocs),
187      {I2, Relocs2, Data};
188    #fp_unop{} ->
189      {I2, Relocs2} = trans_fp_unop(I, Relocs),
190      {I2, Relocs2, Data};
191    #fstore{} ->
192      {I2, Relocs2} = trans_fstore(I, Relocs),
193      {I2, Relocs2, Data};
194    #goto{} ->
195      {I2, Relocs2} = trans_goto(I, Relocs),
196      {I2, Relocs2, Data};
197    #label{} ->
198      {I2, Relocs2} = trans_label(I, Relocs),
199      {I2, Relocs2, Data};
200    #load{} ->
201      {I2, Relocs2} = trans_load(I, Relocs),
202      {I2, Relocs2, Data};
203    #load_address{} ->
204      {I2, Relocs2} = trans_load_address(I, Relocs),
205      {I2, Relocs2, Data};
206    #load_atom{} ->
207      {I2, Relocs2} = trans_load_atom(I, Relocs),
208      {I2, Relocs2, Data};
209    #move{} ->
210      {I2, Relocs2} = trans_move(I, Relocs),
211      {I2, Relocs2, Data};
212    #return{} ->
213      {I2, Relocs2} = trans_return(I, Relocs),
214      {I2, Relocs2, Data};
215    #store{} ->
216      {I2, Relocs2} = trans_store(I, Relocs),
217      {I2, Relocs2, Data};
218    #switch{} -> %% Only switch instruction updates Data
219      {I2, Relocs2, NewData} = trans_switch(I, Relocs, Data),
220      {I2, Relocs2, NewData};
221    Other ->
222      exit({?MODULE, translate_instr, {"Unknown RTL instruction", Other}})
223  end.
224
225%%
226%% alu
227%%
228trans_alu(I, Relocs) ->
229  RtlDst = hipe_rtl:alu_dst(I),
230  TmpDst = mk_temp(),
231  {Src1, I1} = trans_src(hipe_rtl:alu_src1(I)),
232  {Src2, I2} = trans_src(hipe_rtl:alu_src2(I)),
233  Op = trans_op(hipe_rtl:alu_op(I)),
234  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
235  I3 = hipe_llvm:mk_operation(TmpDst, Op, WordTy, Src1, Src2, []),
236  I4 = store_stack_dst(TmpDst, RtlDst),
237  {[I4, I3, I2, I1], Relocs}.
238
239%%
240%% alub
241%%
242trans_alub(I, Relocs) ->
243  case hipe_rtl:alub_cond(I) of
244    Op when Op =:= overflow orelse Op =:= not_overflow ->
245      trans_alub_overflow(I, signed, Relocs);
246    ltu -> %% ltu means unsigned overflow
247      trans_alub_overflow(I, unsigned, Relocs);
248    _ ->
249      trans_alub_no_overflow(I, Relocs)
250  end.
251
252trans_alub_overflow(I, Sign, Relocs) ->
253  {Src1, I1} = trans_src(hipe_rtl:alub_src1(I)),
254  {Src2, I2} = trans_src(hipe_rtl:alub_src2(I)),
255  TmpDst = mk_temp(),
256  Name = trans_alub_op(I, Sign),
257  NewRelocs = relocs_store(Name, {call, remote, {llvm, Name, 2}}, Relocs),
258  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
259  ReturnType = hipe_llvm:mk_struct([WordTy, hipe_llvm:mk_int(1)]),
260  T1 = mk_temp(),
261  I3 = hipe_llvm:mk_call(T1, false, [], [], ReturnType, "@" ++ Name,
262			                   [{WordTy, Src1}, {WordTy, Src2}], []),
263  %% T1{0}: result of the operation
264  I4 = hipe_llvm:mk_extractvalue(TmpDst, ReturnType, T1 , "0", []),
265  I5 = case hipe_rtl:alub_has_dst(I) of
266	 false -> [];
267	 true -> store_stack_dst(TmpDst, hipe_rtl:alub_dst(I))
268       end,
269  T2 = mk_temp(),
270  %% T1{1}: Boolean variable indicating overflow
271  I6 = hipe_llvm:mk_extractvalue(T2, ReturnType, T1, "1", []),
272  {TrueLabel, FalseLabel, MetaData} =
273    case hipe_rtl:alub_cond(I) of
274      Op when Op =:= overflow orelse Op =:= ltu ->
275	{mk_jump_label(hipe_rtl:alub_true_label(I)),
276	 mk_jump_label(hipe_rtl:alub_false_label(I)),
277	 branch_metadata(hipe_rtl:alub_pred(I))};
278      not_overflow ->
279	{mk_jump_label(hipe_rtl:alub_false_label(I)),
280	 mk_jump_label(hipe_rtl:alub_true_label(I)),
281	 branch_metadata(1 - hipe_rtl:alub_pred(I))}
282    end,
283  I7 = hipe_llvm:mk_br_cond(T2, TrueLabel, FalseLabel, MetaData),
284  {[I7, I6, I5, I4, I3, I2, I1], NewRelocs}.
285
286trans_alub_op(I, Sign) ->
287  Name =
288    case Sign of
289      signed ->
290        case hipe_rtl:alub_op(I) of
291          add -> "llvm.sadd.with.overflow.";
292          mul -> "llvm.smul.with.overflow.";
293          sub -> "llvm.ssub.with.overflow.";
294          Op  -> exit({?MODULE, trans_alub_op, {"Unknown alub operator", Op}})
295        end;
296      unsigned ->
297        case hipe_rtl:alub_op(I) of
298          add -> "llvm.uadd.with.overflow.";
299          mul -> "llvm.umul.with.overflow.";
300          sub -> "llvm.usub.with.overflow.";
301          Op  -> exit({?MODULE, trans_alub_op, {"Unknown alub operator", Op}})
302        end
303    end,
304  Type =
305    case hipe_rtl_arch:word_size() of
306      4 -> "i32";
307      8 -> "i64"
308      %% Other -> exit({?MODULE, trans_alub_op, {"Unknown type", Other}})
309    end,
310  Name ++ Type.
311
312trans_alub_no_overflow(I, Relocs) ->
313  {Src1, I1} = trans_src(hipe_rtl:alub_src1(I)),
314  {Src2, I2} = trans_src(hipe_rtl:alub_src2(I)),
315  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
316  %% alu
317  {CmpLhs, CmpRhs, I5, Cond} =
318    case {hipe_rtl:alub_has_dst(I), hipe_rtl:alub_op(I)} of
319      {false, 'sub'} ->
320	Cond0 = trans_branch_rel_op(hipe_rtl:alub_cond(I)),
321	{Src1, Src2, [], Cond0};
322      {HasDst, AlubOp} ->
323	TmpDst = mk_temp(),
324	Op = trans_op(AlubOp),
325	I3 = hipe_llvm:mk_operation(TmpDst, Op, WordTy, Src1, Src2, []),
326	I4 = case HasDst of
327	       false -> [];
328	       true -> store_stack_dst(TmpDst, hipe_rtl:alub_dst(I))
329	     end,
330	Cond0 = trans_alub_rel_op(hipe_rtl:alub_cond(I)),
331	{TmpDst, "0", [I4, I3], Cond0}
332    end,
333  %% icmp
334  T3 = mk_temp(),
335  I6 = hipe_llvm:mk_icmp(T3, Cond, WordTy, CmpLhs, CmpRhs),
336  %% br
337  Metadata = branch_metadata(hipe_rtl:alub_pred(I)),
338  True_label = mk_jump_label(hipe_rtl:alub_true_label(I)),
339  False_label = mk_jump_label(hipe_rtl:alub_false_label(I)),
340  I7 = hipe_llvm:mk_br_cond(T3, True_label, False_label, Metadata),
341  {[I7, I6, I5, I2, I1], Relocs}.
342
343branch_metadata(X) when X =:= 0.5 -> [];
344branch_metadata(X) when X > 0.5 -> ?BRANCH_META_TAKEN;
345branch_metadata(X) when X < 0.5 -> ?BRANCH_META_NOT_TAKEN.
346
347%%
348%% call
349%%
350trans_call(I, Relocs) ->
351  RtlCallArgList= hipe_rtl:call_arglist(I),
352  RtlCallName = hipe_rtl:call_fun(I),
353  {I0, Relocs1} = expose_closure(RtlCallName, RtlCallArgList, Relocs),
354  TmpDst = mk_temp(),
355  {CallArgs, I1} = trans_call_args(RtlCallArgList),
356  FixedRegs = fixed_registers(),
357  {LoadedFixedRegs, I2} = load_fixed_regs(FixedRegs),
358  FinalArgs = fix_reg_args(LoadedFixedRegs) ++ CallArgs,
359  {Name, I3, Relocs2} =
360    trans_call_name(RtlCallName, hipe_rtl:call_type(I), Relocs1, CallArgs, FinalArgs),
361  T1 = mk_temp(),
362  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
363  FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
364  I4 =
365    case hipe_rtl:call_fail(I) of
366      %% Normal Call
367      [] ->
368        hipe_llvm:mk_call(T1, false, "cc 11", [], FunRetTy, Name, FinalArgs,
369                          []);
370      %% Call With Exception
371      FailLabelNum ->
372        TrueLabel = "L" ++ integer_to_list(hipe_rtl:call_normal(I)),
373        FailLabel = "%FL" ++ integer_to_list(FailLabelNum),
374        II1 =
375          hipe_llvm:mk_invoke(T1, "cc 11", [], FunRetTy, Name, FinalArgs, [],
376                              "%" ++ TrueLabel, FailLabel),
377        II2 = hipe_llvm:mk_label(TrueLabel),
378        [II2, II1]
379    end,
380  I5 = store_fixed_regs(FixedRegs, T1),
381  I6 =
382    case hipe_rtl:call_dstlist(I) of
383      [] -> []; %% No return value
384      [Destination] ->
385        II3 =
386          hipe_llvm:mk_extractvalue(TmpDst, FunRetTy, T1,
387                                    integer_to_list(?NR_PINNED_REGS), []),
388        II4 = store_stack_dst(TmpDst, Destination),
389        [II4, II3]
390    end,
391  I7 =
392    case hipe_rtl:call_continuation(I) of
393      [] -> []; %% No continuation
394      CC ->
395        {II5, _} = trans_goto(hipe_rtl:mk_goto(CC), Relocs2),
396        II5
397    end,
398  {[I7, I6, I5, I4, I3, I2, I1, I0], Relocs2}.
399
400%% In case of call to a register (closure call) with more than ?NR_ARG_REGS
401%% arguments we must track the offset this call in the code, in order to
402%% to correct the stack descriptor. So, we insert a new Label and add this label
403%% to the "table_closures"
404%% --------------------------------|--------------------------------------------
405%%        Old Code                 |           New Code
406%% --------------------------------|--------------------------------------------
407%%                                 |           br %ClosureLabel
408%%        call %reg(Args)          |           ClosureLabel:
409%%                                 |           call %reg(Args)
410expose_closure(CallName, CallArgs, Relocs) ->
411  CallArgsNr = length(CallArgs),
412  case hipe_rtl:is_reg(CallName) andalso CallArgsNr > ?NR_ARG_REGS of
413    true ->
414      LabelNum = hipe_gensym:new_label(llvm),
415      ClosureLabel = hipe_llvm:mk_label(mk_label(LabelNum)),
416      JumpIns = hipe_llvm:mk_br(mk_jump_label(LabelNum)),
417      Relocs1 =
418        relocs_store({CallName, LabelNum},
419                     {closure_label, LabelNum, CallArgsNr - ?NR_ARG_REGS},
420                     Relocs),
421      {[ClosureLabel, JumpIns], Relocs1};
422    false ->
423      {[], Relocs}
424  end.
425
426trans_call_name(RtlCallName, RtlCallType, Relocs, CallArgs, FinalArgs) ->
427  case RtlCallName of
428    PrimOp when is_atom(PrimOp) ->
429      LlvmName = trans_prim_op(PrimOp),
430      Relocs1 =
431        relocs_store(LlvmName, {call, not_remote, {bif, PrimOp, length(CallArgs)}}, Relocs),
432      {"@" ++ LlvmName, [], Relocs1};
433    {M, F, A} when is_atom(M), is_atom(F), is_integer(A) ->
434      LlvmName = trans_mfa_name({M, F, A}, RtlCallType),
435      Relocs1 =
436        relocs_store(LlvmName, {call, RtlCallType, {M, F, length(CallArgs)}}, Relocs),
437      {"@" ++ LlvmName, [], Relocs1};
438    Reg ->
439      case hipe_rtl:is_reg(Reg) of
440        true ->
441	  %% In case of a closure call, the register holding the address
442	  %% of the closure must be converted to function type in
443	  %% order to make the call
444          TT1 = mk_temp(),
445          {RegName, II1} = trans_src(Reg),
446          WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
447          WordTyPtr = hipe_llvm:mk_pointer(WordTy),
448          II2 =
449            hipe_llvm:mk_conversion(TT1, inttoptr, WordTy, RegName, WordTyPtr),
450          TT2 = mk_temp(),
451          ArgsTypeList = lists:duplicate(length(FinalArgs), WordTy),
452          FunRetTy =
453            hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
454          FunType = hipe_llvm:mk_fun(FunRetTy, ArgsTypeList),
455          FunTypeP = hipe_llvm:mk_pointer(FunType),
456          II3 = hipe_llvm:mk_conversion(TT2, bitcast, WordTyPtr, TT1, FunTypeP),
457          {TT2, [II3, II2, II1], Relocs};
458        false ->
459          exit({?MODULE, trans_call, {"Unimplemented call to", RtlCallName}})
460      end
461  end.
462
463%%
464trans_call_args(ArgList) ->
465  {Args, I} = lists:unzip(trans_args(ArgList)),
466  %% Reverse arguments that are passed to stack to match with the Erlang
467  %% calling convention. (Propably not needed in prim calls.)
468  ReversedArgs =
469    case erlang:length(Args) > ?NR_ARG_REGS of
470      false ->
471	Args;
472      true ->
473	{ArgsInRegs, ArgsInStack} = lists:split(?NR_ARG_REGS, Args),
474	ArgsInRegs ++ lists:reverse(ArgsInStack)
475    end,
476  %% Reverse I, because some of the arguments may go out of scope and
477  %% should be killed(store -5). When two or more arguments are they
478  %% same, then order matters!
479  {ReversedArgs, lists:reverse(I)}.
480
481%%
482%% trans_comment
483%%
484trans_comment(I, Relocs) ->
485  I1 = hipe_llvm:mk_comment(hipe_rtl:comment_text(I)),
486  {I1, Relocs}.
487
488%%
489%% enter
490%%
491trans_enter(I, Relocs) ->
492  {CallArgs, I0} = trans_call_args(hipe_rtl:enter_arglist(I)),
493  FixedRegs = fixed_registers(),
494  {LoadedFixedRegs, I1} = load_fixed_regs(FixedRegs),
495  FinalArgs = fix_reg_args(LoadedFixedRegs) ++ CallArgs,
496  {Name, I2, NewRelocs} =
497    trans_call_name(hipe_rtl:enter_fun(I), hipe_rtl:enter_type(I), Relocs, CallArgs, FinalArgs),
498  T1 = mk_temp(),
499  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
500  FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
501  I3 = hipe_llvm:mk_call(T1, true, "cc 11", [], FunRetTy, Name, FinalArgs, []),
502  I4 = hipe_llvm:mk_ret([{FunRetTy, T1}]),
503  {[I4, I3, I2, I1, I0], NewRelocs}.
504
505%%
506%% fconv
507%%
508trans_fconv(I, Relocs) ->
509  %% XXX: Can a fconv destination be a precoloured reg?
510  RtlDst = hipe_rtl:fconv_dst(I),
511  TmpDst = mk_temp(),
512  {Src, I1} =  trans_float_src(hipe_rtl:fconv_src(I)),
513  FloatTy = hipe_llvm:mk_double(),
514  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
515  I2 = hipe_llvm:mk_conversion(TmpDst, sitofp, WordTy, Src, FloatTy),
516  I3 = store_float_stack(TmpDst, RtlDst),
517  {[I3, I2, I1], Relocs}.
518
519
520%% TODO: fload, fstore, fmove, and fp are almost the same with load, store, move
521%% and alu. Maybe we should join them.
522
523%%
524%% fload
525%%
526trans_fload(I, Relocs) ->
527  RtlDst = hipe_rtl:fload_dst(I),
528  RtlSrc = hipe_rtl:fload_src(I),
529  _Offset = hipe_rtl:fload_offset(I),
530  TmpDst = mk_temp(),
531  {Src, I1} = trans_float_src(RtlSrc),
532  {Offset, I2} = trans_float_src(_Offset),
533  T1 = mk_temp(),
534  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
535  FloatTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_double()),
536  I3 = hipe_llvm:mk_operation(T1, add, WordTy, Src, Offset, []),
537  T2 = mk_temp(),
538  I4 = hipe_llvm:mk_conversion(T2, inttoptr,  WordTy, T1, FloatTyPtr),
539  I5 = hipe_llvm:mk_load(TmpDst, FloatTyPtr, T2, [], [], false),
540  I6 = store_float_stack(TmpDst, RtlDst),
541  {[I6, I5, I4, I3, I2, I1], Relocs}.
542
543%%
544%% fmove
545%%
546trans_fmove(I, Relocs) ->
547  RtlDst = hipe_rtl:fmove_dst(I),
548  RtlSrc = hipe_rtl:fmove_src(I),
549  {Src, I1} = trans_float_src(RtlSrc),
550  I2 = store_float_stack(Src, RtlDst),
551  {[I2, I1], Relocs}.
552
553%%
554%% fp
555%%
556trans_fp(I, Relocs) ->
557  %% XXX: Just copied trans_alu...think again..
558  RtlDst = hipe_rtl:fp_dst(I),
559  RtlSrc1 = hipe_rtl:fp_src1(I),
560  RtlSrc2 = hipe_rtl:fp_src2(I),
561  %% Destination cannot be a precoloured register
562  FloatTy = hipe_llvm:mk_double(),
563  FloatTyPtr = hipe_llvm:mk_pointer(FloatTy),
564  TmpDst = mk_temp(),
565  {Src1, I1} = trans_float_src(RtlSrc1),
566  {Src2, I2} = trans_float_src(RtlSrc2),
567  Op = trans_fp_op(hipe_rtl:fp_op(I)),
568  I3 = hipe_llvm:mk_operation(TmpDst, Op, FloatTy, Src1, Src2, []),
569  I4 = store_float_stack(TmpDst, RtlDst),
570  %% Synchronization for floating point exceptions
571  I5 = hipe_llvm:mk_store(FloatTy, TmpDst, FloatTyPtr, "%exception_sync", [],
572                          [], true),
573  T1 = mk_temp(),
574  I6 = hipe_llvm:mk_load(T1, FloatTyPtr, "%exception_sync", [], [], true),
575  {[I6, I5, I4, I3, I2, I1], Relocs}.
576
577%%
578%% fp_unop
579%%
580trans_fp_unop(I, Relocs) ->
581  RtlDst = hipe_rtl:fp_unop_dst(I),
582  RtlSrc = hipe_rtl:fp_unop_src(I),
583  %% Destination cannot be a precoloured register
584  TmpDst = mk_temp(),
585  {Src, I1} = trans_float_src(RtlSrc),
586  Op =  trans_fp_op(hipe_rtl:fp_unop_op(I)),
587  FloatTy = hipe_llvm:mk_double(),
588  I2 = hipe_llvm:mk_operation(TmpDst, Op, FloatTy, "0.0", Src, []),
589  I3 = store_float_stack(TmpDst, RtlDst),
590  {[I3, I2, I1], Relocs}.
591%% TODO: Fix fp_unop in a way like the following. You must change trans_dest,
592%% in order to call float_to_list in a case of float constant. Maybe the type
593%% check is expensive...
594%% Dst = hipe_rtl:fp_unop_dst(I),
595%% Src = hipe_rtl:fp_unop_src(I),
596%% Op = hipe_rtl:fp_unop_op(I),
597%% Zero = hipe_rtl:mk_imm(0.0),
598%% I1 = hipe_rtl:mk_fp(Dst, Zero, Op, Src),
599%% trans_fp(I, Relocs1).
600
601%%
602%% fstore
603%%
604trans_fstore(I, Relocs) ->
605  Base = hipe_rtl:fstore_base(I),
606  case isPrecoloured(Base) of
607    true ->
608      trans_fstore_reg(I, Relocs);
609    false ->
610      exit({?MODULE, trans_fstore ,{"Not implemented yet", false}})
611  end.
612
613trans_fstore_reg(I, Relocs) ->
614  {Base, I0}  = trans_reg(hipe_rtl:fstore_base(I), dst),
615  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
616  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
617  FloatTy = hipe_llvm:mk_double(),
618  FloatTyPtr = hipe_llvm:mk_pointer(FloatTy),
619  T1 = mk_temp(),
620  I1 = hipe_llvm:mk_load(T1, WordTyPtr, Base, [],  [], false),
621  {Offset, I2} = trans_src(hipe_rtl:fstore_offset(I)),
622  T2 = mk_temp(),
623  I3 = hipe_llvm:mk_operation(T2, add, WordTy, T1, Offset, []),
624  T3 = mk_temp(),
625  I4 = hipe_llvm:mk_conversion(T3, inttoptr, WordTy, T2, FloatTyPtr),
626  {Value, I5} = trans_src(hipe_rtl:fstore_src(I)),
627  I6 = hipe_llvm:mk_store(FloatTy, Value, FloatTyPtr, T3, [], [], false),
628  {[I6, I5, I4, I3, I2, I1, I0], Relocs}.
629
630%%
631%% goto
632%%
633trans_goto(I, Relocs) ->
634  I1 = hipe_llvm:mk_br(mk_jump_label(hipe_rtl:goto_label(I))),
635  {I1, Relocs}.
636
637%%
638%% label
639%%
640trans_label(I, Relocs) ->
641  Label = mk_label(hipe_rtl:label_name(I)),
642  I1 = hipe_llvm:mk_label(Label),
643  {I1, Relocs}.
644
645%%
646%% load
647%%
648trans_load(I, Relocs) ->
649  RtlDst = hipe_rtl:load_dst(I),
650  TmpDst = mk_temp(),
651  %% XXX: Why translate them independently? ------------------------
652  {Src, I1} = trans_src(hipe_rtl:load_src(I)),
653  {Offset, I2} = trans_src(hipe_rtl:load_offset(I)),
654  T1 = mk_temp(),
655  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
656  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
657  I3 = hipe_llvm:mk_operation(T1, add, WordTy, Src, Offset, []),
658  %%----------------------------------------------------------------
659  I4 = case hipe_rtl:load_size(I) of
660         word ->
661           T2 = mk_temp(),
662           II1 = hipe_llvm:mk_conversion(T2, inttoptr, WordTy, T1, WordTyPtr),
663           II2 = hipe_llvm:mk_load(TmpDst, WordTyPtr, T2, [], [], false),
664           [II2, II1];
665         Size ->
666           LoadType = llvm_type_from_size(Size),
667           LoadTypeP = hipe_llvm:mk_pointer(LoadType),
668           T2 = mk_temp(),
669           II1 = hipe_llvm:mk_conversion(T2, inttoptr, WordTy, T1, LoadTypeP),
670           T3 = mk_temp(),
671           LoadTypePointer = hipe_llvm:mk_pointer(LoadType),
672           II2 = hipe_llvm:mk_load(T3, LoadTypePointer, T2, [], [], false),
673           Conversion =
674             case hipe_rtl:load_sign(I) of
675               signed -> sext;
676               unsigned -> zext
677             end,
678           II3 =
679             hipe_llvm:mk_conversion(TmpDst, Conversion, LoadType, T3, WordTy),
680           [II3, II2, II1]
681       end,
682  I5 = store_stack_dst(TmpDst, RtlDst),
683  {[I5, I4, I3, I2, I1], Relocs}.
684
685%%
686%% load_address
687%%
688trans_load_address(I, Relocs) ->
689  RtlDst = hipe_rtl:load_address_dst(I),
690  RtlAddr = hipe_rtl:load_address_addr(I),
691  {Addr, NewRelocs} =
692    case hipe_rtl:load_address_type(I) of
693      constant ->
694        {"%DL" ++ integer_to_list(RtlAddr) ++ "_var", Relocs};
695      closure  ->
696        {{_, ClosureName, _}, _, _} = RtlAddr,
697        FixedClosureName = fix_closure_name(ClosureName),
698        Relocs1 = relocs_store(FixedClosureName, {closure, RtlAddr}, Relocs),
699        {"%" ++ FixedClosureName ++ "_var", Relocs1};
700      type ->
701        exit({?MODULE, trans_load_address,
702             {"Type not implemented in load_address", RtlAddr}})
703    end,
704  I1 = store_stack_dst(Addr, RtlDst),
705  {[I1], NewRelocs}.
706
707%%
708%% load_atom
709%%
710trans_load_atom(I, Relocs) ->
711  RtlDst = hipe_rtl:load_atom_dst(I),
712  RtlAtom = hipe_rtl:load_atom_atom(I),
713  AtomName = "atom_" ++ make_llvm_id(atom_to_list(RtlAtom)),
714  AtomVar = "%" ++ AtomName ++ "_var",
715  NewRelocs = relocs_store(AtomName, {atom, RtlAtom}, Relocs),
716  I1 = store_stack_dst(AtomVar, RtlDst),
717  {[I1], NewRelocs}.
718
719%%
720%% move
721%%
722trans_move(I, Relocs) ->
723  RtlDst = hipe_rtl:move_dst(I),
724  RtlSrc = hipe_rtl:move_src(I),
725  {Src, I1} = trans_src(RtlSrc),
726  I2 = store_stack_dst(Src, RtlDst),
727  {[I2, I1], Relocs}.
728
729%%
730%% return
731%%
732trans_return(I, Relocs) ->
733  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
734  {VarRet, I1} =
735    case hipe_rtl:return_varlist(I) of
736      [] ->
737	{[], []};
738      [A] ->
739	{Name, II1} = trans_src(A),
740	{[{WordTy, Name}], II1}
741    end,
742  FixedRegs = fixed_registers(),
743  {LoadedFixedRegs, I2} = load_fixed_regs(FixedRegs),
744  FixedRet = [{WordTy, X} || X <- LoadedFixedRegs],
745  Ret = FixedRet ++ VarRet,
746  {RetTypes, _RetNames} = lists:unzip(Ret),
747  Type = hipe_llvm:mk_struct(RetTypes),
748  {RetStruct, I3} = mk_return_struct(Ret, Type),
749  I4 = hipe_llvm:mk_ret([{Type, RetStruct}]),
750  {[I4, I3, I2, I1], Relocs}.
751
752%% @doc Create a structure to hold the return value and the precoloured
753%%      registers.
754mk_return_struct(RetValues, Type) ->
755  mk_return_struct(RetValues, Type, [], "undef", 0).
756
757mk_return_struct([], _, Acc, StructName, _) ->
758  {StructName, Acc};
759mk_return_struct([{ElemType, ElemName}|Rest], Type, Acc, StructName, Index) ->
760  T1 = mk_temp(),
761  I1 = hipe_llvm:mk_insertvalue(T1, Type, StructName, ElemType, ElemName,
762                                integer_to_list(Index), []),
763  mk_return_struct(Rest, Type, [I1 | Acc], T1, Index+1).
764
765%%
766%% store
767%%
768trans_store(I, Relocs) ->
769  {Base, I1} = trans_src(hipe_rtl:store_base(I)),
770  {Offset, I2} = trans_src(hipe_rtl:store_offset(I)),
771  {Value, I3} = trans_src(hipe_rtl:store_src(I)),
772  T1 = mk_temp(),
773  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
774  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
775  I4 = hipe_llvm:mk_operation(T1, add, WordTy, Base, Offset, []),
776  I5 =
777    case hipe_rtl:store_size(I) of
778      word ->
779	T2 = mk_temp(),
780	II1 = hipe_llvm:mk_conversion(T2, inttoptr, WordTy, T1, WordTyPtr),
781	II2 = hipe_llvm:mk_store(WordTy, Value, WordTyPtr, T2, [], [],
782				 false),
783	[II2, II1];
784      Size ->
785	%% XXX: Is always trunc correct ?
786	LoadType = llvm_type_from_size(Size),
787	LoadTypePointer = hipe_llvm:mk_pointer(LoadType),
788	T2 = mk_temp(),
789	II1 = hipe_llvm:mk_conversion(T2, inttoptr, WordTy, T1, LoadTypePointer),
790	T3 = mk_temp(),
791	II2 = hipe_llvm:mk_conversion(T3, 'trunc', WordTy, Value, LoadType),
792	II3 = hipe_llvm:mk_store(LoadType, T3, LoadTypePointer, T2, [], [], false),
793	[II3, II2, II1]
794    end,
795  {[I5, I4, I3, I2, I1], Relocs}.
796
797%%
798%% switch
799%%
800trans_switch(I, Relocs, Data) ->
801  RtlSrc = hipe_rtl:switch_src(I),
802  {Src, I1} = trans_src(RtlSrc),
803  Labels = hipe_rtl:switch_labels(I),
804  JumpLabels = [mk_jump_label(L) || L <- Labels],
805  SortOrder = hipe_rtl:switch_sort_order(I),
806  NrLabels = length(Labels),
807  ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
808  TableType = hipe_llvm:mk_array(NrLabels, ByteTyPtr),
809  TableTypeP = hipe_llvm:mk_pointer(TableType),
810  TypedJumpLabels = [{hipe_llvm:mk_label_type(), X} || X <- JumpLabels],
811  T1 = mk_temp(),
812  {Src2, []} = trans_dst(RtlSrc),
813  TableName = "table_" ++ tl(Src2),
814  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
815  I2 = hipe_llvm:mk_getelementptr(T1, TableTypeP, "@"++TableName,
816                                  [{WordTy, "0"}, {WordTy, Src}], false),
817  T2 = mk_temp(),
818  BYTE_TYPE_PP = hipe_llvm:mk_pointer(ByteTyPtr),
819  I3 = hipe_llvm:mk_load(T2, BYTE_TYPE_PP, T1, [], [], false),
820  I4 = hipe_llvm:mk_indirectbr(ByteTyPtr, T2, TypedJumpLabels),
821  LMap = [{label, L} || L <- Labels],
822  %% Update data with the info for the jump table
823  {NewData, JTabLab} =
824    case hipe_rtl:switch_sort_order(I) of
825      [] ->
826        hipe_consttab:insert_block(Data, word, LMap);
827      SortOrder ->
828        hipe_consttab:insert_sorted_block(Data, word, LMap, SortOrder)
829    end,
830  Relocs2 = relocs_store(TableName, {switch, {TableType, Labels, NrLabels,
831					               SortOrder}, JTabLab}, Relocs),
832  {[I4, I3, I2, I1], Relocs2, NewData}.
833
834%% @doc Pass on RTL code in order to fix invoke and closure calls.
835fix_code(Code) ->
836  fix_calls(Code).
837
838%% @doc Fix invoke calls and closure calls with more than ?NR_ARG_REGS
839%%      arguments.
840fix_calls(Code) ->
841  fix_calls(Code, [], []).
842
843fix_calls([], Acc, FailLabels) ->
844  {lists:reverse(Acc), FailLabels};
845fix_calls([I | Is], Acc, FailLabels) ->
846  case hipe_rtl:is_call(I) of
847    true ->
848      {NewCall, NewFailLabels} =
849        case hipe_rtl:call_fail(I) of
850          [] ->
851            {I, FailLabels};
852          FailLabel ->
853            fix_invoke_call(I, FailLabel, FailLabels)
854        end,
855      fix_calls(Is, [NewCall|Acc], NewFailLabels);
856    false ->
857      fix_calls(Is, [I|Acc], FailLabels)
858  end.
859
860%% @doc When a call has a fail continuation label it must be extended with a
861%%      normal continuation label to go with the LLVM's invoke instruction.
862%%      FailLabels is the list of labels of all fail blocks, which are needed to
863%%      be declared as landing pads. Furtermore, we must add to fail labels a
864%%      call to hipe_bifs:llvm_fix_pinned_regs/0 in order to avoid reloading old
865%%      values of pinned registers. This may happen because the result of an
866%%      invoke instruction is not available at fail-labels, and, thus, we cannot
867%%      get the correct values of pinned registers. Finally, the stack needs to
868%%      be re-adjusted when there are stack arguments.
869fix_invoke_call(I, FailLabel, FailLabels) ->
870  NewLabel = hipe_gensym:new_label(llvm),
871  NewCall1 = hipe_rtl:call_normal_update(I, NewLabel),
872  SpAdj = find_sp_adj(hipe_rtl:call_arglist(I)),
873  case lists:keyfind(FailLabel, 1, FailLabels) of
874    %% Same fail label with same Stack Pointer adjustment
875    {FailLabel, NewFailLabel, SpAdj} ->
876      NewCall2 = hipe_rtl:call_fail_update(NewCall1, NewFailLabel),
877      {NewCall2, FailLabels};
878    %% Same fail label but with different Stack Pointer adjustment
879    {_, _, _} ->
880      NewFailLabel = hipe_gensym:new_label(llvm),
881      NewCall2 = hipe_rtl:call_fail_update(NewCall1, NewFailLabel),
882      {NewCall2, [{FailLabel, NewFailLabel, SpAdj} | FailLabels]};
883    %% New Fail label
884    false ->
885      NewFailLabel = hipe_gensym:new_label(llvm),
886      NewCall2 = hipe_rtl:call_fail_update(NewCall1, NewFailLabel),
887      {NewCall2, [{FailLabel, NewFailLabel, SpAdj} | FailLabels]}
888  end.
889
890find_sp_adj(ArgList) ->
891  NrArgs = length(ArgList),
892  case NrArgs > ?NR_ARG_REGS of
893    true ->
894      (NrArgs - ?NR_ARG_REGS) * hipe_rtl_arch:word_size();
895    false ->
896      0
897  end.
898
899%% @doc Add landingpad instruction in Fail Blocks.
900add_landingpads(LLVM_Code, FailLabels) ->
901  FailLabels2 = [convert_label(T) || T <- FailLabels],
902  add_landingpads(LLVM_Code, FailLabels2, []).
903
904add_landingpads([], _, Acc) ->
905  lists:reverse(Acc);
906add_landingpads([I | Is], FailLabels, Acc) ->
907  case hipe_llvm:is_label(I) of
908    true ->
909      Label = hipe_llvm:label_label(I),
910      Ins = create_fail_blocks(Label, FailLabels),
911      add_landingpads(Is, FailLabels, [I | Ins] ++ Acc);
912    false ->
913      add_landingpads(Is, FailLabels, [I | Acc])
914  end.
915
916convert_label({X,Y,Z}) ->
917  {"L" ++ integer_to_list(X), "FL" ++ integer_to_list(Y), Z}.
918
919%% @doc Create a fail block wich.
920create_fail_blocks(_, []) -> [];
921create_fail_blocks(Label, FailLabels) ->
922  create_fail_blocks(Label, FailLabels, []).
923
924create_fail_blocks(Label, FailLabels, Acc) ->
925  case lists:keytake(Label, 1, FailLabels) of
926    false ->
927      Acc;
928    {value, {Label, FailLabel, SpAdj}, RestFailLabels} ->
929      WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
930      I1 = hipe_llvm:mk_label(FailLabel),
931      LP = hipe_llvm:mk_landingpad(),
932      I2 =
933        case SpAdj > 0 of
934          true ->
935            StackPointer = ?ARCH_REGISTERS:reg_name(?ARCH_REGISTERS:sp()),
936            hipe_llvm:mk_adj_stack(integer_to_list(SpAdj), StackPointer,
937                                   WordTy);
938          false -> []
939        end,
940      T1 = mk_temp(),
941      FixedRegs = fixed_registers(),
942      FunRetTy =
943        hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
944      I3 = hipe_llvm:mk_call(T1, false, "cc 11", [], FunRetTy,
945			                       "@hipe_bifs.llvm_fix_pinned_regs.0", [], []),
946      I4 = store_fixed_regs(FixedRegs, T1),
947      I5 = hipe_llvm:mk_br("%" ++ Label),
948      Ins = lists:flatten([I5, I4, I3, I2, LP,I1]),
949      create_fail_blocks(Label, RestFailLabels, Ins ++ Acc)
950  end.
951
952%%------------------------------------------------------------------------------
953%% Miscellaneous Functions
954%%------------------------------------------------------------------------------
955
956%% @doc Convert RTL argument list to LLVM argument list.
957trans_args(ArgList) ->
958  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
959  MakeArg =
960    fun(A) ->
961      {Name, I1} = trans_src(A),
962      {{WordTy, Name}, I1}
963    end,
964  [MakeArg(A) || A <- ArgList].
965
966%% @doc Convert a list of Precoloured registers to LLVM argument list.
967fix_reg_args(ArgList) ->
968  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
969  [{WordTy, A} || A <- ArgList].
970
971%% @doc Load Precoloured registers.
972load_fixed_regs(RegList) ->
973  Names = [mk_temp_reg(R) || R <- RegList],
974  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
975  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
976  Fun1 =
977    fun (X, Y) ->
978      hipe_llvm:mk_load(X, WordTyPtr, "%" ++ Y ++ "_reg_var", [], [], false)
979    end,
980  Ins = lists:zipwith(Fun1, Names, RegList),
981  {Names, Ins}.
982
983%% @doc  Store Precoloured registers.
984store_fixed_regs(RegList, Name) ->
985  Names = [mk_temp_reg(R) || R <- RegList],
986  Indexes = lists:seq(0, erlang:length(RegList) - 1),
987  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
988  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
989  FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
990  Fun1 =
991    fun(X,Y) ->
992      hipe_llvm:mk_extractvalue(X, FunRetTy, Name, integer_to_list(Y), [])
993    end,
994  I1 = lists:zipwith(Fun1, Names, Indexes),
995  Fun2 =
996    fun (X, Y) ->
997      hipe_llvm:mk_store(WordTy, X, WordTyPtr, "%" ++ Y ++ "_reg_var", [], [],
998                         false)
999    end,
1000  I2 = lists:zipwith(Fun2, Names, RegList),
1001  [I2, I1].
1002
1003%%------------------------------------------------------------------------------
1004%% Translation of Names
1005%%------------------------------------------------------------------------------
1006
1007%% @doc Fix F in MFA tuple to acceptable LLVM identifier (case of closure).
1008-spec fix_mfa_name(mfa()) -> mfa().
1009fix_mfa_name({Mod_Name, Closure_Name, Arity}) ->
1010  Fun_Name = list_to_atom(fix_closure_name(Closure_Name)),
1011  {Mod_Name, Fun_Name, Arity}.
1012
1013%% @doc Make an acceptable LLVM identifier for a closure name.
1014fix_closure_name(ClosureName) ->
1015  make_llvm_id(atom_to_list(ClosureName)).
1016
1017%% @doc Create an acceptable LLVM identifier.
1018make_llvm_id(Name) ->
1019  case Name of
1020    "" -> "Empty";
1021    Other -> lists:flatten([llvm_id(C) || C <- Other])
1022  end.
1023
1024llvm_id(C) when C=:=46; C>47 andalso C<58; C>64 andalso C<91; C=:=95;
1025                C>96 andalso C<123 ->
1026  C;
1027llvm_id(C) ->
1028 io_lib:format("_~2.16.0B_",[C]).
1029
1030%% @doc Create an acceptable LLVM identifier for an MFA.
1031trans_mfa_name({M,F,A}, Linkage) ->
1032  N0 = atom_to_list(M) ++ "." ++ atom_to_list(F) ++ "." ++ integer_to_list(A),
1033  N = case Linkage of
1034	not_remote -> N0;
1035	remote -> "rem." ++ N0
1036      end,
1037  make_llvm_id(N).
1038
1039%%------------------------------------------------------------------------------
1040%% Creation of Labels and Temporaries
1041%%------------------------------------------------------------------------------
1042mk_label(N) ->
1043  "L" ++ integer_to_list(N).
1044
1045mk_jump_label(N) ->
1046  "%L" ++ integer_to_list(N).
1047
1048mk_temp() ->
1049  "%t" ++ integer_to_list(hipe_gensym:new_var(llvm)).
1050
1051mk_temp_reg(Name) ->
1052  "%" ++ Name ++ integer_to_list(hipe_gensym:new_var(llvm)).
1053
1054%%----------------------------------------------------------------------------
1055%% Translation of Operands
1056%%----------------------------------------------------------------------------
1057
1058store_stack_dst(TempDst, Dst) ->
1059  {Dst2, II1} = trans_dst(Dst),
1060  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1061  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
1062  II2 = hipe_llvm:mk_store(WordTy, TempDst, WordTyPtr, Dst2, [], [], false),
1063  [II2, II1].
1064
1065store_float_stack(TempDst, Dst) ->
1066  {Dst2, II1} = trans_dst(Dst),
1067  FloatTy = hipe_llvm:mk_double(),
1068  FloatTyPtr = hipe_llvm:mk_pointer(FloatTy),
1069  II2 = hipe_llvm:mk_store(FloatTy, TempDst, FloatTyPtr, Dst2, [], [], false),
1070  [II2, II1].
1071
1072trans_float_src(Src) ->
1073  case hipe_rtl:is_const_label(Src) of
1074    true ->
1075      Name = "@DL" ++ integer_to_list(hipe_rtl:const_label_label(Src)),
1076      T1 = mk_temp(),
1077      %% XXX: Hardcoded offset
1078      ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
1079      ByteTyPtr = hipe_llvm:mk_pointer(ByteTy),
1080      I1 = hipe_llvm:mk_getelementptr(T1, ByteTyPtr, Name,
1081           [{ByteTy, integer_to_list(?FLOAT_OFFSET)}], true),
1082      T2 = mk_temp(),
1083      FloatTy = hipe_llvm:mk_double(),
1084      FloatTyPtr = hipe_llvm:mk_pointer(FloatTy),
1085      I2 = hipe_llvm:mk_conversion(T2, bitcast, ByteTyPtr, T1, FloatTyPtr),
1086      T3 = mk_temp(),
1087      I3 = hipe_llvm:mk_load(T3, FloatTyPtr, T2, [], [], false),
1088      {T3, [I3, I2, I1]};
1089    false ->
1090      trans_src(Src)
1091  end.
1092
1093trans_src(A) ->
1094  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1095  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
1096  case hipe_rtl:is_imm(A) of
1097    true ->
1098      Value = integer_to_list(hipe_rtl:imm_value(A)),
1099      {Value, []};
1100    false ->
1101      case hipe_rtl:is_reg(A) of
1102        true ->
1103          case isPrecoloured(A) of
1104            true -> trans_reg(A, src);
1105            false ->
1106              {Name, []} = trans_reg(A, src),
1107              T1 = mk_temp(),
1108              I1 = hipe_llvm:mk_load(T1, WordTyPtr, Name, [], [], false),
1109              {T1, [I1]}
1110          end;
1111        false ->
1112          case hipe_rtl:is_var(A) of
1113            true ->
1114              RootName = "%vr" ++ integer_to_list(hipe_rtl:var_index(A)),
1115              T1 = mk_temp(),
1116              I1 = hipe_llvm:mk_load(T1, WordTyPtr, RootName, [], [], false),
1117              I2 =
1118		case hipe_rtl:var_liveness(A) of
1119		  live ->
1120		    [];
1121		  dead ->
1122		    NilValue = hipe_tagscheme:mk_nil(),
1123		    hipe_llvm:mk_store(WordTy, integer_to_list(NilValue), WordTyPtr, RootName,
1124		                       [], [], false)
1125		end,
1126              {T1, [I2, I1]};
1127            false ->
1128              case hipe_rtl:is_fpreg(A) of
1129                true ->
1130                  {Name, []} = trans_dst(A),
1131                  T1 = mk_temp(),
1132                  FloatTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_double()),
1133                  I1 = hipe_llvm:mk_load(T1, FloatTyPtr, Name, [], [], false),
1134                  {T1, [I1]};
1135                false -> trans_dst(A)
1136              end
1137          end
1138      end
1139  end.
1140
1141trans_dst(A) ->
1142  case hipe_rtl:is_reg(A) of
1143    true ->
1144      trans_reg(A, dst);
1145    false ->
1146      Name = case hipe_rtl:is_var(A) of
1147	       true ->
1148		 "%vr" ++ integer_to_list(hipe_rtl:var_index(A));
1149	       false ->
1150		 case hipe_rtl:is_fpreg(A) of
1151		   true -> "%fr" ++ integer_to_list(hipe_rtl:fpreg_index(A));
1152		   false ->
1153		     case hipe_rtl:is_const_label(A) of
1154		       true ->
1155			 "%DL" ++ integer_to_list(hipe_rtl:const_label_label(A)) ++ "_var";
1156		       false ->
1157			 error(badarg, [A])
1158		     end
1159		 end
1160	     end,
1161      {Name, []}
1162  end.
1163
1164%% @doc Translate a register. If it is precoloured it must be mapped to the
1165%%      correct stack slot that holds the precoloured register value.
1166trans_reg(Arg, Position) ->
1167  Index = hipe_rtl:reg_index(Arg),
1168  case isPrecoloured(Arg) of
1169    true ->
1170      Name = map_precoloured_reg(Index),
1171      case Position of
1172        src -> fix_reg_src(Name);
1173        dst -> fix_reg_dst(Name)
1174      end;
1175    false ->
1176      {hipe_rtl_arch:reg_name(Index), []}
1177  end.
1178
1179map_precoloured_reg(Index) ->
1180  case hipe_rtl_arch:reg_name(Index) of
1181    "%r15" -> "%hp_reg_var";
1182    "%rbp" -> "%p_reg_var";
1183    "%esi" -> "%hp_reg_var";
1184    "%ebp" -> "%p_reg_var";
1185    "%fcalls" ->
1186      {"%p_reg_var", ?ARCH_REGISTERS:proc_offset(?ARCH_REGISTERS:fcalls())};
1187    "%hplim" ->
1188      {"%p_reg_var", ?ARCH_REGISTERS:proc_offset(?ARCH_REGISTERS:heap_limit())};
1189    _ ->
1190      exit({?MODULE, map_precoloured_reg, {"Register not mapped yet", Index}})
1191  end.
1192
1193%% @doc Load precoloured dst register.
1194fix_reg_dst(Register) ->
1195  case Register of
1196    {Name, Offset} -> %% Case of %fcalls, %hplim
1197      WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1198      pointer_from_reg(Name, WordTy, Offset);
1199    Name -> %% Case of %p and %hp
1200      {Name, []}
1201  end.
1202
1203%% @doc Load precoloured src register.
1204fix_reg_src(Register) ->
1205  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1206  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
1207  case Register of
1208    {Name, Offset} -> %% Case of %fcalls, %hplim
1209      {T1, I1} = pointer_from_reg(Name, WordTy, Offset),
1210      T2 = mk_temp(),
1211      I2 = hipe_llvm:mk_load(T2, WordTyPtr, T1, [], [] , false),
1212      {T2, [I2, I1]};
1213    Name -> %% Case of %p and %hp
1214      T1 = mk_temp(),
1215      {T1, hipe_llvm:mk_load(T1, WordTyPtr, Name, [], [], false)}
1216  end.
1217
1218%% @doc Load %fcalls and %hplim.
1219pointer_from_reg(RegName, Type, Offset) ->
1220  PointerType = hipe_llvm:mk_pointer(Type),
1221  T1 = mk_temp(),
1222  I1 = hipe_llvm:mk_load(T1, PointerType, RegName, [], [] ,false),
1223  T2 = mk_temp(),
1224  I2 = hipe_llvm:mk_conversion(T2, inttoptr, Type, T1, PointerType),
1225  T3 = mk_temp(),
1226  %% XXX: Offsets should be a power of 2.
1227  I3 = hipe_llvm:mk_getelementptr(T3, PointerType, T2,
1228    [{Type, integer_to_list(Offset div hipe_rtl_arch:word_size())}], true),
1229  {T3, [I3, I2, I1]}.
1230
1231isPrecoloured(X) ->
1232  hipe_rtl_arch:is_precoloured(X).
1233
1234%%------------------------------------------------------------------------------
1235%% Translation of operators
1236%%------------------------------------------------------------------------------
1237
1238trans_op(Op) ->
1239  case Op of
1240    add -> add;
1241    sub -> sub;
1242    'or' -> 'or';
1243    'and' -> 'and';
1244    'xor' -> 'xor';
1245    sll -> shl;
1246    srl -> lshr;
1247    sra -> ashr;
1248    mul -> mul;
1249    'fdiv' -> fdiv;
1250    'sdiv' -> sdiv;
1251    'srem' -> srem;
1252    Other -> exit({?MODULE, trans_op, {"Unknown RTL operator", Other}})
1253  end.
1254
1255trans_branch_rel_op(Op) ->
1256  case Op of
1257    gtu -> ugt;
1258    geu -> uge;
1259    ltu -> ult;
1260    leu -> ule;
1261    _ -> trans_alub_rel_op(Op)
1262  end.
1263
1264trans_alub_rel_op(Op) ->
1265  case Op of
1266    eq -> eq;
1267    ne -> ne;
1268    gt -> sgt;
1269    ge -> sge;
1270    lt -> slt;
1271    le -> sle
1272  end.
1273
1274trans_prim_op(Op) ->
1275  case Op of
1276    '+' -> "bif_add";
1277    '-' -> "bif_sub";
1278    '*' -> "bif_mul";
1279    'div' -> "bif_div";
1280    '/' -> "bif_div";
1281    Other -> atom_to_list(Other)
1282  end.
1283
1284trans_fp_op(Op) ->
1285  case Op of
1286    fadd -> fadd;
1287    fsub -> fsub;
1288    fdiv -> fdiv;
1289    fmul -> fmul;
1290    fchs -> fsub;
1291    Other -> exit({?MODULE, trans_fp_op, {"Unknown RTL float operator",Other}})
1292  end.
1293
1294%% Misc.
1295insn_dst(I) ->
1296  case I of
1297    #alu{} ->
1298      [hipe_rtl:alu_dst(I)];
1299    #alub{} ->
1300      case hipe_rtl:alub_has_dst(I) of
1301	true -> [hipe_rtl:alub_dst(I)];
1302	false -> []
1303      end;
1304    #call{} ->
1305      case hipe_rtl:call_dstlist(I) of
1306        [] -> [];
1307        [Dst] -> [Dst]
1308      end;
1309    #load{} ->
1310      [hipe_rtl:load_dst(I)];
1311    #load_address{} ->
1312      [hipe_rtl:load_address_dst(I)];
1313    #load_atom{} ->
1314      [hipe_rtl:load_atom_dst(I)];
1315    #move{} ->
1316      [hipe_rtl:move_dst(I)];
1317    #phi{} ->
1318      [hipe_rtl:phi_dst(I)];
1319    #fconv{} ->
1320      [hipe_rtl:fconv_dst(I)];
1321    #fload{} ->
1322      [hipe_rtl:fload_dst(I)];
1323    #fmove{} ->
1324      [hipe_rtl:fmove_dst(I)];
1325    #fp{} ->
1326      [hipe_rtl:fp_dst(I)];
1327    #fp_unop{} ->
1328      [hipe_rtl:fp_unop_dst(I)];
1329    _ ->
1330      []
1331  end.
1332
1333llvm_type_from_size(Size) ->
1334  case Size of
1335    byte  -> hipe_llvm:mk_int(?BITS_IN_BYTE);
1336    int16 -> hipe_llvm:mk_int(16);
1337    int32 -> hipe_llvm:mk_int(32);
1338    word  -> hipe_llvm:mk_int(?BITS_IN_WORD)
1339  end.
1340
1341%% @doc Create definition for the compiled function. The parameters that are
1342%%      passed to the stack must be reversed to match with the CC. Also
1343%%      precoloured registers that are passed as arguments must be stored to
1344%%      the corresonding stack slots.
1345create_function_definition(Fun, Params, Code, LocalVars) ->
1346  FunctionName = trans_mfa_name(Fun, not_remote),
1347  FixedRegs = fixed_registers(),
1348  %% Reverse parameters to match with the Erlang calling convention
1349  ReversedParams =
1350    case erlang:length(Params) > ?NR_ARG_REGS of
1351		  false ->
1352		    Params;
1353		  true ->
1354		    {ParamsInRegs, ParamsInStack} = lists:split(?NR_ARG_REGS, Params),
1355		    ParamsInRegs ++ lists:reverse(ParamsInStack)
1356		end,
1357  Args = header_regs(FixedRegs) ++ header_params(ReversedParams),
1358  EntryLabel = hipe_llvm:mk_label("Entry"),
1359  FloatTy = hipe_llvm:mk_double(),
1360  ExceptionSync = hipe_llvm:mk_alloca("%exception_sync", FloatTy, [], []),
1361  I2 = load_regs(FixedRegs),
1362  I3 = hipe_llvm:mk_br(mk_jump_label(get(first_label))),
1363  StoredParams = store_params(Params),
1364  EntryBlock =
1365    lists:flatten([EntryLabel, ExceptionSync, I2, LocalVars, StoredParams, I3]),
1366  Final_Code = EntryBlock ++ Code,
1367  FunctionOptions = [nounwind, noredzone, 'gc "erlang"'],
1368  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1369  FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
1370  hipe_llvm:mk_fun_def([], [], "cc 11", [], FunRetTy, FunctionName, Args,
1371                       FunctionOptions, [], Final_Code).
1372
1373header_params(Params) ->
1374  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1375  [{WordTy, "%v" ++ integer_to_list(hipe_rtl:var_index(P))} || P <- Params].
1376
1377store_params(Params) ->
1378  Fun1 =
1379    fun(X) ->
1380      Index = hipe_rtl:var_index(X),
1381      {Name, _} = trans_dst(X),
1382      ParamName = "%v" ++ integer_to_list(Index),
1383      WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1384      WordTyPtr = hipe_llvm:mk_pointer(WordTy),
1385      hipe_llvm:mk_store(WordTy, ParamName, WordTyPtr, Name, [], [], false)
1386    end,
1387  lists:map(Fun1, Params).
1388
1389fixed_registers() ->
1390  case get(hipe_target_arch) of
1391    x86 ->
1392      ["hp", "p"];
1393    amd64 ->
1394      ["hp", "p"];
1395    Other ->
1396      exit({?MODULE, map_registers, {"Unknown architecture", Other}})
1397  end.
1398
1399header_regs(Registers) ->
1400  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1401  [{WordTy, "%" ++ X ++ "_in"} || X <- Registers].
1402
1403load_regs(Registers) ->
1404  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1405  WordTyPtr = hipe_llvm:mk_pointer(WordTy),
1406  Fun1 =
1407    fun(X) ->
1408	I1 = hipe_llvm:mk_alloca("%" ++ X ++ "_reg_var", WordTy, [], []),
1409	I2 = hipe_llvm:mk_store(WordTy, "%" ++ X ++ "_in", WordTyPtr,
1410			 "%" ++ X ++ "_reg_var", [], [], false),
1411	[I1, I2]
1412    end,
1413  lists:map(Fun1, Registers).
1414
1415%%------------------------------------------------------------------------------
1416%% Relocation-specific Stuff
1417%%------------------------------------------------------------------------------
1418
1419relocs_store(Key, Value, Relocs) ->
1420  dict:store(Key, Value, Relocs).
1421
1422relocs_to_list(Relocs) ->
1423  dict:to_list(Relocs).
1424
1425%% @doc This function is responsible for the actions needed to handle
1426%%      relocations:
1427%%      1) Updates relocations with constants and switch jump tables.
1428%%      2) Creates LLVM code to declare relocations as external
1429%%         functions/constants.
1430%%      3) Creates LLVM code in order to create local variables for the external
1431%%         constants/labels.
1432handle_relocations(Relocs, Data, Fun) ->
1433  RelocsList = relocs_to_list(Relocs),
1434  %% Separate Relocations according to their type
1435  {CallList, AtomList, ClosureList, ClosureLabels, SwitchList} =
1436    seperate_relocs(RelocsList),
1437  %% Create code to declare atoms
1438  AtomDecl = [declare_atom(A) || A <- AtomList],
1439  %% Create code to create local name for atoms
1440  AtomLoad = [load_atom(A) || A <- AtomList],
1441  %% Create code to declare closures
1442  ClosureDecl = [declare_closure(C) || C <- ClosureList],
1443  %% Create code to create local name for closures
1444  ClosureLoad = [load_closure(C) || C <- ClosureList],
1445  %% Find function calls
1446  IsExternalCall = fun (X) -> is_external_call(X, Fun) end,
1447  ExternalCallList = lists:filter(IsExternalCall, CallList),
1448  %% Create code to declare external function
1449  FunDecl = fixed_fun_decl() ++ [call_to_decl(C) || C <- ExternalCallList],
1450  %% Extract constant labels from Constant Map (remove duplicates)
1451  ConstLabels = hipe_consttab:labels(Data),
1452  %% Create code to declare constants
1453  ConstDecl = [declare_constant(C) || C <- ConstLabels],
1454  %% Create code to create local name for constants
1455  ConstLoad = [load_constant(C) || C <- ConstLabels],
1456  %% Create code to create jump tables
1457  SwitchDecl = declare_switches(SwitchList, Fun),
1458  %% Create code to create a table with the labels of all closure calls
1459  {ClosureLabelDecl, Relocs1} =
1460    declare_closure_labels(ClosureLabels, Relocs, Fun),
1461  %% Enter constants to relocations
1462  Relocs2 = lists:foldl(fun const_to_dict/2, Relocs1, ConstLabels),
1463  %% Temporary Store inc_stack and llvm_fix_pinned_regs to Dictionary
1464  %% TODO: Remove this
1465  Relocs3 = dict:store("inc_stack_0", {call, not_remote, {bif, inc_stack_0, 0}}, Relocs2),
1466  Relocs4 = dict:store("hipe_bifs.llvm_fix_pinned_regs.0",
1467                       {call, remote, {hipe_bifs, llvm_fix_pinned_regs, 0}}, Relocs3),
1468  BranchMetaData = [
1469    hipe_llvm:mk_meta(?BRANCH_META_TAKEN,     ["branch_weights", 99, 1])
1470  , hipe_llvm:mk_meta(?BRANCH_META_NOT_TAKEN, ["branch_weights", 1, 99])
1471  ],
1472  ExternalDeclarations = AtomDecl ++ ClosureDecl ++ ConstDecl ++ FunDecl ++
1473    ClosureLabelDecl ++ SwitchDecl ++ BranchMetaData,
1474  LocalVariables = AtomLoad ++ ClosureLoad ++ ConstLoad,
1475  {Relocs4, ExternalDeclarations, LocalVariables}.
1476
1477%% @doc Separate relocations according to their type.
1478seperate_relocs(Relocs) ->
1479  seperate_relocs(Relocs, [], [], [], [], []).
1480
1481seperate_relocs([], CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc) ->
1482  {CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc};
1483seperate_relocs([R|Rs], CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc) ->
1484  case R of
1485    {_, {call, _, _}} ->
1486      seperate_relocs(Rs, [R | CallAcc], AtomAcc, ClosureAcc, LabelAcc,
1487                      JmpTableAcc);
1488
1489    {_, {atom, _}} ->
1490      seperate_relocs(Rs, CallAcc, [R | AtomAcc], ClosureAcc, LabelAcc,
1491                      JmpTableAcc);
1492    {_, {closure, _}} ->
1493      seperate_relocs(Rs, CallAcc, AtomAcc, [R | ClosureAcc], LabelAcc,
1494                      JmpTableAcc);
1495    {_, {switch, _, _}} ->
1496      seperate_relocs(Rs, CallAcc, AtomAcc, ClosureAcc, LabelAcc,
1497                      [R | JmpTableAcc]);
1498    {_, {closure_label, _, _}} ->
1499      seperate_relocs(Rs, CallAcc, AtomAcc, ClosureAcc, [R | LabelAcc],
1500                      JmpTableAcc)
1501  end.
1502
1503%% @doc External declaration of an atom.
1504declare_atom({AtomName, _}) ->
1505  %% The type has to be byte, or a backend might assume the constant is aligned
1506  %% and incorrectly optimise away type tests
1507  ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
1508  hipe_llvm:mk_const_decl("@" ++ AtomName, "external constant", ByteTy, "").
1509
1510%% @doc Creation of local variable for an atom.
1511load_atom({AtomName, _}) ->
1512  Dst = "%" ++ AtomName ++ "_var",
1513  Name = "@" ++ AtomName,
1514  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1515  ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
1516  hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
1517
1518%% @doc External declaration of a closure.
1519declare_closure({ClosureName, _})->
1520  ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
1521  hipe_llvm:mk_const_decl("@" ++ ClosureName, "external constant", ByteTy, "").
1522
1523%% @doc Creation of local variable for a closure.
1524load_closure({ClosureName, _})->
1525  Dst = "%" ++ ClosureName ++ "_var",
1526  Name = "@" ++ ClosureName,
1527  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1528  ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
1529  hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
1530
1531%% @doc Declaration of a local variable for a switch jump table.
1532declare_switches(JumpTableList, Fun) ->
1533  FunName = trans_mfa_name(Fun, not_remote),
1534  [declare_switch_table(X, FunName) || X <- JumpTableList].
1535
1536declare_switch_table({Name, {switch, {TableType, Labels, _, _}, _}}, FunName) ->
1537  LabelList = [mk_jump_label(L) || L <- Labels],
1538  Fun1 = fun(X) -> "i8* blockaddress(@" ++ FunName ++ ", " ++ X ++ ")" end,
1539  List2 = lists:map(Fun1, LabelList),
1540  List3 = lists:flatten(lists:join(",\n", List2)),
1541  List4 = "[\n" ++ List3 ++ "\n]\n",
1542  hipe_llvm:mk_const_decl("@" ++ Name, "constant", TableType, List4).
1543
1544%% @doc Declaration of a variable for a table with the labels of all closure
1545%%      calls in the code.
1546declare_closure_labels([], Relocs, _Fun) ->
1547  {[], Relocs};
1548declare_closure_labels(ClosureLabels, Relocs, Fun) ->
1549  FunName = trans_mfa_name(Fun, not_remote),
1550  {LabelList, ArityList} =
1551    lists:unzip([{mk_jump_label(Label), A} ||
1552		  {_, {closure_label, Label, A}} <- ClosureLabels]),
1553  Relocs1 = relocs_store("table_closures", {table_closures, ArityList}, Relocs),
1554  List2 =
1555    ["i8* blockaddress(@" ++ FunName ++ ", " ++ L ++ ")" || L <- LabelList],
1556  List3 = lists:flatten(lists:join(",\n", List2)),
1557  List4 = "[\n" ++ List3 ++ "\n]\n",
1558  NrLabels = length(LabelList),
1559  ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
1560  TableType = hipe_llvm:mk_array(NrLabels, ByteTyPtr),
1561  ConstDecl =
1562    hipe_llvm:mk_const_decl("@table_closures", "constant", TableType, List4),
1563  {[ConstDecl], Relocs1}.
1564
1565%% @doc A call is treated as non external only in a case of a local recursive
1566%%      function.
1567is_external_call({_, {call, not_remote, MFA}}, MFA) -> false;
1568is_external_call(_, _) -> true.
1569
1570%% @doc External declaration of a function.
1571call_to_decl({Name, {call, _, MFA}}) ->
1572  {M, _F, A} = MFA,
1573  CConv = "cc 11",
1574  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1575  FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
1576  {Type, Args} =
1577    case M of
1578      llvm ->
1579        {hipe_llvm:mk_struct([WordTy, hipe_llvm:mk_int(1)]), [1, 2]};
1580      %% +precoloured regs
1581      _ ->
1582        {FunRetTy, lists:seq(1, A + ?NR_PINNED_REGS)}
1583    end,
1584  ArgsTypes = lists:duplicate(length(Args), WordTy),
1585  hipe_llvm:mk_fun_decl([], [], CConv, [], Type, "@" ++ Name, ArgsTypes, []).
1586
1587%% @doc These functions are always declared, even if not used.
1588fixed_fun_decl() ->
1589  ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
1590  ByteTyPtr = hipe_llvm:mk_pointer(ByteTy),
1591  LandPad = hipe_llvm:mk_fun_decl([], [], [], [], hipe_llvm:mk_int(32),
1592    "@__gcc_personality_v0", [hipe_llvm:mk_int(32), hipe_llvm:mk_int(64),
1593    ByteTyPtr, ByteTyPtr], []),
1594  GCROOTDecl = hipe_llvm:mk_fun_decl([], [], [], [], hipe_llvm:mk_void(),
1595    "@llvm.gcroot", [hipe_llvm:mk_pointer(ByteTyPtr), ByteTyPtr], []),
1596  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1597  FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
1598  FixPinnedRegs = hipe_llvm:mk_fun_decl([], [], [], [], FunRetTy,
1599    "@hipe_bifs.llvm_fix_pinned_regs.0", [], []),
1600  GcMetadata = hipe_llvm:mk_const_decl("@gc_metadata", "external constant",
1601                                       ByteTy, ""),
1602  [LandPad, GCROOTDecl, FixPinnedRegs, GcMetadata].
1603
1604%% @doc Declare an External Consant. We declare all constants as i8 in order to
1605%%      be able to calcucate pointers of the form DL+6, with the getelementptr
1606%%      instruction. Otherwise we have to convert constants form pointers to
1607%%      values, add the offset and convert them again to pointers.
1608declare_constant(Label) ->
1609  Name = "@DL" ++ integer_to_list(Label),
1610  ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
1611  hipe_llvm:mk_const_decl(Name, "external constant", ByteTy, "").
1612
1613%% @doc Load a constant is achieved by converting a pointer to an integer of
1614%%      the correct width.
1615load_constant(Label) ->
1616  Dst = "%DL" ++ integer_to_list(Label) ++ "_var",
1617  Name = "@DL" ++ integer_to_list(Label),
1618  WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
1619  ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
1620  hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
1621
1622%% @doc Store external constants and calls to dictionary.
1623const_to_dict(Elem, Dict) ->
1624  Name = "DL" ++ integer_to_list(Elem),
1625  dict:store(Name, {'constant', Elem}, Dict).
1626
1627%% @doc Export the hipe literals that LLVM needs to generate the prologue as
1628%% metadata.
1629add_literals_metadata(ExternalDecls) ->
1630  Pairs = [hipe_llvm:mk_meta(integer_to_list(?FIRST_FREE_META_NO),
1631			     ["P_NSP_LIMIT", ?P_NSP_LIMIT])
1632	  ,hipe_llvm:mk_meta(integer_to_list(?FIRST_FREE_META_NO + 1),
1633			     ["X86_LEAF_WORDS", ?X86_LEAF_WORDS])
1634	  ,hipe_llvm:mk_meta(integer_to_list(?FIRST_FREE_META_NO + 2),
1635			     ["AMD64_LEAF_WORDS", ?AMD64_LEAF_WORDS])
1636	  ],
1637  [hipe_llvm:mk_meta(?HIPE_LITERALS_META, Pairs) |
1638   Pairs ++ ExternalDecls].
1639