summaryrefslogtreecommitdiff
path: root/asmcomp/arm/scheduling.ml
blob: 9d847d4cef0c6826d85406d18f1ccc52667119f1 (plain)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(**************************************************************************)
(*                                                                        *)
(*                                 OCaml                                  *)
(*                                                                        *)
(*                 Benedikt Meurer, University of Siegen                  *)
(*                                                                        *)
(*   Copyright 1998 Institut National de Recherche en Informatique et     *)
(*     en Automatique.                                                    *)
(*   Copyright 2012 Benedikt Meurer.                                      *)
(*                                                                        *)
(*   All rights reserved.  This file is distributed under the terms of    *)
(*   the GNU Lesser General Public License version 2.1, with the          *)
(*   special exception on linking described in the file LICENSE.          *)
(*                                                                        *)
(**************************************************************************)

open Arch
open Mach

(* Instruction scheduling for the ARM *)

class scheduler = object

inherit Schedgen.scheduler_generic as super

(* Scheduling -- based roughly on the ARM11 (ARMv6) *)

method oper_latency = function
  (* Loads have a latency of two cycles in general *)
    Iconst_symbol _
  | Iconst_float _
  | Iload(_, _)
  | Ireload
  | Ifloatofint       (* mcr/mrc count as memory access *)
  | Iintoffloat -> 2
  (* Multiplys have a latency of two cycles *)
  | Iintop (Imul | Imulh)
  | Ispecific(Imuladd | Imulsub | Imulhadd) -> 2
  (* VFP instructions *)
  | Iaddf
  | Isubf
  | Idivf
  | Imulf | Ispecific Inegmulf
  | Ispecific(Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf)
  | Ispecific Isqrtf
  | Inegf | Iabsf when !fpu >= VFPv2 -> 2
  (* Everything else *)
  | _ -> 1

method! is_checkbound = function
    Ispecific(Ishiftcheckbound _) -> true
  | op -> super#is_checkbound op

(* Issue cycles. Rough approximations *)

method oper_issue_cycles = function
    Ialloc _ -> 4
  | Iintop(Ilsl | Ilsr | Iasr) -> 2
  | Iintop(Icomp _)
  | Iintop_imm(Icomp _, _) -> 3
  | Iintop(Icheckbound)
  | Iintop_imm(Icheckbound, _) -> 2
  | Ispecific(Ishiftcheckbound _) -> 3
  | Iintop(Imul | Imulh)
  | Ispecific(Imuladd | Imulsub | Imulhadd) -> 2
  (* VFP instructions *)
  | Iaddf
  | Isubf -> 7
  | Imulf
  | Ispecific Inegmulf -> 9
  | Ispecific(Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf) -> 17
  | Idivf
  | Ispecific Isqrtf -> 27
  | Inegf | Iabsf | Iconst_float _ when !fpu >= VFPv2 -> 4
  (* Everything else *)
  | _ -> 1

end

let fundecl f = (new scheduler)#schedule_fundecl f