aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/ppc/hipe_ppc_registers.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/ppc/hipe_ppc_registers.erl')
-rw-r--r--lib/hipe/ppc/hipe_ppc_registers.erl246
1 files changed, 246 insertions, 0 deletions
diff --git a/lib/hipe/ppc/hipe_ppc_registers.erl b/lib/hipe/ppc/hipe_ppc_registers.erl
new file mode 100644
index 0000000000..74aeab3df4
--- /dev/null
+++ b/lib/hipe/ppc/hipe_ppc_registers.erl
@@ -0,0 +1,246 @@
+%% -*- erlang-indent-level: 2 -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(hipe_ppc_registers).
+
+-export([reg_name_gpr/1,
+ reg_name_fpr/1,
+ first_virtual/0,
+ is_precoloured_gpr/1,
+ is_precoloured_fpr/1,
+ all_precoloured/0,
+ return_value/0,
+ temp1/0,
+ temp2/0,
+ temp3/0, % for base2 in storeix :-(
+ heap_pointer/0,
+ stack_pointer/0,
+ proc_pointer/0,
+ %%heap_limit/0,
+ %%fcalls/0,
+ allocatable_gpr/0,
+ allocatable_fpr/0,
+ is_fixed/1,
+ nr_args/0,
+ arg/1,
+ args/1,
+ is_arg/1, % for linear scan
+ call_clobbered/0,
+ tailcall_clobbered/0,
+ live_at_return/0
+ ]).
+
+-include("../rtl/hipe_literals.hrl").
+
+-define(R0, 0).
+-define(R1, 1).
+-define(R2, 2).
+-define(R3, 3).
+-define(R4, 4).
+-define(R5, 5).
+-define(R6, 6).
+-define(R7, 7).
+-define(R8, 8).
+-define(R9, 9).
+-define(R10, 10).
+-define(R11, 11).
+-define(R12, 12).
+-define(R13, 13).
+-define(R14, 14).
+-define(R15, 15).
+-define(R16, 16).
+-define(R17, 17).
+-define(R18, 18).
+-define(R19, 19).
+-define(R20, 20).
+-define(R21, 21).
+-define(R22, 22).
+-define(R23, 23).
+-define(R24, 24).
+-define(R25, 25).
+-define(R26, 26).
+-define(R27, 27).
+-define(R28, 28).
+-define(R29, 29).
+-define(R30, 30).
+-define(R31, 31).
+-define(LAST_PRECOLOURED, 31). % must handle both GPR and FPR ranges
+
+-define(ARG0, ?R4).
+-define(ARG1, ?R5).
+-define(ARG2, ?R6).
+-define(ARG3, ?R7).
+-define(ARG4, ?R8).
+-define(ARG5, ?R9).
+-define(ARG6, ?R10).
+
+-define(TEMP1, ?R28).
+-define(TEMP2, ?R27).
+-define(TEMP3, ?R26). % XXX: for base2 in storeix, switch to R0 instead?
+
+-define(RETURN_VALUE, ?R3).
+-define(HEAP_POINTER, ?R29).
+-define(STACK_POINTER, ?R30).
+-define(PROC_POINTER, ?R31).
+
+reg_name_gpr(R) -> [$r | integer_to_list(R)].
+reg_name_fpr(R) -> [$f | integer_to_list(R)].
+
+%%% Must handle both GPR and FPR ranges.
+first_virtual() -> ?LAST_PRECOLOURED + 1.
+
+%%% These two tests have the same implementation, but that's
+%%% not something we should cast in stone in the interface.
+is_precoloured_gpr(R) -> R =< ?LAST_PRECOLOURED.
+is_precoloured_fpr(R) -> R =< ?LAST_PRECOLOURED.
+
+all_precoloured() ->
+ %% XXX: skip R1, R2, and R13. They should never occur anywhere.
+ [ ?R0, ?R1, ?R2, ?R3, ?R4, ?R5, ?R6, ?R7,
+ ?R8, ?R9, ?R10, ?R11, ?R12, ?R13, ?R14, ?R15,
+ ?R16, ?R17, ?R18, ?R19, ?R20, ?R21, ?R22, ?R23,
+ ?R24, ?R25, ?R26, ?R27, ?R28, ?R29, ?R30, ?R31].
+
+return_value() -> ?RETURN_VALUE.
+
+temp1() -> ?TEMP1.
+temp2() -> ?TEMP2.
+temp3() -> ?TEMP3. % for base2 in storeix :-(
+
+heap_pointer() -> ?HEAP_POINTER.
+
+stack_pointer() -> ?STACK_POINTER.
+
+proc_pointer() -> ?PROC_POINTER.
+
+allocatable_gpr() ->
+ %% r0 is too restricted to be useful for variables
+ %% r1, r2, and r13 are reserved for C
+ %% r29, r30, and r31 are fixed global registers
+ [ ?R3, ?R4, ?R5, ?R6, ?R7,
+ ?R8, ?R9, ?R10, ?R11, ?R12, ?R14, ?R15,
+ ?R16, ?R17, ?R18, ?R19, ?R20, ?R21, ?R22, ?R23,
+ ?R24, ?R25, ?R26, ?R27, ?R28].
+
+allocatable_fpr() ->
+ [ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31].
+
+%% Needed for hipe_graph_coloring_regalloc.
+%% Presumably true for Reg in AllPrecoloured \ Allocatable.
+is_fixed(Reg) ->
+ case Reg of
+ ?HEAP_POINTER -> true;
+ ?STACK_POINTER -> true;
+ ?PROC_POINTER -> true;
+ %% The following cases are required for linear scan:
+ %% it gets confused if it sees a register which is
+ %% neither allocatable nor global (fixed or one of
+ %% the scratch registers set aside for linear scan).
+ ?R0 -> true;
+ ?R1 -> true;
+ ?R2 -> true;
+ ?R13 -> true;
+ _ -> false
+ end.
+
+nr_args() -> ?PPC_NR_ARG_REGS.
+
+args(Arity) when is_integer(Arity) ->
+ N = erlang:min(Arity, ?PPC_NR_ARG_REGS),
+ args(N-1, []).
+
+args(I, Rest) when is_integer(I), I < 0 -> Rest;
+args(I, Rest) -> args(I-1, [arg(I) | Rest]).
+
+arg(N) ->
+ if N < ?PPC_NR_ARG_REGS ->
+ case N of
+ 0 -> ?ARG0;
+ 1 -> ?ARG1;
+ 2 -> ?ARG2;
+ 3 -> ?ARG3;
+ 4 -> ?ARG4;
+ 5 -> ?ARG5;
+ 6 -> ?ARG6;
+ _ -> exit({?MODULE, arg, N})
+ end;
+ true ->
+ exit({?MODULE, arg, N})
+ end.
+
+is_arg(R) ->
+ case R of
+ ?ARG0 -> ?PPC_NR_ARG_REGS > 0;
+ ?ARG1 -> ?PPC_NR_ARG_REGS > 1;
+ ?ARG2 -> ?PPC_NR_ARG_REGS > 2;
+ ?ARG3 -> ?PPC_NR_ARG_REGS > 3;
+ ?ARG4 -> ?PPC_NR_ARG_REGS > 4;
+ ?ARG5 -> ?PPC_NR_ARG_REGS > 5;
+ ?ARG6 -> ?PPC_NR_ARG_REGS > 6;
+ _ -> false
+ end.
+
+call_clobbered() -> % does the RA strip the type or not?
+ [{?R0,tagged},{?R0,untagged},
+ %% R1 is reserved for C
+ %% R2 is reserved for C
+ {?R3,tagged},{?R3,untagged},
+ {?R4,tagged},{?R4,untagged},
+ {?R5,tagged},{?R5,untagged},
+ {?R6,tagged},{?R6,untagged},
+ {?R7,tagged},{?R7,untagged},
+ {?R8,tagged},{?R8,untagged},
+ {?R9,tagged},{?R9,untagged},
+ {?R10,tagged},{?R10,untagged},
+ {?R11,tagged},{?R11,untagged},
+ {?R12,tagged},{?R12,untagged},
+ %% R13 is reserved for C
+ {?R14,tagged},{?R14,untagged},
+ {?R15,tagged},{?R15,untagged},
+ {?R16,tagged},{?R16,untagged},
+ {?R17,tagged},{?R17,untagged},
+ {?R18,tagged},{?R18,untagged},
+ {?R19,tagged},{?R19,untagged},
+ {?R20,tagged},{?R20,untagged},
+ {?R21,tagged},{?R21,untagged},
+ {?R22,tagged},{?R22,untagged},
+ {?R23,tagged},{?R23,untagged},
+ {?R24,tagged},{?R24,untagged},
+ {?R25,tagged},{?R25,untagged},
+ {?R26,tagged},{?R26,untagged},
+ {?R27,tagged},{?R27,untagged},
+ {?R28,tagged},{?R28,untagged}
+ %% R29 is fixed (HP)
+ %% R30 is fixed (NSP)
+ %% R31 is fixed (P)
+ ].
+
+tailcall_clobbered() -> % tailcall crapola needs one temp
+ [{?TEMP1,tagged},{?TEMP1,untagged}].
+
+live_at_return() ->
+ [%%{?LR,untagged},
+ {?HEAP_POINTER,untagged},
+ {?STACK_POINTER,untagged},
+ {?PROC_POINTER,untagged}
+ ].