summaryrefslogtreecommitdiff
path: root/asmcomp/power
diff options
context:
space:
mode:
Diffstat (limited to 'asmcomp/power')
-rw-r--r--asmcomp/power/CSE.ml38
-rw-r--r--asmcomp/power/emit.mlp19
-rw-r--r--asmcomp/power/proc.ml11
-rw-r--r--asmcomp/power/scheduling.ml2
4 files changed, 59 insertions, 11 deletions
diff --git a/asmcomp/power/CSE.ml b/asmcomp/power/CSE.ml
new file mode 100644
index 0000000000..50fefa5e35
--- /dev/null
+++ b/asmcomp/power/CSE.ml
@@ -0,0 +1,38 @@
+(***********************************************************************)
+(* *)
+(* OCaml *)
+(* *)
+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2014 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* CSE for the PowerPC *)
+
+open Arch
+open Mach
+open CSEgen
+
+class cse = object (self)
+
+inherit cse_generic as super
+
+method! class_of_operation op =
+ match op with
+ | Ispecific(Imultaddf | Imultsubf) -> Op_pure
+ | Ispecific(Ialloc_far _) -> Op_other
+ | _ -> super#class_of_operation op
+
+method! is_cheap_operation op =
+ match op with
+ | Iconst_int n | Iconst_blockheader n -> n <= 32767n && n >= -32768n
+ | _ -> false
+
+end
+
+let fundecl f =
+ (new cse)#fundecl f
+
diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp
index f6ee1a2321..0a26ed1479 100644
--- a/asmcomp/power/emit.mlp
+++ b/asmcomp/power/emit.mlp
@@ -229,7 +229,7 @@ let record_frame live dbg =
(* Record floating-point and large integer literals *)
-let float_literals = ref ([] : (string * int) list)
+let float_literals = ref ([] : (int64 * int) list)
let int_literals = ref ([] : (nativeint * int) list)
(* Record external C functions to be called in a position-independent way
@@ -333,7 +333,7 @@ let instr_size = function
if chunk = Byte_signed
then load_store_size addr + 1
else load_store_size addr
- | Lop(Istore(chunk, addr)) -> load_store_size addr
+ | Lop(Istore(chunk, addr, _)) -> load_store_size addr
| Lop(Ialloc n) -> 4
| Lop(Ispecific(Ialloc_far n)) -> 5
| Lop(Iintop Imod) -> 3
@@ -466,9 +466,9 @@ let rec emit_instr i dslot =
` addis {emit_gpr 11}, 0, {emit_upper emit_label lbl}\n`;
` {emit_string lg} {emit_reg i.res.(0)}, {emit_lower emit_label lbl}({emit_gpr 11})\n`
end
- | Lop(Iconst_float s) ->
+ | Lop(Iconst_float f) ->
let lbl = new_label() in
- float_literals := (s, lbl) :: !float_literals;
+ float_literals := (Int64.bits_of_float f, lbl) :: !float_literals;
` addis {emit_gpr 11}, 0, {emit_upper emit_label lbl}\n`;
` lfd {emit_reg i.res.(0)}, {emit_lower emit_label lbl}({emit_gpr 11})\n`
| Lop(Iconst_symbol s) ->
@@ -548,7 +548,7 @@ let rec emit_instr i dslot =
emit_load_store loadinstr addr i.arg 0 i.res.(0);
if chunk = Byte_signed then
` extsb {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n`
- | Lop(Istore(chunk, addr)) ->
+ | Lop(Istore(chunk, addr, _)) ->
let storeinstr =
match chunk with
Byte_unsigned | Byte_signed -> "stb"
@@ -628,8 +628,7 @@ let rec emit_instr i dslot =
` fcfid {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n`
end else begin
let lbl = new_label() in
- float_literals := ("4.503601774854144e15", lbl) :: !float_literals;
- (* That float above represents 0x4330000080000000 *)
+ float_literals := (0x4330000080000000L, lbl) :: !float_literals;
` addis {emit_gpr 11}, 0, {emit_upper emit_label lbl}\n`;
` lfd {emit_fpr 0}, {emit_lower emit_label lbl}({emit_gpr 11})\n`;
` lis {emit_gpr 0}, 0x4330\n`;
@@ -899,11 +898,11 @@ let emit_item = function
| Cint n ->
` {emit_string datag} {emit_nativeint n}\n`
| Csingle f ->
- emit_float32_directive ".long" f
+ emit_float32_directive ".long" (Int32.bits_of_float f)
| Cdouble f ->
if ppc64
- then emit_float64_directive ".quad" f
- else emit_float64_split_directive ".long" f
+ then emit_float64_directive ".quad" (Int64.bits_of_float f)
+ else emit_float64_split_directive ".long" (Int64.bits_of_float f)
| Csymbol_address s ->
` {emit_string datag} {emit_symbol s}\n`
| Clabel_address lbl ->
diff --git a/asmcomp/power/proc.ml b/asmcomp/power/proc.ml
index 203e8a9ef4..77e37deda0 100644
--- a/asmcomp/power/proc.ml
+++ b/asmcomp/power/proc.ml
@@ -224,6 +224,17 @@ let max_register_pressure = function
Iextcall(_, _) -> [| 15; 18 |]
| _ -> [| 23; 30 |]
+(* Pure operations (without any side effect besides updating their result
+ registers). *)
+
+let op_is_pure = function
+ | Icall_ind | Icall_imm _ | Itailcall_ind | Itailcall_imm _
+ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _
+ | Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false
+ | Ispecific(Imultaddf | Imultsubf) -> true
+ | Ispecific _ -> false
+ | _ -> true
+
(* Layout of the stack *)
let num_stack_slots = [| 0; 0 |]
diff --git a/asmcomp/power/scheduling.ml b/asmcomp/power/scheduling.ml
index 6e594f0283..7adaa2eed3 100644
--- a/asmcomp/power/scheduling.ml
+++ b/asmcomp/power/scheduling.ml
@@ -44,7 +44,7 @@ method reload_retaddr_latency = 12
method oper_issue_cycles = function
Iconst_float _ | Iconst_symbol _ -> 2
| Iload(_, Ibased(_, _)) -> 2
- | Istore(_, Ibased(_, _)) -> 2
+ | Istore(_, Ibased(_, _), _) -> 2
| Ialloc _ -> 4
| Iintop(Imod) -> 40 (* assuming full stall *)
| Iintop(Icomp _) -> 4