60
60
-define(IS_SPILLED(Reg,Map),hipe_temp_map:is_spilled(hipe_sparc:reg_nr(Reg),Map)).
62
62
frame(Cfg, TempMap, FpMap, NextSpillPos, _Options) ->
63
%% io:format("~p\n",[TempMap]),
63
%% io:format("~p\n",[TempMap]),
64
64
rewrite(Cfg, TempMap, FpMap, NextSpillPos).
67
66
rewrite(Cfg, TempMap, FpMap, NextSpillPos) ->
68
%% hipe_sparc_cfg:pp(Cfg),
67
%% hipe_sparc_cfg:pp(Cfg),
70
68
Sparc = hipe_sparc_cfg:linearize(Cfg),
71
69
Arity = hipe_sparc:sparc_arity(Sparc),
72
70
Code = hipe_sparc:sparc_code(Sparc),
75
71
%% ConvNeed is added if there are any conv_fp instructions.
77
73
case get(hipe_inline_fp) of
80
fun(I, Acc) -> case hipe_sparc:is_conv_fp(I) of true->1; _->Acc end
75
lists:foldl(fun(I, Acc) ->
76
case hipe_sparc:is_conv_fp(I) of true -> 1; _ -> Acc end
126
122
%% Create a new CFG
127
123
NewSparc = hipe_sparc:sparc_code_update(Sparc, lists:flatten(NewCode)),
128
124
CFG0 = hipe_sparc_cfg:init(NewSparc),
129
CFG1 = hipe_sparc_cfg:var_range_update(CFG0, {0, 31}),
130
125
%% io:format("\n\n\n\n\n\n\n\nAfter frame\n"),
131
126
%% hipe_sparc_cfg:pp(CFG1),
134
129
rewrite_instrs([I|Is], TempMap, TempMaps, FpMap, Need, Arity, RetLabel) ->
136
131
case hipe_sparc:is_label(I) of
138
%% io:format("~w\n",[?vector_get(hipe_sparc:label_name(I),TempMaps)]),
139
?vector_get(hipe_sparc:label_name(I),TempMaps);
133
%% io:format("~w\n",[hipe_vectors:get(TempMaps, hipe_sparc:label_name(I)-1)]),
134
hipe_vectors:get(TempMaps, hipe_sparc:label_name(I)-1);
143
138
[rewrite_instr(I, NewMap, FpMap, Need, Arity, RetLabel) |
144
139
rewrite_instrs(Is, NewMap, TempMaps, FpMap, Need, Arity, RetLabel)];
145
rewrite_instrs([],_,_,_,_,_,_) -> [].
140
rewrite_instrs([],_,_,_,_,_,_) ->
148
143
rewrite_instr(I, TempMap, FpMap, Need, Arity, RetLabel) ->
149
144
%% io:format("\n\n~w -> \n",[I]),
155
150
remap_fp_regs(I, FpMap) ->
156
case hipe_sparc:type(I) of
157
%% These instructions handles their own remapping.
152
%% These instructions handle their own remapping.
154
#pseudo_spill{} -> I;
155
#pseudo_unspill{} -> I;
162
157
Defs = hipe_sparc:fp_reg_defines(I),
163
NewI = remap_fp(remap_fp(I, Defs, FpMap),
158
NewI = remap_fp(remap_fp(I, Defs, FpMap),
164
159
hipe_sparc:fp_reg_uses(I),
169
164
rewrite_instr2(I, TempMap, FpMap, Need, Arity, RetLabel) ->
171
case hipe_sparc:type(I) of
173
167
?EXIT({pseudo_push, not_supportet_any_more,I});
175
169
Temp = hipe_sparc:pseudo_pop_reg(I),
176
170
Reg = map(Temp,TempMap),
177
%% Arg position on stack = -(arg index + need)*4
178
Pos = - ((hipe_sparc:imm_value(
179
hipe_sparc:pseudo_pop_index(I)) +
171
%% Arg position on stack = -(arg index + need)*4
172
ArgIndex = hipe_sparc:imm_value(hipe_sparc:pseudo_pop_index(I)),
173
Pos = - ((ArgIndex + Need) bsl ?log2_wordsize),
181
174
gen_stack_load(Pos, Reg);
183
176
rewrite_move(I, TempMap);
185
178
rewrite_spill(I, TempMap, FpMap);
187
180
rewrite_unspill(I, TempMap, FpMap);
190
182
rewrite_call(I, TempMap, Need, Arity);
193
184
%% Note we assume that the arguments to return have been
194
185
%% mapped to physical register in the translation RTL->SPARC.
196
187
%% XXX: Fix if we start using multiple return values
197
188
%% Acctually just fix gen_ret/2 to annotate the
198
189
%% jmp with the live registers...
199
case length(hipe_sparc:pseudo_return_regs(I)) == 1 of
190
case length(hipe_sparc:pseudo_return_regs(I)) =:= 1 of
200
191
true -> %% Just one retval all is ok
201
hipe_sparc:goto_create(RetLabel,[return]);
192
hipe_sparc:goto_create(RetLabel);
203
194
%% Number of retvalues not 1.
204
195
?EXIT({multiple_retvals_not_handled,I})
208
198
rewrite_enter(I, TempMap, Need, Arity);
211
rewrite_fmov(I, TempMap, FpMap);
200
rewrite_fmove(I, TempMap, FpMap);
213
202
rewrite_load_fp(I, TempMap);
215
204
rewrite_store_fp(I, TempMap);
217
206
NewI = map_temps(I, TempMap),
218
207
Source = hipe_sparc:conv_fp_src(NewI),
219
208
Dest = hipe_sparc:conv_fp_dest(NewI),
220
209
Off = hipe_sparc:mk_imm(get_offset(Need - 1)),
221
210
SP = hipe_sparc:mk_reg(hipe_sparc_registers:stack_pointer()),
223
[hipe_sparc:store_create(SP, Off, w, Source, []),
224
hipe_sparc:load_fp_create(Dest, 32, single, SP, Off, []),
211
[hipe_sparc:store_create(SP, Off, w, Source),
212
hipe_sparc:load_fp_create(Dest, 32, single, SP, Off),
225
213
hipe_sparc:conv_fp_create(Dest, Dest)];
228
215
%% All other instructions.
229
216
%% No special handling, just map the temps to regs or spill positions.
244
231
Args = hipe_sparc:pseudo_enter_args(I),
245
232
RegArgs = lists:sublist(Args,1,NoRegArgs),
246
233
%% Get target (closure or address).
248
= case hipe_sparc:pseudo_enter_type(I) of
250
{map(hipe_sparc:pseudo_enter_target(I), TempMap),[]};
252
TL = hipe_sparc:pseudo_enter_target(I),
254
TI = hipe_sparc:load_address_create(TR,TL,
234
T = hipe_sparc:pseudo_enter_target(I),
236
case hipe_sparc:pseudo_enter_is_known(I) of
238
{map(T, TempMap),[]};
241
TT = case hipe_sparc:pseudo_enter_type(I) of
242
remote -> remote_function;
243
not_remote -> local_function
245
TI = hipe_sparc:load_address_create(TR, T, TT),
259
248
CP = ?MK_CP_REG(),
261
250
%% The code for enter.
263
252
%% Restore CP from stack
264
253
%% TODO: Do this only in non-leaf functions.
265
gen_stack_load(-(Need*4),CP),
254
gen_stack_load(-(Need bsl ?log2_wordsize), CP),
267
256
%% If arguments to the called function spill over to the
268
257
%% stack, do some shuffling.
296
284
remap_call_regs(I, TempMap) ->
297
285
Defs = hipe_sparc:keep_registers(hipe_sparc:defines(I)),
299
lists:sublist(hipe_sparc:call_link_args(I),
300
hipe_sparc_registers:register_args()),
302
case hipe_sparc:call_link_type(I) of
286
ArgsInRegs = lists:sublist(hipe_sparc:call_link_args(I),
287
hipe_sparc_registers:register_args()),
288
case hipe_sparc:call_link_is_known(I) of
304
290
Target = hipe_sparc:call_link_target(I),
305
291
case ?IS_SPILLED(Target,TempMap) of
308
remap(I, [(Defs ++ ArgsInRegs)],TempMap),
293
RemappedCall = remap(I, [(Defs ++ ArgsInRegs)],TempMap),
309
294
Temp = ?MK_TEMP_REG(),
310
Pos = get_spill_offset(hipe_temp_map:find(Target, TempMap)),
295
Pos = get_spill_offset(hipe_temp_map:find(hipe_sparc:reg_nr(Target), TempMap)),
311
296
[gen_stack_load(Pos, Temp),
312
297
hipe_sparc:call_link_target_update(RemappedCall, Temp)];
314
299
remap(I, [Target | (Defs ++ ArgsInRegs)],TempMap)
317
302
remap(I,Defs ++ ArgsInRegs, TempMap)
321
306
%% ____________________________________________________________________
486
469
rewrite_load_fp(I, TempMap)->
487
NewI = map_temps(I, TempMap),
488
Source = hipe_sparc:load_fp_src(NewI),
489
Dest = hipe_sparc:load_fp_dest(NewI),
490
Off = hipe_sparc:load_fp_off(NewI),
491
Align = hipe_sparc:load_fp_align(NewI),
492
case hipe_sparc:load_fp_type(NewI) of
494
Dest2 = hipe_sparc:mk_fpreg(hipe_sparc:fpreg_nr(Dest) + 1),
495
case hipe_sparc:is_imm(Off) of
497
Off2 = hipe_sparc:mk_imm(hipe_sparc:imm_value(Off) + 4),
498
[hipe_sparc:load_fp_create(Dest, Align, single, Source, Off, []),
499
hipe_sparc:load_fp_create(Dest2, Align, single, Source, Off2,[])];
500
_ -> %% The offset is a register
501
[hipe_sparc:load_fp_create(Dest, Align, single, Source, Off, []),
502
hipe_sparc:alu_create(Off, Off, '+', hipe_sparc:mk_imm(4), []),
503
hipe_sparc:load_fp_create(Dest2, Align, single, Source, Off,[]),
504
hipe_sparc:alu_create(Off, Off, '-', hipe_sparc:mk_imm(4), [])]
470
NewI = map_temps(I, TempMap),
471
Source = hipe_sparc:load_fp_src(NewI),
472
Dest = hipe_sparc:load_fp_dest(NewI),
473
Off = hipe_sparc:load_fp_off(NewI),
474
Align = hipe_sparc:load_fp_align(NewI),
475
case hipe_sparc:load_fp_type(NewI) of
477
Dest2 = hipe_sparc:mk_fpreg(hipe_sparc:fpreg_nr(Dest) + 1),
478
case hipe_sparc:is_imm(Off) of
480
Off2 = hipe_sparc:mk_imm(hipe_sparc:imm_value(Off) + 4),
481
[hipe_sparc:load_fp_create(Dest, Align, single, Source, Off),
482
hipe_sparc:load_fp_create(Dest2, Align, single, Source, Off2)];
483
_ -> %% The offset is a register
484
[hipe_sparc:load_fp_create(Dest, Align, single, Source, Off),
485
hipe_sparc:alu_create(Off, Off, '+', hipe_sparc:mk_imm(4)),
486
hipe_sparc:load_fp_create(Dest2, Align, single, Source, Off),
487
hipe_sparc:alu_create(Off, Off, '-', hipe_sparc:mk_imm(4))]
511
493
rewrite_store_fp(I, TempMap)->
512
NewI = map_temps(I, TempMap),
513
Source = hipe_sparc:store_fp_src(NewI),
514
Dest = hipe_sparc:store_fp_dest(NewI),
515
Off = hipe_sparc:store_fp_off(NewI),
516
Align = hipe_sparc:store_fp_align(NewI),
517
case hipe_sparc:store_fp_type(NewI) of
519
Source2 = hipe_sparc:mk_fpreg(hipe_sparc:fpreg_nr(Source) + 1),
520
case hipe_sparc:is_imm(Off) of
522
Off2 = hipe_sparc:mk_imm(hipe_sparc:imm_value(Off) + 4),
523
[hipe_sparc:store_fp_create(Dest, Off, single, Align, Source, []),
524
hipe_sparc:store_fp_create(Dest, Off2, single, Align, Source2, [])];
526
[hipe_sparc:store_fp_create(Dest, Off, single, Align, Source, []),
527
hipe_sparc:alu_create(Off, Off, '+', hipe_sparc:mk_imm(4), []),
528
hipe_sparc:store_fp_create(Dest, Off, single, Align, Source2, []),
529
hipe_sparc:alu_create(Off, Off, '-', hipe_sparc:mk_imm(4), [])]
494
NewI = map_temps(I, TempMap),
495
Source = hipe_sparc:store_fp_src(NewI),
496
Dest = hipe_sparc:store_fp_dest(NewI),
497
Off = hipe_sparc:store_fp_off(NewI),
498
Align = hipe_sparc:store_fp_align(NewI),
499
case hipe_sparc:store_fp_type(NewI) of
501
Source2 = hipe_sparc:mk_fpreg(hipe_sparc:fpreg_nr(Source) + 1),
502
case hipe_sparc:is_imm(Off) of
504
Off2 = hipe_sparc:mk_imm(hipe_sparc:imm_value(Off) + 4),
505
[hipe_sparc:store_fp_create(Dest, Off, single, Align, Source),
506
hipe_sparc:store_fp_create(Dest, Off2, single, Align, Source2)];
508
[hipe_sparc:store_fp_create(Dest, Off, single, Align, Source),
509
hipe_sparc:alu_create(Off, Off, '+', hipe_sparc:mk_imm(4)),
510
hipe_sparc:store_fp_create(Dest, Off, single, Align, Source2),
511
hipe_sparc:alu_create(Off, Off, '-', hipe_sparc:mk_imm(4))]
677
659
{lists:reverse(ToSave),lists:reverse(Args)}.
679
661
save([Pos|Poses], Offset, TempReg) ->
662
ToPos = Offset bsl ?log2_wordsize,
681
663
FromPos = get_offset(Pos+1),
682
[gen_stack_load(FromPos,TempReg),
664
[gen_stack_load(FromPos, TempReg),
683
665
gen_stack_store(ToPos, TempReg)
684
666
| save(Poses, Offset+1, TempReg)];
685
667
save([],_,_) -> [].
687
669
pushem([{reg,R}|Args], Pos, Temp) ->
689
[gen_stack_store(ToPos, hipe_sparc:mk_reg(R))|
670
ToPos = Pos bsl ?log2_wordsize,
671
[gen_stack_store(ToPos, hipe_sparc:mk_reg(R)) | pushem(Args,Pos+1, Temp)];
672
pushem([{spill,P}|Args], Pos, Temp) ->
673
FromPos = P bsl ?log2_wordsize,
674
ToPos = Pos bsl ?log2_wordsize,
675
[gen_stack_load(FromPos, Temp),
676
gen_stack_store(ToPos, Temp) |
690
677
pushem(Args,Pos+1, Temp)];
691
pushem([{spill,P}|Args], Pos, Temp) ->
694
[gen_stack_load(FromPos,Temp),
695
gen_stack_store(ToPos, Temp)|
696
pushem(Args,Pos+1, Temp)];
697
678
pushem([{imm,I}|Args], Pos, Temp) ->
699
[ hipe_sparc:move_create(Temp, hipe_sparc:mk_imm(I), [get_arg]),
700
gen_stack_store(ToPos, Temp)|
701
pushem(Args,Pos+1, Temp)];
702
pushem([],_,_) -> [].
679
ToPos = Pos bsl ?log2_wordsize,
680
[hipe_sparc:move_create(Temp, hipe_sparc:mk_imm(I)),
681
gen_stack_store(ToPos, Temp) |
682
pushem(Args, Pos+1, Temp)];
683
pushem([], _, _) -> [].
706
685
find_reg(Temp,Map) ->
707
case hipe_temp_map:find(hipe_sparc:reg_nr(Temp), Map) of
710
Where -> ?EXIT({temp_assumed_in_reg,Temp,Where})
686
case hipe_temp_map:find(hipe_sparc:reg_nr(Temp), Map) of
689
Where -> ?EXIT({temp_assumed_in_reg,Temp,Where})
713
692
find_fpreg(Temp,Map) ->
714
case hipe_temp_map:find(hipe_sparc:fpreg_nr(Temp), Map) of
717
Where -> ?EXIT({temp_assumed_in_fpreg,Temp,Where})
693
case hipe_temp_map:find(hipe_sparc:fpreg_nr(Temp), Map) of
696
Where -> ?EXIT({temp_assumed_in_fpreg,Temp,Where})
720
699
%%find_pos(Temp,Map) ->
721
700
%% case hipe_temp_map:find(hipe_sparc:reg_nr(Temp), Map) of
857
826
call_args_need(Args) ->
858
827
length(args_on_stack(hipe_sparc_registers:register_args(), Args)).
863
829
set_stack_size(Call,Size, Arity) ->
864
830
SD = hipe_sparc:call_link_stack_desc(Call),
865
NewSD = hipe_sparc_stack_descriptors:set_size(SD, Size),
866
NewSD2 = hipe_sparc_stack_descriptors:set_arity(NewSD, Arity),
831
NewSD = hipe_sparc:sdesc_size_update(SD, Size),
832
NewSD2 = hipe_sparc:sdesc_arity_update(NewSD, Arity),
867
833
hipe_sparc:call_link_stack_desc_update(Call,NewSD2).
870
835
gen_stack_test(StackNeed, SP, CP, Arity, Cfg) ->
871
Leaf = hipe_sparc_cfg:is_leaf(Cfg),
836
Leaf = hipe_sparc_cfg:is_leaf(Cfg),
872
837
TempReg = ?MK_TEMP_REG(),
873
838
TempReg1 = hipe_sparc:mk_reg(hipe_sparc_registers:temp1()),
876
if (StackNeed) =:= 0 -> {[],[]};
877
(StackNeed) < ?HIPE_SPARC_LEAF_WORDS, Leaf =:= true -> {[],[]};
840
if (StackNeed) =:= 0 ->
842
(StackNeed) < ?SPARC_LEAF_WORDS, Leaf =:= true ->
879
845
Zero = hipe_sparc:mk_reg(hipe_sparc_registers:zero()),
880
846
SL = hipe_sparc:mk_reg(hipe_sparc_registers:stack_limit()),
886
852
OverflowName = hipe_rtl:label_name(OverflowLbl),
887
853
StartName = hipe_rtl:label_name(StartLbl),
888
854
TestName = hipe_rtl:label_name(TestLbl),
889
ByteNeed = (?HIPE_SPARC_LEAF_WORDS+StackNeed)*4,
855
ByteNeed = (?SPARC_LEAF_WORDS+StackNeed) bsl ?log2_wordsize,
891
857
if ByteNeed > 16#fff -> %% Max in simm13.
893
hipe_sparc:alu_create(TempReg, SL, '-', SP, []),
859
hipe_sparc:alu_create(TempReg, SL, '-', SP),
894
860
hipe_sparc:sethi_create(TempReg1,
896
high22(ByteNeed)),[]),
861
hipe_sparc:mk_imm(high22(ByteNeed))),
897
862
hipe_sparc:alu_create(TempReg1, TempReg1, 'or',
901
hipe_sparc:alu_cc_create(Zero, TempReg, '-', TempReg1,
903
hipe_sparc:b_create(l, OverflowName,
904
StartName, Pred, na, []),
863
hipe_sparc:mk_imm(low10(ByteNeed))),
864
hipe_sparc:alu_cc_create(Zero, TempReg, '-', TempReg1),
865
hipe_sparc:b_create(l, OverflowName, StartName, Pred, na),
908
[hipe_sparc:alu_create(TempReg, SL, '-', SP, []),
868
[hipe_sparc:alu_create(TempReg, SL, '-', SP),
909
869
hipe_sparc:alu_cc_create(Zero, TempReg, '-',
910
hipe_sparc:mk_imm(ByteNeed),
912
hipe_sparc:b_create(l, OverflowName,
913
StartName, Pred, na, []),
870
hipe_sparc:mk_imm(ByteNeed)),
871
hipe_sparc:b_create(l, OverflowName, StartName, Pred, na),
918
874
CPSAVE = hipe_sparc:mk_reg(hipe_sparc_registers:cpsave()),
919
{[hipe_sparc:goto_create(TestName,[]),
875
{[hipe_sparc:goto_create(TestName),
920
876
TestLbl|TestCode],
922
hipe_sparc:move_create(CPSAVE, CP,[savecp]),
878
hipe_sparc:move_create(CPSAVE, CP),
923
879
hipe_sparc:call_link_create(inc_stack_fun(Arity),
926
hipe_rtl:label_name(RetLbl), [], c, []),
882
hipe_rtl:label_name(RetLbl), [], not_remote),
928
hipe_sparc:move_create(CP, CPSAVE,[restorecp]),
929
hipe_sparc:goto_create(TestName,[])]
884
hipe_sparc:move_create(CP, CPSAVE),
885
hipe_sparc:goto_create(TestName)]
935
889
inc_stack_fun(Arity) ->
938
hipe_sparc_registers:register_args()),
939
list_to_atom("inc_stack_" ++
940
integer_to_list(ArgsInRegs) ++ "args_0").
890
ArgsInRegs = min(Arity, hipe_sparc_registers:register_args()),
891
list_to_atom("inc_stack_" ++ integer_to_list(ArgsInRegs) ++ "args_0").
943
894
gen_alloc_code(NeededBytes,SP) ->