diff options
Diffstat (limited to 'lib/hipe/ppc/hipe_ppc_registers.erl')
-rw-r--r-- | lib/hipe/ppc/hipe_ppc_registers.erl | 246 |
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} + ]. |