aboutsummaryrefslogblamecommitdiffstats
path: root/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
blob: 5654455b44d938cdf741759a6f90c22d00cbb398 (plain) (tree)














































































































































































                                                                                
%% -*- 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_amd64_specific_sse2).

-export([number_of_temporaries/1]).

% The following exports are used as M:F(...) calls from other modules;
%% e.g. hipe_amd64_ra_ls.
-export([analyze/1,
         bb/2,
         args/1,
         labels/1,
         livein/2,
         liveout/2,
         uses/1,
         defines/1,
	 def_use/1,
	 is_arg/1,	%% used by hipe_ls_regalloc
	 is_move/1,
	 is_fixed/1,	%% used by hipe_graph_coloring_regalloc
         is_global/1,
	 is_precoloured/1,
         reg_nr/1,
	 non_alloc/1,
	 allocatable/0,
         physical_name/1,
	 all_precoloured/0,
	 new_spill_index/1,	%% used by hipe_ls_regalloc
	 var_range/1,
         breadthorder/1,
         postorder/1,
         reverse_postorder/1]).

%% callbacks for hipe_regalloc_loop
-export([defun_to_cfg/1,
	 check_and_rewrite/2]).

%%----------------------------------------------------------------------------

-include("../flow/cfg.hrl").

%%----------------------------------------------------------------------------

defun_to_cfg(Defun) ->
  hipe_x86_cfg:init(Defun).

check_and_rewrite(Defun, Coloring) ->
  hipe_amd64_ra_sse2_postconditions:check_and_rewrite(Defun, Coloring).

reverse_postorder(CFG) ->
  hipe_x86_cfg:reverse_postorder(CFG).

breadthorder(CFG) ->
  hipe_x86_cfg:breadthorder(CFG).

postorder(CFG) ->
  hipe_x86_cfg:postorder(CFG).

is_global(_Reg) ->
  false.
 
is_fixed(_Reg) ->
  false.

is_arg(_Reg) ->
  false.

-spec args(#cfg{}) -> [].
args(_CFG) ->
  [].
 
non_alloc(_) ->
  [].

%% Liveness stuff

analyze(CFG) ->
  hipe_amd64_liveness:analyze(CFG).

livein(Liveness, L) ->
  [X || X <- hipe_amd64_liveness:livein(Liveness, L),
 	     hipe_x86:temp_is_allocatable(X),
	     hipe_x86:temp_type(X) =:= 'double'].

liveout(BB_in_out_liveness, Label) ->
  [X || X <- hipe_amd64_liveness:liveout(BB_in_out_liveness, Label),
 	     hipe_x86:temp_is_allocatable(X),
	     hipe_x86:temp_type(X) =:= 'double'].

%% Registers stuff

allocatable() ->
  hipe_amd64_registers:allocatable_sse2().

all_precoloured() ->
  allocatable().

is_precoloured(Reg) ->
  lists:member(Reg,all_precoloured()).

physical_name(Reg) ->
  Reg.

%% CFG stuff

labels(CFG) ->
  hipe_x86_cfg:labels(CFG).

var_range(_CFG) ->
  hipe_gensym:var_range(x86).

-spec number_of_temporaries(#cfg{}) -> non_neg_integer().
number_of_temporaries(_CFG) ->
  Highest_temporary = hipe_gensym:get_var(x86),
  %% Since we can have temps from 0 to Max adjust by +1.
  Highest_temporary + 1.

bb(CFG, L) ->
  hipe_x86_cfg:bb(CFG, L).

%% AMD64 stuff

def_use(Instruction) ->
  {[X || X <- hipe_amd64_defuse:insn_def(Instruction), 
 	   hipe_x86:temp_is_allocatable(X),
 	   hipe_x86:temp_type(X) =:= 'double'],
   [X || X <- hipe_amd64_defuse:insn_use(Instruction), 
 	   hipe_x86:temp_is_allocatable(X),
	   hipe_x86:temp_type(X) =:= 'double']
  }.

uses(I) ->
  [X || X <- hipe_amd64_defuse:insn_use(I),
 	     hipe_x86:temp_is_allocatable(X),
 	     hipe_x86:temp_type(X) =:= 'double'].

defines(I) ->
  [X || X <- hipe_amd64_defuse:insn_def(I),
	     hipe_x86:temp_is_allocatable(X),
	     hipe_x86:temp_type(X) =:= 'double'].

is_move(Instruction) ->
  case hipe_x86:is_fmove(Instruction) of
    true ->
      Src = hipe_x86:fmove_src(Instruction),
      Dst = hipe_x86:fmove_dst(Instruction),
      hipe_x86:is_temp(Src) andalso hipe_x86:temp_is_allocatable(Src)
	andalso hipe_x86:is_temp(Dst) andalso hipe_x86:temp_is_allocatable(Dst);
    false -> false
  end.
 
reg_nr(Reg) ->
  hipe_x86:temp_reg(Reg).

-spec new_spill_index(non_neg_integer()) -> pos_integer().
new_spill_index(SpillIndex) when is_integer(SpillIndex) ->
  SpillIndex + 1.