diff options
-rw-r--r-- | asmcomp/emit_sparc.mlp | 43 | ||||
-rw-r--r-- | asmcomp/proc_sparc.ml | 35 | ||||
-rw-r--r-- | asmrun/sparc.S | 68 |
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 */ |