summaryrefslogtreecommitdiff
path: root/asmcomp
diff options
context:
space:
mode:
authorJérémie Dimino <jeremie@dimino.org>2015-08-25 16:18:54 +0000
committerJérémie Dimino <jeremie@dimino.org>2015-08-25 16:18:54 +0000
commit766a5adf414c19c42be34222b7f85203989d0dce (patch)
tree23765ca7a128c8060ae0867f5f95963dbbbad97a /asmcomp
parentb3cf02c1ef8fb7af9d0d601f2ed5881c28915e55 (diff)
downloadocaml-766a5adf414c19c42be34222b7f85203989d0dce.tar.gz
Update sparc backend for unboxed primitive arguments/results
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16391 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'asmcomp')
-rw-r--r--asmcomp/sparc/emit.mlp11
-rw-r--r--asmcomp/sparc/proc.ml45
2 files changed, 41 insertions, 15 deletions
diff --git a/asmcomp/sparc/emit.mlp b/asmcomp/sparc/emit.mlp
index b849a12f2c..0189614458 100644
--- a/asmcomp/sparc/emit.mlp
+++ b/asmcomp/sparc/emit.mlp
@@ -290,7 +290,16 @@ let rec emit_instr i dslot =
` sub %sp, 8, %sp\n`;
` std {emit_reg src}, [%sp + 96]\n`;
` ld [%sp + 96], {emit_reg dst}\n`;
- ` ld [%sp + 100], {emit_reg(next_in_pair dst)}\n`;
+ let dst2 = i.res.(1) in
+ begin match dst2 with
+ | {loc = Reg _; typ = Int} ->
+ ` ld [%sp + 100], {emit_reg dst2}\n`;
+ | {loc = Stack _; typ = Int} ->
+ ` ld [%sp + 100], %g1\n`;
+ ` st %g1, {emit_stack dst2}\n`;
+ | _ ->
+ fatal_error "Emit: Imove Float [| _; _ |]"
+ end;
` add %sp, 8, %sp\n`
| {loc = Reg rs; typ = (Int | Addr)}, {loc = Stack sd} ->
` st {emit_reg src}, {emit_stack dst}\n`
diff --git a/asmcomp/sparc/proc.ml b/asmcomp/sparc/proc.ml
index 9ba01bfabe..f34a987290 100644
--- a/asmcomp/sparc/proc.ml
+++ b/asmcomp/sparc/proc.ml
@@ -144,29 +144,46 @@ let loc_results res =
are passed in %o0..%o5, then on the stack *)
let loc_external_arguments arg =
- let loc = ref [] in
+ let loc = Array.make (Array.length arg) [| |] in
let reg = ref 0 (* %o0 *) in
let ofs = ref (-4) in (* start at sp + 92 = sp + 96 - 4 *)
- for i = 0 to Array.length arg - 1 do
+ let next_loc typ =
if !reg <= 5 (* %o5 *) then begin
- match arg.(i).typ with
- | Val | Int | Addr ->
- loc := phys_reg !reg :: !loc;
- incr reg
- | Float ->
- if !reg = 5 then fatal_error "Proc_sparc: cannot call";
- loc := phys_reg (!reg + 1) :: phys_reg !reg :: !loc;
- reg := !reg + 2
+ assert (size_component typ = size_int);
+ let loc = phys_reg !reg in
+ incr reg;
+ loc
end else begin
- loc := stack_slot (outgoing !ofs) arg.(i).typ :: !loc;
- ofs := !ofs + size_component arg.(i).typ
+ let loc = stack_slot (outgoing !ofs) typ in
+ ofs := !ofs + size_component typ;
+ loc
end
+ in
+ for i = 0 to Array.length arg - 1 do
+ match arg.(i) with
+ | [| { typ = (Val | Int | Addr as typ) } |] ->
+ loc.(i) <- [| next_loc typ |]
+ | [| { typ = Float } |] ->
+ if !reg <= 5 then begin
+ let loc1 = next_loc Int in
+ let loc2 = next_loc Int in
+ loc.(i) <- [| loc1; loc2 |]
+ end else
+ loc.(i) <- [| next_loc Float |]
+ | [| { typ = Int }; { typ = Int } |] ->
+ (* int64 unboxed *)
+ let loc1 = next_loc Int in
+ let loc2 = next_loc Int in
+ assert big_endian;
+ loc.(i) <- [| loc2; loc1 |]
+ | _ ->
+ fatal_error "Proc.loc_external_arguments: cannot call"
done;
(* Keep stack 8-aligned *)
- (Array.of_list(List.rev !loc), Misc.align (!ofs + 4) 8)
+ (loc, Misc.align (!ofs + 4) 8)
let loc_external_results res =
- let (loc, ofs) = calling_conventions 0 0 100 100 not_supported res in loc
+ let (loc, ofs) = calling_conventions 0 1 100 100 not_supported res in loc
let loc_exn_bucket = phys_reg 0 (* $o0 *)