summaryrefslogtreecommitdiffstats
path: root/asmcomp/alpha
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>1998-08-13 09:02:43 +0000
committerXavier Leroy <xavier.leroy@inria.fr>1998-08-13 09:02:43 +0000
commitfe0a2ee8928e3fa8c4cf4bbbceb275c1f354ac29 (patch)
treec59f29c9f2dba62d455f895ac9ba89729a2be109 /asmcomp/alpha
parentc239015c1368574175c9a8df32bcd89739c84228 (diff)
Retour a la strategie standard de gestion du
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2048 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'asmcomp/alpha')
-rw-r--r--asmcomp/alpha/emit.mlp95
1 files changed, 54 insertions, 41 deletions
diff --git a/asmcomp/alpha/emit.mlp b/asmcomp/alpha/emit.mlp
index 1b163098e..fcd153698 100644
--- a/asmcomp/alpha/emit.mlp
+++ b/asmcomp/alpha/emit.mlp
@@ -11,11 +11,11 @@
(* $Id$ *)
-(* Emission of Alpha assembly code *)
-
module LabelSet =
Set.Make(struct type t = Linearize.label let compare = compare end)
+(* Emission of Alpha assembly code *)
+
open Misc
open Cmm
open Arch
@@ -27,8 +27,11 @@ open Emitaux
(* First pass: insert Iloadgp instructions where needed *)
-let instr_copy i next =
- { desc = i.desc; next = next; arg = i.arg; res = i.res; live = i.live }
+let multiple_gp =
+ match Config.system with
+ "digital" -> true
+ | "linux" -> false
+ | _ -> assert false
let insert_load_gp f =
@@ -59,11 +62,11 @@ let insert_load_gp f =
| Lop(Iconst_float s) -> true (* turned into ldq ($gp) *)
| Lop(Iconst_symbol s) -> true (* turned into ldq ($gp) *)
| Lop(Icall_ind) -> false (* does ldgp if needed afterwards *)
- | Lop(Icall_imm s) -> false (* does ldgp if needed afterwards *)
+ | Lop(Icall_imm s) -> true (* does lda $27, <s> *)
| Lop(Itailcall_ind) -> false
| Lop(Itailcall_imm s) ->
- if s = f.fun_name then label_needs_gp tailrec_entry_point else false
- | Lop(Iextcall(_, _)) -> true (* loads $27 from ($gp) *)
+ if s = f.fun_name then label_needs_gp tailrec_entry_point else true
+ | Lop(Iextcall(_, _)) -> true (* does lda $27, <s> *)
| Lop(Iload(_, Ibased(_, _))) -> true (* loads address from ($gp) *)
| Lop(Istore(_, Ibased(_, _))) -> true (* loads address from ($gp) *)
| Lop(Iintop(Idiv | Imod)) -> true (* divq and remq can be turned into *)
@@ -105,19 +108,18 @@ let insert_load_gp f =
(* If the instruction destroys $gp and $gp is needed afterwards,
insert a ldgp after the instructions. *)
Lop(Icall_ind | Icall_imm _) when needs_next ->
- instr_copy i
- (instr_cons (Lop(Ispecific(Ireloadgp true))) [||] [||] new_next)
+ {i with next =
+ instr_cons (Lop(Ispecific(Ireloadgp true))) [||] [||] new_next }
| Lop(Iextcall(_, false)) | Lsetuptrap _ when needs_next ->
- instr_copy i
- (instr_cons (Lop(Ispecific(Ireloadgp false))) [||] [||] new_next)
+ {i with next =
+ instr_cons (Lop(Ispecific(Ireloadgp false))) [||] [||] new_next }
| _ ->
- instr_copy i new_next in
+ {i with next = new_next} in
(new_instr, instr_needs_gp needs_next i.desc)
end in
let (new_body, uses_gp) = insert_reload_gp f.fun_body in
- ({fun_body = new_body; fun_name = f.fun_name; fun_fast = f.fun_fast},
- uses_gp)
+ ({f with fun_body = new_body}, uses_gp)
(* Second pass: code generation proper *)
@@ -246,7 +248,7 @@ let record_frame live =
let lbl = record_frame_label live in `{emit_label lbl}:`
let emit_frame fd =
- ` .quad {emit_label fd.fd_lbl} + 4\n`;
+ ` .quad {emit_label fd.fd_lbl}\n`;
` .word {emit_int fd.fd_frame_size}\n`;
` .word {emit_int (List.length fd.fd_live_offset)}\n`;
List.iter
@@ -268,9 +270,9 @@ let call_gc_sites = ref ([] : gc_call list)
let emit_call_gc gc =
`{emit_label gc.gc_lbl}:`;
liveregs gc.gc_instr 0;
- `{emit_label gc.gc_frame}: bsr $26, caml_call_gc\n`;
+ ` bsr $26, caml_call_gc\n`;
(* caml_call_gc preserves $gp *)
- ` br {emit_label gc.gc_return_lbl}\n`
+ `{emit_label gc.gc_frame}: br {emit_label gc.gc_return_lbl}\n`
(* Name of readonly data section *)
@@ -403,17 +405,26 @@ let emit_instr i =
` lda {emit_reg i.res.(0)}, {emit_symbol s}\n`
| Lop(Icall_ind) ->
liveregs i 0;
- `{record_frame i.live} jsr ({emit_reg i.arg.(0)})\n`
+ if multiple_gp then
+ ` mov {emit_reg i.arg.(0)}, $27\n`;
+ ` jsr ({emit_reg i.arg.(0)})\n`;
+ `{record_frame i.live}\n`
| Lop(Icall_imm s) ->
liveregs i 0;
- `{record_frame i.live} bsr $26, {emit_symbol s}\n`
+ if multiple_gp then
+ ` jsr {emit_symbol s}\n`
+ else
+ ` bsr $26, {emit_symbol s}\n`;
+ `{record_frame i.live}\n`
| Lop(Itailcall_ind) ->
let n = frame_size() in
if !contains_calls then
` ldq $26, {emit_int(n - 8)}($sp)\n`;
if n > 0 then
` lda $sp, {emit_int n}($sp)\n`;
- liveregs i live_26;
+ if multiple_gp then
+ ` mov {emit_reg i.arg.(0)}, $27\n`;
+ liveregs i (live_26 + live_27);
` jmp ({emit_reg i.arg.(0)})\n`
| Lop(Itailcall_imm s) ->
if s = !function_name then begin
@@ -424,16 +435,21 @@ let emit_instr i =
` ldq $26, {emit_int(n - 8)}($sp)\n`;
if n > 0 then
` lda $sp, {emit_int n}($sp)\n`;
- liveregs i live_26;
+ if multiple_gp then
+ ` lda $27, {emit_symbol s}\n`;
+ liveregs i (live_26 + live_27);
` br {emit_symbol s}\n`
end
| Lop(Iextcall(s, alloc)) ->
if alloc then begin
` lda $25, {emit_symbol s}\n`;
liveregs i live_25;
- `{record_frame i.live} bsr $26, caml_c_call\n`
+ ` bsr $26, caml_c_call\n`;
+ `{record_frame i.live}\n`
end else begin
- ` jsr {emit_symbol s}\n`
+ ` jsr {emit_symbol s}\n`;
+ if not multiple_gp then
+ ` ldgp $gp, 0($26)\n`
end
| Lop(Istackoffset n) ->
` lda $sp, {emit_int (-n)}($sp)\n`;
@@ -471,17 +487,17 @@ let emit_instr i =
end else begin
begin match n with
16 -> liveregs i 0;
- `{record_frame i.live} bsr $26, caml_alloc1\n`
+ ` bsr $26, caml_alloc1\n`
| 24 -> liveregs i 0;
- `{record_frame i.live} bsr $26, caml_alloc2\n`
+ ` bsr $26, caml_alloc2\n`
| 32 -> liveregs i 0;
- `{record_frame i.live} bsr $26, caml_alloc3\n`
+ ` bsr $26, caml_alloc3\n`
| _ -> ` ldiq $25, {emit_int n}\n`;
liveregs i live_25;
- `{record_frame i.live} bsr $26, caml_alloc\n`
+ ` bsr $26, caml_alloc\n`
end;
(* $gp preserved by caml_alloc* *)
- ` addq $13, 8, {emit_reg i.res.(0)}\n`
+ `{record_frame i.live} addq $13, 8, {emit_reg i.res.(0)}\n`
end
| Lop(Iintop(Icomp cmp)) ->
let (comp, test) = name_for_int_comparison cmp in
@@ -556,12 +572,9 @@ let emit_instr i =
` lda $sp, 8($sp)\n`;
` .set at\n`
| Lop(Ispecific(Ireloadgp marked_r26)) ->
- if marked_r26 then begin
- ` bic $26, 1, $26\n`;
- ` ldgp $gp, 4($26)\n`
- end else begin
- ` ldgp $gp, 0($26)\n`
- end
+ ` ldgp $gp, 0($26)\n`;
+ if marked_r26 then
+ ` bic $gp, 1, $gp\n`
| Lop(Ispecific sop) ->
let instr = name_for_specific_operation sop in
` {emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
@@ -689,21 +702,21 @@ let emit_fundecl (fundecl, needs_gp) =
` .globl {emit_symbol fundecl.fun_name}\n`;
` .ent {emit_symbol fundecl.fun_name}\n`;
`{emit_symbol fundecl.fun_name}:\n`;
+ if needs_gp then begin
+ ` .set noreorder\n`;
+ ` ldgp $gp, 0($27)\n`;
+ ` .set reorder\n`
+ end;
let n = frame_size() in
if n > 0 then
` lda $sp, -{emit_int n}($sp)\n`;
- if needs_gp then begin
- let lbl = new_label() in
- ` br $27, {emit_label lbl}\n`;
- `{emit_label lbl}: ldgp $gp, 0($27)\n`
- end;
if !contains_calls then begin
` stq $26, {emit_int(n - 8)}($sp)\n`;
` .mask 0x04000000, -8\n`;
` .fmask 0x0, 0\n`
end;
` .frame $sp, {emit_int n}, $26\n`;
- ` .prologue 0\n`;
+ ` .prologue {if needs_gp then 1 else 0}\n`;
tailrec_entry_point := new_label();
`{emit_label !tailrec_entry_point}:\n`;
emit_all fundecl.fun_body;
@@ -730,7 +743,7 @@ let emit_fundecl (fundecl, needs_gp) =
end
let fundecl f =
- emit_fundecl (insert_load_gp f)
+ emit_fundecl (if multiple_gp then insert_load_gp f else (f, false))
(* Emission of data *)