summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asmcomp/emit_sparc.mlp43
-rw-r--r--asmcomp/proc_sparc.ml35
-rw-r--r--asmrun/sparc.S68
3 files changed, 58 insertions, 88 deletions
diff --git a/asmcomp/emit_sparc.mlp b/asmcomp/emit_sparc.mlp
index 9066686c9f..a7416785da 100644
--- a/asmcomp/emit_sparc.mlp
+++ b/asmcomp/emit_sparc.mlp
@@ -239,13 +239,6 @@ let name_for_float_comparison cmp neg =
| Clt -> if neg then "fbuge" else "fbl"
| Cge -> if neg then "fbul" else "fbge"
-(* Names of special registers *)
-
-let (exn_reg, alloc_reg, limit_reg) =
- if Config.system = "sunos"
- then ("%g5", "%g6", "%g7")
- else ("%g2", "%g3", "%g4")
-
(* Output the assembly code for an instruction *)
let function_name = ref ""
@@ -325,9 +318,9 @@ let rec emit_instr i dslot =
end
| Lop(Iextcall(s, alloc)) ->
if alloc then begin
- ` sethi %hi({emit_symbol s}), %l7\n`;
+ ` sethi %hi({emit_symbol s}), %g2\n`;
`{record_frame i.live} call {emit_symbol "caml_c_call"}\n`;
- ` or %l7, %lo({emit_symbol s}), %l7\n` (* in delay slot *)
+ ` or %g2, %lo({emit_symbol s}), %g2\n` (* in delay slot *)
end else begin
` call {emit_symbol s}\n`;
fill_delay_slot dslot
@@ -366,19 +359,19 @@ let rec emit_instr i dslot =
| Lop(Ialloc n) ->
if !fastcode_flag then begin
let lbl_cont = new_label() in
- ` ld [{emit_string limit_reg}], %g1\n`;
- ` sub {emit_string alloc_reg}, {emit_int n}, {emit_string alloc_reg}\n`;
- ` cmp {emit_string alloc_reg}, %g1\n`;
+ ` ld [%l7], %g1\n`;
+ ` sub %l6, {emit_int n}, %l6\n`;
+ ` cmp %l6, %g1\n`;
` bgeu {emit_label lbl_cont}\n`;
- ` add {emit_string alloc_reg}, 4, {emit_reg i.res.(0)}\n`; (* in delay slot *)
+ ` add %l6, 4, {emit_reg i.res.(0)}\n`; (* in delay slot *)
`{record_frame i.live} call {emit_symbol "caml_call_gc"}\n`;
- ` mov {emit_int n}, %l7\n`; (* in delay slot *)
- ` add {emit_string alloc_reg}, 4, {emit_reg i.res.(0)}\n`;
+ ` mov {emit_int n}, %g2\n`; (* in delay slot *)
+ ` add %l6, 4, {emit_reg i.res.(0)}\n`;
`{emit_label lbl_cont}:\n`
end else begin
`{record_frame i.live} call {emit_symbol "caml_alloc"}\n`;
- ` mov {emit_int n}, %l7\n`; (* in delay slot *)
- ` add {emit_string alloc_reg}, 4, {emit_reg i.res.(0)}\n`
+ ` mov {emit_int n}, %g2\n`; (* in delay slot *)
+ ` add %l6, 4, {emit_reg i.res.(0)}\n`
end
| Lop(Iintop(Icomp cmp)) ->
let comp = name_for_int_comparison cmp in
@@ -506,8 +499,8 @@ let rec emit_instr i dslot =
let lbl_jumptbl = new_label() in
` sethi %hi({emit_label lbl_jumptbl}), %g1\n`;
` or %g1, %lo({emit_label lbl_jumptbl}), %g1\n`;
- ` sll {emit_reg i.arg.(0)}, 2, %l7\n`;
- ` ld [%g1 + %l7], %g1\n`;
+ ` sll {emit_reg i.arg.(0)}, 2, %g2\n`;
+ ` ld [%g1 + %g2], %g1\n`;
` jmp %g1\n`; (* poor scheduling *)
` nop\n`;
`{emit_label lbl_jumptbl}:`;
@@ -520,16 +513,16 @@ let rec emit_instr i dslot =
| Lpushtrap ->
stack_offset := !stack_offset + 8;
` st %o7, [%sp + 96]\n`;
- ` st {emit_string exn_reg}, [%sp + 100]\n`;
- ` mov %sp, {emit_string exn_reg}\n`
+ ` st %l5, [%sp + 100]\n`;
+ ` mov %sp, %l5\n`
| Lpoptrap ->
- ` ld [%sp + 100], {emit_string exn_reg}\n`;
+ ` ld [%sp + 100], %l5\n`;
` add %sp, 8, %sp\n`;
stack_offset := !stack_offset - 8
| Lraise ->
- ` ld [{emit_string exn_reg} + 96], %g1\n`;
- ` mov {emit_string exn_reg}, %sp\n`;
- ` ld [%sp + 100], {emit_string exn_reg}\n`;
+ ` ld [%l5 + 96], %g1\n`;
+ ` mov %l5, %sp\n`;
+ ` ld [%sp + 100], %l5\n`;
` jmp %g1 + 8\n`;
` add %sp, 8, %sp\n`
diff --git a/asmcomp/proc_sparc.ml b/asmcomp/proc_sparc.ml
index e2b8e1d00a..b0c3757665 100644
--- a/asmcomp/proc_sparc.ml
+++ b/asmcomp/proc_sparc.ml
@@ -96,13 +96,16 @@ let word_addressed = false
(* Register map:
%o0 - %o5 0 - 5 function results, C functions args / res
%i0 - %i5 6 - 11 function arguments, preserved by C
- %l0 - %l7 12 - 19 general purpose, preserved by C
+ %l0 - %l4 12 - 16 general purpose, preserved by C
+ %g3 - %g4 17 - 18 general purpose, not preserved by C
+
+ %l5 exception pointer
+ %l6 allocation pointer
+ %l7 address of allocation limit
%g0 always zero
- %g1 temporary
- %g2 (%g5 for SunOS) exception pointer
- %g3 (%g6 for SunOS) allocation pointer
- %g4 (%g7 for SunOS) allocation limit
+ %g1 - %g2 temporaries
+ %g5 - %g7 reserved for system libraries
%f0 - %f10 100 - 105 function arguments and results
%f12 - %f28 106 - 114 general purpose
@@ -111,7 +114,8 @@ let word_addressed = false
let int_reg_name = [|
(* 0-5 *) "%o0"; "%o1"; "%o2"; "%o3"; "%o4"; "%o5";
(* 6-11 *) "%i0"; "%i1"; "%i2"; "%i3"; "%i4"; "%i5";
- (* 12-19 *) "%l0"; "%l1"; "%l2"; "%l3"; "%l4"; "%l5"; "%l6"; "%l7"
+ (* 12-16 *) "%l0"; "%l1"; "%l2"; "%l3"; "%l4";
+ (* 17-18 *) "%g3"; "%g4"
|]
let float_reg_name = [|
@@ -132,7 +136,7 @@ let register_class r =
| Addr -> 0
| Float -> 1
-let num_available_registers = [| 20; 15 |]
+let num_available_registers = [| 19; 15 |]
let first_available_register = [| 0; 100 |]
@@ -144,8 +148,8 @@ let rotate_registers = true
(* Representation of hard registers by pseudo-registers *)
let hard_int_reg =
- let v = Array.create 20 Reg.dummy in
- for i = 0 to 19 do v.(i) <- Reg.at_location Int (Reg i) done;
+ let v = Array.create 19 Reg.dummy in
+ for i = 0 to 18 do v.(i) <- Reg.at_location Int (Reg i) done;
v
let hard_float_reg =
@@ -232,19 +236,15 @@ let loc_exn_bucket = phys_reg 0 (* $o0 *)
(* Registers destroyed by operations *)
-let destroyed_at_c_call = (* %l0-%l6, %i0-%i5 preserved ; %l7 used as temp *)
+let destroyed_at_c_call = (* %l0-%l4, %i0-%i5 preserved *)
Array.of_list(List.map phys_reg
- [0; 1; 2; 3; 4; 5; 19;
+ [0; 1; 2; 3; 4; 5; 17; 18;
100; 101; 102; 103; 104; 105; 106; 107;
108; 109; 110; 111; 112; 113; 114])
-let destroy_l7 = [| phys_reg 19 (* %l7 *) |]
-
let destroyed_at_oper = function
Iop(Icall_ind | Icall_imm _ | Iextcall(_, true)) -> all_phys_regs
| Iop(Iextcall(_, false)) -> destroyed_at_c_call
- | Iop(Ialloc _) -> destroy_l7
- | Iswitch(_, _) -> destroy_l7
| _ -> [||]
let destroyed_at_raise = all_phys_regs
@@ -256,9 +256,8 @@ let safe_register_pressure = function
| _ -> 15
let max_register_pressure = function
- Iextcall(_, _) -> [| 13; 0 |]
- | Ialloc _ -> [| 19; 15 |]
- | _ -> [| 20; 15 |]
+ Iextcall(_, _) -> [| 11; 0 |]
+ | _ -> [| 19; 15 |]
(* Reloading *)
diff --git a/asmrun/sparc.S b/asmrun/sparc.S
index 020f9472b8..3732cf3509 100644
--- a/asmrun/sparc.S
+++ b/asmrun/sparc.S
@@ -18,7 +18,7 @@
#ifndef SYS_solaris
- .common _gc_entry_regs, 22 * 4, "bss"
+ .common _gc_entry_regs, 19 * 4, "bss"
.common _gc_entry_float_regs, 30 * 4, "bss"
.common _caml_required_size, 4, "bss"
@@ -76,29 +76,9 @@
#endif
-#ifdef SYS_sunos
-
-/* SunOS has no well-defined policy w.r.t. %g2 ... %g7
- By trial and error, it appears that most libc functions preserve
- %g5 ... %g7, except a few (e.g. sigtramp clobbers %g6).
- Use %g5 ... %g7 for the global registers, but save and restore
- them in caml_c_call. */
-#define Exn_ptr %g5
-#define Alloc_ptr %g6
-#define Alloc_limit %g7
-
-#else
-
-/* The Sparc ABI says that %g2 ... %g4 are reserved for the application
- (and should be preserved across system calls and libc functions)
- and %g5 ... %g7 are reserved for the libraries and kernel
- (e.g. %g7 is used by the Solaris thread library).
- Solaris follows the ABI; we assume BSD does, too. */
-#define Exn_ptr %g2
-#define Alloc_ptr %g3
-#define Alloc_limit %g4
-
-#endif
+#define Exn_ptr %l5
+#define Alloc_ptr %l6
+#define Alloc_limit %l7
#define Load(symb,reg) sethi %hi(symb), %g1; ld [%g1 + %lo(symb)], reg
#define Store(reg,symb) sethi %hi(symb), %g1; st reg, [%g1 + %lo(symb)]
@@ -110,20 +90,20 @@
.global Caml_alloc
.global Caml_call_gc
-/* Required size in %l7 */
+/* Required size in %g2 */
Caml_alloc:
ld [Alloc_limit], %g1
- sub Alloc_ptr, %l7, Alloc_ptr
+ sub Alloc_ptr, %g2, Alloc_ptr
cmp Alloc_ptr, %g1
blu Caml_call_gc
nop
retl
nop
-/* Required size in %l7 */
+/* Required size in %g2 */
Caml_call_gc:
- /* Save %l7 (required size) */
- Store(%l7, Caml_required_size)
+ /* Save %g2 (required size) */
+ Store(%g2, Caml_required_size)
/* Save Exn_ptr (exception pointer) */
Store(Exn_ptr, Caml_exception_pointer)
/* Save current allocation pointer for debugging purposes */
@@ -142,8 +122,9 @@ Caml_call_gc:
std %i4, [%g1 + 0x28]
std %l0, [%g1 + 0x30]
std %l2, [%g1 + 0x38]
- std %l4, [%g1 + 0x40]
- st %l6, [%g1 + 0x48]
+ st %l4, [%g1 + 0x40]
+ st %g3, [%g1 + 0x44]
+ st %g4, [%g1 + 0x48]
Address(Gc_entry_float_regs, %g1)
std %f0, [%g1]
std %f2, [%g1 + 0x8]
@@ -173,8 +154,9 @@ Caml_call_gc:
ldd [%g1 + 0x28], %i4
ldd [%g1 + 0x30], %l0
ldd [%g1 + 0x38], %l2
- ldd [%g1 + 0x40], %l4
- ld [%g1 + 0x48], %l6
+ ld [%g1 + 0x40], %l4
+ ld [%g1 + 0x44], %g3
+ ld [%g1 + 0x48], %g4
Address(Gc_entry_float_regs, %g1)
ldd [%g1], %f0
ldd [%g1 + 0x8], %f2
@@ -191,13 +173,11 @@ Caml_call_gc:
ldd [%g1 + 0x60], %f24
ldd [%g1 + 0x68], %f26
ldd [%g1 + 0x70], %f28
- /* Reload global registers */
- Load(Caml_exception_pointer, Exn_ptr)
+ /* Reload alloc ptr */
Load(Young_ptr, Alloc_ptr)
- Address(Young_limit, Alloc_limit)
/* Allocate space for block */
- Load(Caml_required_size, %l7)
- sub Alloc_ptr, %l7, Alloc_ptr
+ Load(Caml_required_size, %g2)
+ sub Alloc_ptr, %g2, Alloc_ptr
/* Return to caller */
Load(Caml_last_return_address, %o7)
retl
@@ -206,7 +186,7 @@ Caml_call_gc:
/* Call a C function from Caml */
.global Caml_c_call
-/* Function to call is in %l7 */
+/* Function to call is in %g2 */
Caml_c_call:
/* Record lowest stack address and return address */
Store(%sp, Caml_bottom_of_stack)
@@ -215,17 +195,15 @@ Caml_c_call:
Store(Exn_ptr, Caml_exception_pointer)
sethi %hi(Young_ptr), %g1
/* Call the C function */
- call %l7
+ call %g2
st Alloc_ptr, [%g1 + %lo(Young_ptr)] /* in delay slot */
/* Reload return address */
Load(Caml_last_return_address, %o7)
- /* Reload global registers */
- Load(Caml_exception_pointer, Exn_ptr)
- Load(Young_ptr, Alloc_ptr)
- sethi %hi(Young_limit), Alloc_limit
+ /* Reload alloc pointer */
+ sethi %hi(Young_ptr), %g1
/* Return to caller */
retl
- or Alloc_limit, %lo(Young_limit), Alloc_limit /* in delay slot */
+ ld [%g1 + %lo(Young_ptr)], Alloc_limit /* in delay slot */
/* Start the Caml program */