]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ocaml/contrib/asmcomp/hppa/selection.ml
update
[l4.git] / l4 / pkg / ocaml / contrib / asmcomp / hppa / selection.ml
1 (***********************************************************************)
2 (*                                                                     *)
3 (*                           Objective Caml                            *)
4 (*                                                                     *)
5 (*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         *)
6 (*                                                                     *)
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.               *)
10 (*                                                                     *)
11 (***********************************************************************)
12
13 (* $Id: selection.ml 8768 2008-01-11 16:13:18Z doligez $ *)
14
15 (* Instruction selection for the HPPA processor *)
16
17 open Misc
18 open Cmm
19 open Reg
20 open Arch
21 open Proc
22 open Mach
23
24 let shiftadd = function
25     2 -> Ishift1add
26   | 4 -> Ishift2add
27   | 8 -> Ishift3add
28   | _ -> fatal_error "Proc_hppa.shiftadd"
29
30 class selector = object (self)
31
32 inherit Selectgen.selector_generic as super
33
34 method is_immediate n = (n < 16) && (n >= -16) (* 5 bits *)
35
36 method select_addressing = function
37     Cconst_symbol s ->
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]) ->
42       (Iindexed n, arg)
43   | Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int n])]) ->
44       (Iindexed n, Cop(Cadda, [arg1; arg2]))
45   | arg ->
46       (Iindexed 0, arg)
47
48 method select_operation op args =
49   match (op, args) with
50   (* Recognize shift-add operations. *)
51     ((Caddi|Cadda),
52      [arg2; Cop(Clsl, [arg1; Cconst_int(1|2|3 as shift)])]) ->
53       (Ispecific(shiftadd(1 lsl shift)), [arg1; arg2])
54   | ((Caddi|Cadda),
55      [arg2; Cop(Cmuli, [arg1; Cconst_int(2|4|8 as mult)])]) ->
56       (Ispecific(shiftadd mult), [arg1; arg2])
57   | ((Caddi|Cadda),
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
72       if n = 1 lsl l 
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
77       if n = 1 lsl l
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)
90   | _ ->
91       super#select_operation op args
92
93 (* Deal with register constraints *)
94
95 method insert_op_debug op dbg rs rd =
96   match op with
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;
103       rd
104   | _ ->
105       super#insert_op_debug op dbg rs rd
106
107 end
108
109 let fundecl f = (new selector)#emit_fundecl f