1 (***********************************************************************)
5 (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
7 (* Copyright 1997 Institut National de Recherche en Informatique et *)
8 (* en Automatique. All rights reserved. This file is distributed *)
9 (* under the terms of the Q Public License version 1.0. *)
11 (***********************************************************************)
13 (* $Id: selection.ml 8768 2008-01-11 16:13:18Z doligez $ *)
15 (* Instruction selection for the HPPA processor *)
24 let shiftadd = function
28 | _ -> fatal_error "Proc_hppa.shiftadd"
30 class selector = object (self)
32 inherit Selectgen.selector_generic as super
34 method is_immediate n = (n < 16) && (n >= -16) (* 5 bits *)
36 method select_addressing = function
38 (Ibased(s, 0), Ctuple [])
39 | Cop(Cadda, [Cconst_symbol s; Cconst_int n]) ->
40 (Ibased(s, n), Ctuple [])
41 | Cop(Cadda, [arg; Cconst_int n]) ->
43 | Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int n])]) ->
44 (Iindexed n, Cop(Cadda, [arg1; arg2]))
48 method select_operation op args =
50 (* Recognize shift-add operations. *)
52 [arg2; Cop(Clsl, [arg1; Cconst_int(1|2|3 as shift)])]) ->
53 (Ispecific(shiftadd(1 lsl shift)), [arg1; arg2])
55 [arg2; Cop(Cmuli, [arg1; Cconst_int(2|4|8 as mult)])]) ->
56 (Ispecific(shiftadd mult), [arg1; arg2])
58 [arg2; Cop(Cmuli, [Cconst_int(2|4|8 as mult); arg1])]) ->
59 (Ispecific(shiftadd mult), [arg1; arg2])
60 | (Caddi, [Cop(Clsl, [arg1; Cconst_int(1|2|3 as shift)]); arg2]) ->
61 (Ispecific(shiftadd(1 lsl shift)), [arg1; arg2])
62 | (Caddi, [Cop(Cmuli, [arg1; Cconst_int(2|4|8 as mult)]); arg2]) ->
63 (Ispecific(shiftadd mult), [arg1; arg2])
64 | (Caddi, [Cop(Cmuli, [Cconst_int(2|4|8 as mult); arg1]); arg2]) ->
65 (Ispecific(shiftadd mult), [arg1; arg2])
66 (* Prevent the recognition of some immediate arithmetic operations *)
67 (* Cmuli : -> Ilsl if power of 2
68 Cdivi, Cmodi : only if power of 2
69 Cand, Cor, Cxor : never *)
70 | (Cmuli, ([arg1; Cconst_int n] as args)) ->
71 let l = Misc.log2 n in
73 then (Iintop_imm(Ilsl, l), [arg1])
74 else (Iintop Imul, args)
75 | (Cmuli, ([Cconst_int n; arg1] as args)) ->
76 let l = Misc.log2 n in
78 then (Iintop_imm(Ilsl, l), [arg1])
79 else (Iintop Imul, args)
80 | (Cmuli, args) -> (Iintop Imul, args)
81 | (Cdivi, [arg1; Cconst_int n]) when n = 1 lsl (Misc.log2 n) ->
82 (Iintop_imm(Idiv, n), [arg1])
83 | (Cdivi, args) -> (Iintop Idiv, args)
84 | (Cmodi, [arg1; Cconst_int n]) when n = 1 lsl (Misc.log2 n) ->
85 (Iintop_imm(Imod, n), [arg1])
86 | (Cmodi, args) -> (Iintop Imod, args)
87 | (Cand, args) -> (Iintop Iand, args)
88 | (Cor, args) -> (Iintop Ior, args)
89 | (Cxor, args) -> (Iintop Ixor, args)
91 super#select_operation op args
93 (* Deal with register constraints *)
95 method insert_op_debug op dbg rs rd =
97 Iintop(Idiv | Imod) -> (* handled via calls to millicode *)
98 let rs' = [|phys_reg 20; phys_reg 19|] (* %r26, %r25 *)
99 and rd' = [|phys_reg 22|] (* %r29 *) in
100 self#insert_moves rs rs';
101 self#insert_debug (Iop op) dbg rs' rd';
102 self#insert_moves rd' rd;
105 super#insert_op_debug op dbg rs rd
109 let fundecl f = (new selector)#emit_fundecl f