1
%%% -*- erlang-indent-level: 2 -*-
3
%%% ===========================================================================
4
%%% Filename : hipe_amd64_registers.erl
5
%%% Author : Daniel Luna (luna@update.uu.se)
8
%%% ===========================================================================
10
-module(hipe_amd64_registers).
27
is_precoloured_sse2/1,
47
-include("../rtl/hipe_literals.hrl").
49
-ifdef(AMD64_HP_IN_REGISTER).
50
-export([heap_pointer/0]).
53
-ifdef(AMD64_FCALLS_IN_REGISTER).
54
fcalls_offset() -> false.
56
fcalls_offset() -> ?P_FCALLS.
57
-define(AMD64_FCALLS_REGISTER,16).
60
-ifdef(AMD64_HEAP_LIMIT_IN_REGISTER).
61
heap_limit_offset() -> false.
63
-define(AMD64_HEAP_LIMIT_REGISTER, 17).
64
heap_limit_offset() -> ?P_HP_LIMIT.
84
-define(FCALLS, ?AMD64_FCALLS_REGISTER).
85
-define(HEAP_LIMIT, ?AMD64_HEAP_LIMIT_REGISTER).
86
-define(LAST_PRECOLOURED, 17).
98
-define(PROC_POINTER, ?RBP).
110
?FCALLS -> "%fcalls";
111
?HEAP_LIMIT -> "%hplim";
112
Other -> "%r" ++ integer_to_list(Other)
119
first_virtual() -> ?LAST_PRECOLOURED + 1.
121
is_precoloured(X) -> X =< ?LAST_PRECOLOURED.
123
is_precoloured_sse2(X) -> X =< 15.
125
is_precoloured_x87(X) -> X =< 6.
152
proc_pointer() -> ?PROC_POINTER.
154
heap_limit() -> ?HEAP_LIMIT.
157
-ifdef(AMD64_HP_IN_REGISTER).
158
-define(HEAP_POINTER, ?AMD64_HEAP_POINTER).
159
heap_pointer() -> ?HEAP_POINTER.
160
-define(LIST_HP_LIVE_AT_RETURN,[{?HEAP_POINTER,untagged}]).
161
is_heap_pointer(?HEAP_POINTER) -> true;
162
is_heap_pointer(_) -> false.
163
%% -define(LIST_HP_FIXED,[?HEAP_POINTER]).
166
-define(HEAP_POINTER, -1).
167
is_heap_pointer(_) -> false.
168
%% -define(LIST_HP_FIXED,[]).
169
-define(LIST_HP_LIVE_AT_RETURN,[]).
172
proc_offset(?FCALLS) -> fcalls_offset();
173
proc_offset(?HEAP_LIMIT) -> heap_limit_offset();
174
proc_offset(_) -> false.
176
sp_limit_offset() -> ?P_NSP_LIMIT.
178
is_fixed(?RSP) -> true;
179
is_fixed(?PROC_POINTER) -> true;
180
is_fixed(?FCALLS) -> true;
181
is_fixed(?HEAP_LIMIT) -> true;
182
is_fixed(R) -> is_heap_pointer(R).
185
% %% [?ESP, ?PROC_POINTER, ?FCALLS, ?HEAP_LIMIT | ?LIST_HP_FIXED].
188
[?RDX, ?RCX, ?RBX, ?RAX, ?RSI, ?RDI,
189
?R8 , ?R9 , ?R10, ?R11, ?R12, ?R13, ?R14, ?R15]
190
-- [?FCALLS, ?HEAP_POINTER, ?HEAP_LIMIT].
192
allocatable_sse2() ->
193
[00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15]. %% xmm0 - xmm15
198
nr_args() -> ?AMD64_NR_ARG_REGS.
201
if N < ?AMD64_NR_ARG_REGS ->
209
_ -> exit({?MODULE, arg, N})
212
exit({?MODULE, arg, N})
217
?ARG0 -> ?AMD64_NR_ARG_REGS > 0;
218
?ARG1 -> ?AMD64_NR_ARG_REGS > 1;
219
?ARG2 -> ?AMD64_NR_ARG_REGS > 2;
220
?ARG3 -> ?AMD64_NR_ARG_REGS > 3;
221
?ARG4 -> ?AMD64_NR_ARG_REGS > 4;
222
?ARG5 -> ?AMD64_NR_ARG_REGS > 5;
227
Max = ?AMD64_NR_ARG_REGS,
228
N = if Arity > Max -> Max; true -> Arity end,
231
args(I, Rest) when I < 0 -> Rest;
232
args(I, Rest) -> args(I-1, [arg(I) | Rest]).
237
_ -> exit({?MODULE, ret, N})
241
[{?RAX,tagged},{?RAX,untagged}, % does the RA strip the type or not?
242
{?RDX,tagged},{?RDX,untagged},
243
{?RCX,tagged},{?RCX,untagged},
244
{?RBX,tagged},{?RBX,untagged},
245
{?RDI,tagged},{?RDI,untagged},
246
{?RSI,tagged},{?RSI,untagged},
247
{?R8 ,tagged},{?R8 ,untagged},
248
{?R9 ,tagged},{?R9 ,untagged},
249
{?R10,tagged},{?R10,untagged},
250
{?R11,tagged},{?R11,untagged},
251
{?R12,tagged},{?R12,untagged},
252
{?R13,tagged},{?R13,untagged},
253
{?R14,tagged},{?R14,untagged},
254
{?R15,tagged},{?R15,untagged}
255
| fp_call_clobbered()]
257
[{?FCALLS,tagged},{?FCALLS,untagged},
258
{?HEAP_POINTER,tagged},{?HEAP_POINTER,untagged},
259
{?HEAP_LIMIT,tagged},{?HEAP_LIMIT,untagged}
262
fp_call_clobbered() -> %% sse2 since it has more registers than x87
263
[{Reg,double} || Reg <- allocatable_sse2()].
265
tailcall_clobbered() -> % tailcall crapola needs two temps
266
[{?TEMP0,tagged},{?TEMP0,untagged},
267
{?TEMP1,tagged},{?TEMP1,untagged}
268
| fp_call_clobbered()].
273
,{?PROC_POINTER,untagged}
275
,{?HEAP_LIMIT,untagged}
276
| ?LIST_HP_LIVE_AT_RETURN