1
%% -*- erlang-indent-level: 2 -*-
2
%% ====================================================================
3
%% Filename : hipe_sparc_loader.erl
4
%% Module : hipe_sparc_loader
5
%% Purpose : To provide SPARC specific code-patching for the loader
7
%% Very sparc specific.
8
%% Also, the native code-stubs for non-existing functions
9
%% depends on the use of specific sparc registers.
11
%% ====================================================================
12
%% Exported functions (short description):
15
%% offsets_to_addresses/2
16
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17
-module(hipe_sparc_loader).
18
-export([make_native_stub/2,
20
offsets_to_addresses/2]).
21
%%-define(DEBUG,true).
23
%% ____________________________________________________________________
25
offsets_to_addresses([O|Os],Base) ->
26
[{O+Base,sethi},{O+Base+4,'or'}|offsets_to_addresses(Os,Base)];
27
offsets_to_addresses([],_) -> [].
29
%% ____________________________________________________________________
31
patch_instr(Addr, Val, Type) ->
33
call -> patch_call_instr(Addr, Val);
34
sethiref -> Hi = (Val bsr 10),
35
patch_sethi(Addr, Hi);
36
orref -> Lo = (Val band 16#3FF),
38
atom -> patch_hi_or(Addr,Val);
39
constant -> patch_hi_or(Addr,Val);
40
closure -> patch_hi_or(Addr,Val);
41
c_const -> patch_hi_or(Addr,Val)
44
patch_call_instr(Address,DestAddress) ->
45
RelDest = DestAddress - Address,
46
NewI = ((1 bsl 30) bor (bits_32(RelDest) bsr 2)),
47
hipe_bifs:write_u32(Address,NewI).
50
patch_hi_or(Address,Value) ->
52
patch_sethi(Address,Hi),
53
Lo = (Value band 16#3FF),
54
patch_alu(Address+4,Lo).
56
patch_sethi(Addr,Bits) ->
57
I = hipe_bifs:read_u32(Addr),
58
NewI = ((I band (2#1111111111 bsl 22)) bor bits_22(Bits)),
59
hipe_bifs:write_u32(Addr,NewI).
62
patch_alu(Addr,Bits) ->
63
I = hipe_bifs:read_u32(Addr),
64
NewI = ((I band (2#1111111111111111111 bsl 13)) bor bits_13(Bits)),
65
hipe_bifs:write_u32(Addr,NewI).
68
bits_13(X) -> X band 16#1fff.
69
bits_22(X) -> X band 16#3fffff.
70
bits_32(X) -> X band 16#ffffffff.
72
%% ____________________________________________________________________
74
make_native_stub(Address, Arity) ->
76
Mem = hipe_bifs:alloc_code(CodeSize),
77
RelOffset = (hipe_bifs:primop_address(callemu)-(Mem+3*4)) ,
80
[%% sethi $temp0, hi(Address)
81
((50331648 band (2#1111111111 bsl 22)) bor bits_22((Address bsr 10))),
83
2886729743, %% 2819620879,
84
%% or $temp0, lo(Address)
85
((2182111232 band (2#1111111111111111111 bsl 13))
86
bor bits_13((Address band 16#3FF))),
89
((1 bsl 30) bor (bits_32(RelOffset) bsr 2)),
92
((2920292352 band (2#1111111111111111111 bsl 13)) bor
94
hipe_unified_loader:write_words(Code, Mem),