1%%% Licensed under the Apache License, Version 2.0 (the "License"); 2%%% you may not use this file except in compliance with the License. 3%%% You may obtain a copy of the License at 4%%% 5%%% http://www.apache.org/licenses/LICENSE-2.0 6%%% 7%%% Unless required by applicable law or agreed to in writing, software 8%%% distributed under the License is distributed on an "AS IS" BASIS, 9%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10%%% See the License for the specific language governing permissions and 11%%% limitations under the License. 12%%% 13%%% TODO: 14%%% - Do we need a pseudo reg for the condition codes? 15 16-module(hipe_x86_registers). 17 18-export([reg_name/1, 19 first_virtual/0, 20 is_precoloured/1, 21 is_precoloured_x87/1, 22 all_precoloured/0, 23 eax/0, 24 ecx/0, 25 temp0/0, 26 temp1/0, 27 sp/0, 28 proc_pointer/0, 29 heap_limit/0, 30 fcalls/0, 31 proc_offset/1, 32 sp_limit_offset/0, 33 is_fixed/1, 34 %% fixed/0, 35 allocatable/0, 36 allocatable_x87/0, 37 nr_args/0, 38 arg/1, 39 is_arg/1, 40 args/1, 41 nr_rets/0, 42 ret/1, 43 call_clobbered/0, 44 tailcall_clobbered/0, 45 live_at_return/0, 46 float_size/0, 47 wordsize/0, 48 alignment/0]). 49 50-include("../rtl/hipe_literals.hrl"). 51 52-ifdef(X86_HP_IN_ESI). 53-export([heap_pointer/0]). 54-endif. 55 56-define(EAX, 0). 57-define(ECX, 1). 58-define(EDX, 2). 59-define(EBX, 3). 60-define(ESP, 4). 61-define(EBP, 5). 62-define(ESI, 6). 63-define(EDI, 7). 64-define(FCALLS, 8). % proc field alias 65-define(HEAP_LIMIT, 9). % proc field alias 66-define(LAST_PRECOLOURED, 9). 67 68-define(ARG0, ?EAX). 69-define(ARG1, ?EDX). 70-define(ARG2, ?ECX). 71-define(ARG3, ?EBX). 72-define(ARG4, ?EDI). 73 74-define(RET0, ?EAX). 75-define(RET1, ?EDX). 76-define(RET2, ?ECX). 77-define(RET3, ?EBX). 78-define(RET4, ?EDI). 79 80-define(TEMP0, ?EBX). % XXX: was EAX 81-define(TEMP1, ?EDI). % XXX: was EDX then EDI 82 83-define(PROC_POINTER, ?EBP). 84 85reg_name(R) -> 86 case R of 87 ?EAX -> "%eax"; 88 ?ECX -> "%ecx"; 89 ?EDX -> "%edx"; 90 ?EBX -> "%ebx"; 91 ?ESP -> "%esp"; 92 ?EBP -> "%ebp"; 93 ?ESI -> "%esi"; 94 ?EDI -> "%edi"; 95 ?FCALLS -> "%fcalls"; 96 ?HEAP_LIMIT -> "%hplim"; 97 Other -> "%r" ++ integer_to_list(Other) 98 end. 99 100first_virtual() -> ?LAST_PRECOLOURED + 1. 101 102is_precoloured(X) -> X =< ?LAST_PRECOLOURED. 103 104is_precoloured_x87(X) -> X =< 6. 105 106all_precoloured() -> 107 [?EAX, 108 ?ECX, 109 ?EDX, 110 ?EBX, 111 ?ESP, 112 ?EBP, 113 ?ESI, 114 ?EDI, 115 ?FCALLS, 116 ?HEAP_LIMIT]. 117 118eax() -> ?EAX. 119ecx() -> ?ECX. 120temp0() -> ?TEMP0. 121temp1() -> ?TEMP1. 122sp() -> ?ESP. 123proc_pointer() -> ?PROC_POINTER. 124fcalls() -> ?FCALLS. 125heap_limit() -> ?HEAP_LIMIT. 126 127-ifdef(X86_HP_IN_ESI). 128-define(ESI_IS_FIXED,1). 129-define(HEAP_POINTER, ?ESI). 130heap_pointer() -> ?HEAP_POINTER. 131is_heap_pointer(?HEAP_POINTER) -> true; 132is_heap_pointer(_) -> false. 133-define(LIST_HP_FIXED,[?HEAP_POINTER]). 134-define(LIST_HP_LIVE_AT_RETURN,[{?HEAP_POINTER,untagged}]). 135-else. 136is_heap_pointer(_) -> false. 137-define(LIST_HP_FIXED,[]). 138-define(LIST_HP_LIVE_AT_RETURN,[]). 139-endif. 140 141-ifdef(ESI_IS_FIXED). 142-define(LIST_ESI_ALLOCATABLE,[]). 143-define(LIST_ESI_CALL_CLOBBERED,[]). 144-else. 145-define(LIST_ESI_ALLOCATABLE,[?ESI]). 146-define(LIST_ESI_CALL_CLOBBERED,[{?ESI,tagged},{?ESI,untagged}]). 147-endif. 148 149proc_offset(?FCALLS) -> ?P_FCALLS; 150proc_offset(?HEAP_LIMIT) -> ?P_HP_LIMIT; 151proc_offset(_) -> false. 152 153sp_limit_offset() -> ?P_NSP_LIMIT. 154 155is_fixed(?ESP) -> true; 156is_fixed(?PROC_POINTER) -> true; 157is_fixed(?FCALLS) -> true; 158is_fixed(?HEAP_LIMIT) -> true; 159is_fixed(R) -> is_heap_pointer(R). 160 161%% fixed() -> 162%% [?ESP, ?PROC_POINTER, ?FCALLS, ?HEAP_LIMIT | ?LIST_HP_FIXED]. 163 164allocatable() -> 165 [?EDX, ?ECX, ?EBX, ?EAX, ?EDI| ?LIST_ESI_ALLOCATABLE]. 166 167allocatable_x87() -> 168 [0,1,2,3,4,5,6]. 169 170nr_args() -> ?X86_NR_ARG_REGS. 171 172arg(N) -> 173 if N < ?X86_NR_ARG_REGS -> 174 case N of 175 0 -> ?ARG0; 176 1 -> ?ARG1; 177 2 -> ?ARG2; 178 3 -> ?ARG3; 179 4 -> ?ARG4; 180 _ -> exit({?MODULE, arg, N}) 181 end; 182 true -> 183 exit({?MODULE, arg, N}) 184 end. 185 186is_arg(R) -> 187 case R of 188 ?ARG0 -> ?X86_NR_ARG_REGS > 0; 189 ?ARG1 -> ?X86_NR_ARG_REGS > 1; 190 ?ARG2 -> ?X86_NR_ARG_REGS > 2; 191 ?ARG3 -> ?X86_NR_ARG_REGS > 3; 192 ?ARG4 -> ?X86_NR_ARG_REGS > 4; 193 _ -> false 194 end. 195 196args(Arity) when is_integer(Arity), Arity >= 0 -> 197 N = erlang:min(Arity, ?X86_NR_ARG_REGS), 198 args(N-1, []). 199 200args(I, Rest) when I < 0 -> Rest; 201args(I, Rest) -> args(I-1, [arg(I) | Rest]). 202 203nr_rets() -> ?X86_NR_RET_REGS. 204 205ret(N) -> 206 if N < ?X86_NR_RET_REGS -> 207 case N of 208 0 -> ?RET0; 209 1 -> ?RET1; 210 2 -> ?RET2; 211 3 -> ?RET3; 212 4 -> ?RET4; 213 _ -> exit({?MODULE, ret, N}) 214 end; 215 true -> 216 exit({?MODULE, ret, N}) 217 end. 218 219%% Note: the fact that (allocatable() UNION allocatable_x87()) is a subset of 220%% call_clobbered() is hard-coded in hipe_x86_defuse:insn_defs_all/1 221call_clobbered() -> 222 [{?EAX,tagged},{?EAX,untagged}, % does the RA strip the type or not? 223 {?EDX,tagged},{?EDX,untagged}, 224 {?ECX,tagged},{?ECX,untagged}, 225 {?EBX,tagged},{?EBX,untagged}, 226 {?EDI,tagged},{?EDI,untagged} 227 | ?LIST_ESI_CALL_CLOBBERED] ++ all_x87_pseudos(). 228 229tailcall_clobbered() -> % tailcall crapola needs two temps 230 [{?TEMP0,tagged},{?TEMP0,untagged}, 231 {?TEMP1,tagged},{?TEMP1,untagged}] ++ all_x87_pseudos(). 232 233all_x87_pseudos() -> 234 [{0,double}, {1,double}, {2,double}, {3,double}, 235 {4,double}, {5,double}, {6,double}]. 236 237live_at_return() -> 238 [{?ESP,untagged} 239 ,{?PROC_POINTER,untagged} 240 ,{?FCALLS,untagged} 241 ,{?HEAP_LIMIT,untagged} 242 | ?LIST_HP_LIVE_AT_RETURN 243 ]. 244 245alignment() -> 4. 246 247float_size() -> 8. 248 249wordsize() -> 4. 250