You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 1396 Reporter: administrator Status: closed Resolution: fixed Priority: normal Severity: feature Category: ~DO NOT USE (was: OCaml general)
Bug description
Enclosed are my SPARC code generation changes.
Code may be generated for different SPARC versions -- old SPARC,
SPARC V8, SPARC V9. The target must be selected at compile time.
This is suboptimal but I didn't see any trivial way to pass flags
from the command line to the code generator.
List of changes:
proc.ml: Update latencies for UltraSPARC. Pass appropriate -xarch=
flag to assembler.
emit.mlp: On Solaris, emit .type and .size directives, put frame table
and floating point constants in read-only data section, and support
profiling.
emit.mlp: For SPARC V9, use new double precision floating point
instructions (fabsd, fmovd, fnegd) and conditional move, and omit
the nop after a floating point comparison.
For SPARC V8 and V9, use hardware multiply and divide.
Emit add src,src,dst instead of sll src,1,dst because the former is
faster on UltraSPARC.
If a function does not allocate any stack space, change add %sp,0,%sp
in the epilogue to a nop.
On Solaris, store the allocation limit in a register (instead of
storing the address in a register).
Support reg+reg addressing mode.
emit.mlp and sparc.S: Avoid ldd and std instructions on UltraSPARC.
let comp = name_for_int_comparison cmp in
` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
! let lbl = new_label() in
! {emit_string comp},a {emit_label lbl}\n;
! mov 1, {emit_reg i.res.(0)}\n;
! mov 0, {emit_reg i.res.(0)}\n;
! {emit_label lbl}:\n
| Lop(Iintop Icheckbound) -> cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n; tleu 5\n (* 5 = ST_RANGE_CHECK )
| Lop(Iintop op) ->
let instr = name_for_int_operation op in {emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n
| Lop(Iintop_imm(Idiv, n)) -> ( n is a power of 2 )
let l = Misc.log2 n in
! let lbl = new_label() in
! cmp {emit_reg i.arg.(0)}, 0\n;
! bge {emit_label lbl}\n;
! mov {emit_reg i.arg.(0)}, %g1\n; ( in delay slot )
! add %g1, {emit_int (n-1)}, %g1\n;
! {emit_label lbl}:\n;
! sra %g1, {emit_int l}, {emit_reg i.res.(0)}\n
| Lop(Iintop_imm(Imod, n)) -> ( n is a power of 2 )
let lbl = new_label() in tst {emit_reg i.arg.(0)}\n; bge {emit_label lbl}\n;
--- 425,484 ---- add %l6, 4, {emit_reg i.res.(0)}\n
end
| Lop(Iintop(Icomp cmp)) -> cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n;
! if !arch_version = SPARC_V9 then begin
! let comp = name_for_int_movcc cmp in
! mov 0, {emit_reg i.res.(0)}\n;
! mov{emit_string comp} %icc, 1, {emit_reg i.res.(0)}\n
! end
! else begin
! let comp = name_for_int_comparison cmp
! and lbl = new_label() in
! {emit_string comp},a {emit_label lbl}\n;
! mov 1, {emit_reg i.res.(0)}\n;
! mov 0, {emit_reg i.res.(0)}\n;
! {emit_label lbl}:\n
! end
| Lop(Iintop Icheckbound) -> cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n; tleu 5\n ( 5 = ST_RANGE_CHECK *)
(*
| Lop(Iintop Imod) ->
` sra {emit_reg i.arg.(0)}, 0, %g1\n`;
` sra {emit_reg i.arg.(1)}, 0, %g2\n`;
` sdivx %g1, %g2, %g1\n`;
` smul %g1, %g2, %g1\n`;
` sub {emit_reg i.arg.(0)}, %g1, {emit_reg i.res.(0)}\n`
*)
| Lop(Iintop Idiv) ->
` sra {emit_reg i.arg.(0)}, 31, %g1\n`;
` wr %g1, %y\n`;
` sdiv {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
| Lop(Iintop op) ->
let instr = name_for_int_operation op in
` {emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
| Lop(Iintop_imm(Ilsl, 1)) ->
(* UltraSPARC has two add units but only one shifter. *)
` add {emit_reg i.arg.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.res.(0)}\n`
| Lop(Iintop_imm(Idiv, n)) -> (* n is a power of 2 *)
let l = Misc.log2 n in
! if n = 1 lsl l then begin
! let lbl = new_label() in
! cmp {emit_reg i.arg.(0)}, 0\n;
! bge {emit_label lbl}\n;
! mov {emit_reg i.arg.(0)}, %g1\n; (* in delay slot )
! add %g1, {emit_int (n-1)}, %g1\n;
! {emit_label lbl}:\n;
! sra %g1, {emit_int l}, {emit_reg i.res.(0)}\n
! end
! else begin ( Not a power of 2 )
! sra {emit_reg i.arg.(0)}, 31, %g1\n;
! wr %g1, %y\n;
! sdiv {emit_reg i.arg.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n
! end
| Lop(Iintop_imm(Imod, n)) -> ( n is a power of 2 *)
let log = Misc.log2 n in
if n != 1 lsl log then Misc.fatal_error "Imod operand" else
let lbl = new_label() in
` tst {emit_reg i.arg.(0)}\n`;
` bge {emit_label lbl}\n`;
! type specific_operation = unit (* None worth mentioning *)
(* Addressing modes *)
type addressing_mode =
Ibased of string * int (* symbol + displ )
| Iindexed of int ( reg + displ *)
(* Sizes, endianness *)
--- 17,41 ----
open Misc
open Format
! (* SPARC V8 adds multiply and divide.
! SPARC V9 adds double precision float operations, conditional
! move, and more instructions that are only useful in 64 bit mode.
! Sun calls 32 bit V9 "V8+". *)
! type arch_version = SPARC_V7 | SPARC_V8 | SPARC_V9
let arch_version = ref SPARC_V9
(* V9 conditional move *)
type specific_operation =
Icmov of Cmm.comparison * int * int
| Icmov_imm of Cmm.comparison * int * int * int
(* Addressing modes *)
type addressing_mode =
Ibased of string * int (* symbol + displ )
| Iindexed of int ( reg + displ *)
| Iindexed2 of int
(* Sizes, endianness *)
*** 41,50 ****
--- 53,65 ----
match addr with
Ibased(s, n) -> Ibased(s, n + delta)
| Iindexed n -> Iindexed(n + delta)
| Iindexed2 0 -> Iindexed2(delta)
| Iindexed2 n -> Misc.fatal_error "Arch_sparc.offset_addressing"
let num_args_addressing = function
Ibased(s, n) -> 0
| Iindexed n -> 1
| Iindexed2 _ -> 2
(* Printing operations and addressing modes *)
*** 56,61 ****
--- 71,80 ----
| Iindexed n ->
let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in
fprintf ppf "%a%s" printreg arg.(0) idx
mov %o0, %i0 /* %i0 will become %o0 after restore */
/* Reload callee-save registers and return */
ret
! restore
L110:
/* The trap handler /
Store(Exn_ptr, Caml_exception_pointer)
/ Encode exception bucket as an exception result */
or %o0, 2, %o0
b L112
! nop
/* Raise an exception from C */
.global Raise_caml_exception
Raise_caml_exception:
/* Save exception bucket in a register outside the reg windows /
mov %o0, %g2
--- 328,347 ----
add %sp, 16, %sp
/ Save allocation pointer /
Store(Alloc_ptr, Young_ptr)
/ Reload callee-save registers and return /
ret
! restore %o0, 0, %o0 / copy %o0 in this window to caller's %o0 /
L110:
/ The trap handler /
Store(Exn_ptr, Caml_exception_pointer)
/ Encode exception bucket as an exception result */
b L112
! or %o0, 2, %o0
/* Raise an exception from C */
.global Raise_caml_exception
FUNCTION(Raise_caml_exception)
Raise_caml_exception:
/* Save exception bucket in a register outside the reg windows */
mov %o0, %g2
Original bug ID: 1396
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)
Bug description
Enclosed are my SPARC code generation changes.
Code may be generated for different SPARC versions -- old SPARC,
SPARC V8, SPARC V9. The target must be selected at compile time.
This is suboptimal but I didn't see any trivial way to pass flags
from the command line to the code generator.
List of changes:
proc.ml: Update latencies for UltraSPARC. Pass appropriate -xarch=
flag to assembler.
emit.mlp: On Solaris, emit .type and .size directives, put frame table
and floating point constants in read-only data section, and support
profiling.
emit.mlp: For SPARC V9, use new double precision floating point
instructions (fabsd, fmovd, fnegd) and conditional move, and omit
the nop after a floating point comparison.
For SPARC V8 and V9, use hardware multiply and divide.
Emit add src,src,dst instead of sll src,1,dst because the former is
faster on UltraSPARC.
If a function does not allocate any stack space, change add %sp,0,%sp
in the epilogue to a nop.
On Solaris, store the allocation limit in a register (instead of
storing the address in a register).
Support reg+reg addressing mode.
emit.mlp and sparc.S: Avoid ldd and std instructions on UltraSPARC.
*** asmcomp/sparc/proc.ml.orig Mon Jul 22 12:37:55 2002
--- asmcomp/sparc/proc.ml Thu Sep 19 16:08:45 2002
*** 198,215 ****
Iextcall(_, _) -> [| 11; 0 |]
| _ -> [| 19; 15 |]
! (* Latencies (in cycles). Wild guesses. *)
let need_scheduling = true
let oper_latency = function
Ireload -> 3
| Iload(_, _) -> 3
| Iconst_float _ -> 3 (* turned into a load *)
! | Iaddf | Isubf -> 3
! | Imulf -> 5
| Idivf -> 15
! | _ -> 1
(* Layout of the stack *)
--- 198,224 ----
Iextcall(_, _) -> [| 11; 0 |]
| _ -> [| 19; 15 |]
! (* Latencies (in cycles). *)
let need_scheduling = true
let oper_latency = function
Ireload -> 3
| Iload(, _) -> 3
| Iconst_float _ -> 3 (* turned into a load *)
! | Ispecific _ -> 4
! | Inegf | Iabsf | Iaddf | Isubf | Imulf -> 4
| Idivf -> 15
! | _ -> 2
(* Layout of the stack *)
*** 219,225 ****
(* Calling the assembler and the archiver *)
let assemble_file infile outfile =
! Ccomp.command ("as -o " ^ Filename.quote outfile ^ " " ^ Filename.quote infile)
open Clflags;;
open Config;;
--- 228,239 ----
(* Calling the assembler and the archiver *)
let assemble_file infile outfile =
! let asprefix = begin match !arch_version with
! SPARC_V7 -> "as -o "
! | SPARC_V8 -> "as -xarch=v8 -o "
! | SPARC_V9 -> "as -xarch=v8plus -o "
! end in
! Ccomp.command (asprefix ^ Filename.quote outfile ^ " " ^ Filename.quote infile)
open Clflags;;
open Config;;
*** asmcomp/sparc/emit.mlp.orig Mon Jul 22 12:37:55 2002
--- asmcomp/sparc/emit.mlp Thu Sep 19 16:18:09 2002
*** 68,73 ****
--- 68,83 ----
then emit_string s
else begin emit_string symbol_prefix; Emitaux.emit_symbol '$' s end
let emit_size lbl =
if Config.system = "solaris" then
let rodata () =
if Config.system = "solaris" (* || Config.system = "linux" *) then
else
(* Check if an integer or native integer is an immediate operand *)
let is_immediate n =
*** 117,122 ****
--- 127,137 ----
or %g1, %lo({emit_int ofs}), %g1\n
;{emit_string instr} [{emit_reg arg.(0)} + %g1], {emit_reg dst}\n
end
| Iindexed2 0 ->
| Iindexed2 n ->
(* Output a store *)
*** 136,142 ****
--- 151,163 ----
or %g1, %lo({emit_int ofs}), %g1\n
;{emit_string instr} {emit_reg src}, [{emit_reg arg.(1)} + %g1]\n
end
| Iindexed2 0 ->
| Iindexed2 n ->
(* Record live pointers at call points *)
type frame_descr =
*** 179,188 ****
let float_constants = ref ([] : (int * string) list)
let emit_float_constant (lbl, cst) =
!
.data\n
;.align 8\n
;{emit_label lbl}: .double 0r{emit_string cst}\n
(* Names of various instructions *)
let name_for_int_operation = function
--- 200,225 ----
let float_constants = ref ([] : (int * string) list)
let emit_float_constant (lbl, cst) =
! rodata ();
.align 8\n
;{emit_label lbl}: .double 0r{emit_string cst}\n
(* Emission of the profiling prelude *)
let emit_profile () =
begin match Config.system with
| _ -> ()
end
(* Names of various instructions *)
let name_for_int_operation = function
*** 194,204 ****
| Ilsl -> "sll"
| Ilsr -> "srl"
| Iasr -> "sra"
| _ -> Misc.fatal_error "Emit.name_for_int_operation"
let name_for_float_operation = function
! Inegf -> "fnegs"
! | Iabsf -> "fabss"
| Iaddf -> "faddd"
| Isubf -> "fsubd"
| Imulf -> "fmuld"
--- 231,242 ----
| Ilsl -> "sll"
| Ilsr -> "srl"
| Iasr -> "sra"
| _ -> Misc.fatal_error "Emit.name_for_int_operation"
let name_for_float_operation = function
! Inegf -> if !arch_version != SPARC_V9 then "fnegs" else "fnegd"
! | Iabsf -> if !arch_version != SPARC_V9 then "fabss" else "fabsd"
| Iaddf -> "faddd"
| Isubf -> "fsubd"
| Imulf -> "fmuld"
*** 205,210 ****
--- 243,256 ----
| Idivf -> "fdivd"
| _ -> Misc.fatal_error "Emit.name_for_float_operation"
Isigned Ceq -> "be" | Isigned Cne -> "bne"
| Isigned Cle -> "ble" | Isigned Cgt -> "bg"
*** 236,249 ****
{loc = Reg rs; typ = (Int | Addr)}, {loc = Reg rd} ->
mov {emit_reg src}, {emit_reg dst}\n
| {loc = Reg rs; typ = Float}, {loc = Reg rd; typ = Float} ->
!
fmovs {emit_reg src}, {emit_reg dst}\n
;!
fmovs {emit_reg(next_in_pair src)}, {emit_reg(next_in_pair dst)}\n
| {loc = Reg rs; typ = Float}, {loc = Reg rd; typ = (Int | Addr)} ->
(* This happens when calling C functions and passing a float arg
in %o0...%o5 )
sub %sp, 8, %sp\n
;std {emit_reg src}, [%sp + 96]\n
;! if rd land 1 = 0 then
ldd [%sp + 96], {emit_reg dst}\n
else begin
ld [%sp + 96], {emit_reg dst}\n
;--- 282,299 ----
{loc = Reg rs; typ = (Int | Addr)}, {loc = Reg rd} ->
mov {emit_reg src}, {emit_reg dst}\n
| {loc = Reg rs; typ = Float}, {loc = Reg rd; typ = Float} ->
! if !arch_version != SPARC_V9 then begin
!
fmovs {emit_reg src}, {emit_reg dst}\n
;!
fmovs {emit_reg(next_in_pair src)}, {emit_reg(next_in_pair dst)}\n
! end
! else
!
fmovd {emit_reg src}, {emit_reg dst}\n
| {loc = Reg rs; typ = Float}, {loc = Reg rd; typ = (Int | Addr)} ->
( This happens when calling C functions and passing a float arg
in %o0...%o5 *)
sub %sp, 8, %sp\n
;std {emit_reg src}, [%sp + 96]\n
;! if !arch_version != SPARC_V9 && rd land 1 = 0 then
ldd [%sp + 96], {emit_reg dst}\n
else begin
ld [%sp + 96], {emit_reg dst}\n
;*** 269,274 ****
--- 319,326 ----
or %g1, %lo({emit_nativeint n}), {emit_reg i.res.(0)}\n
end
| Lop(Iconst_float s) ->
*** 352,361 ****
end
| Lop(Ialloc n) ->
if !fastcode_flag then begin
! let lbl_cont = new_label() in
!
ld [%l7], %g1\n
;sub %l6, {emit_int n}, %l6\n
;!
cmp %l6, %g1\n
;bgeu {emit_label lbl_cont}\n
;add %l6, 4, {emit_reg i.res.(0)}\n
; (* in delay slot ){record_frame i.live} call {emit_symbol "caml_call_gc"}\n
;--- 404,418 ----
end
| Lop(Ialloc n) ->
if !fastcode_flag then begin
! let lbl_cont = new_label()
! and indirect = Config.system <> "solaris" in
! if indirect then
!
ld [%l7], %g1\n
;sub %l6, {emit_int n}, %l6\n
;! if indirect then
!
cmp %l6, %g1\n
! else
!
cmp %l6, %l7\n
;bgeu {emit_label lbl_cont}\n
;add %l6, 4, {emit_reg i.res.(0)}\n
; ( in delay slot *){record_frame i.live} call {emit_symbol "caml_call_gc"}\n
;*** 368,396 ****
add %l6, 4, {emit_reg i.res.(0)}\n
end
| Lop(Iintop(Icomp cmp)) ->
! let lbl = new_label() in
!
{emit_string comp},a {emit_label lbl}\n
;!
mov 1, {emit_reg i.res.(0)}\n
;!
mov 0, {emit_reg i.res.(0)}\n
;!
{emit_label lbl}:\n
| Lop(Iintop Icheckbound) ->
cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n
;tleu 5\n
(* 5 = ST_RANGE_CHECK )| Lop(Iintop op) ->
let instr = name_for_int_operation op in
{emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n
| Lop(Iintop_imm(Idiv, n)) -> ( n is a power of 2 )
let l = Misc.log2 n in
! let lbl = new_label() in
!
cmp {emit_reg i.arg.(0)}, 0\n
;!
bge {emit_label lbl}\n
;!
mov {emit_reg i.arg.(0)}, %g1\n
; ( in delay slot )!
add %g1, {emit_int (n-1)}, %g1\n
;!
{emit_label lbl}:\n
;!
sra %g1, {emit_int l}, {emit_reg i.res.(0)}\n
| Lop(Iintop_imm(Imod, n)) -> ( n is a power of 2 )
let lbl = new_label() in
tst {emit_reg i.arg.(0)}\n
;bge {emit_label lbl}\n
;--- 425,484 ----
add %l6, 4, {emit_reg i.res.(0)}\n
end
| Lop(Iintop(Icomp cmp)) ->
cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n
;! if !arch_version = SPARC_V9 then begin
! let comp = name_for_int_movcc cmp in
!
mov 0, {emit_reg i.res.(0)}\n
;!
mov{emit_string comp} %icc, 1, {emit_reg i.res.(0)}\n
! end
! else begin
! let comp = name_for_int_comparison cmp
! and lbl = new_label() in
!
{emit_string comp},a {emit_label lbl}\n
;!
mov 1, {emit_reg i.res.(0)}\n
;!
mov 0, {emit_reg i.res.(0)}\n
;!
{emit_label lbl}:\n
! end
| Lop(Iintop Icheckbound) ->
cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n
;tleu 5\n
( 5 = ST_RANGE_CHECK *)! if n = 1 lsl l then begin
! let lbl = new_label() in
!
cmp {emit_reg i.arg.(0)}, 0\n
;!
bge {emit_label lbl}\n
;!
mov {emit_reg i.arg.(0)}, %g1\n
; (* in delay slot )!
add %g1, {emit_int (n-1)}, %g1\n
;!
{emit_label lbl}:\n
;!
sra %g1, {emit_int l}, {emit_reg i.res.(0)}\n
! end
! else begin ( Not a power of 2 )
!
sra {emit_reg i.arg.(0)}, 31, %g1\n
;!
wr %g1, %y\n
;!
sdiv {emit_reg i.arg.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n
! end
| Lop(Iintop_imm(Imod, n)) -> ( n is a power of 2 *)
*** 399,412 ****
nop\n
;sub {emit_reg i.res.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n
;{emit_label lbl}:\n
| Lop(Iintop_imm(Icomp cmp, n)) ->
! let lbl = new_label() in
!
{emit_string comp},a {emit_label lbl}\n
;!
mov 1, {emit_reg i.res.(0)}\n
;!
mov 0, {emit_reg i.res.(0)}\n
;!
{emit_label lbl}:\n
| Lop(Iintop_imm(Icheckbound, n)) ->
cmp {emit_reg i.arg.(0)}, {emit_int n}\n
;tleu 5\n
(* 5 = ST_RANGE_CHECK *)--- 487,514 ----
nop\n
;sub {emit_reg i.res.(0)}, {emit_int n}, {emit_reg i.res.(0)}\n
;{emit_label lbl}:\n
| Lop(Iintop_imm(Icomp cmp, n)) ->
cmp {emit_reg i.arg.(0)}, {emit_int n}\n
;! if !arch_version = SPARC_V9 then begin
! let comp = name_for_int_movcc cmp in
!
mov 0, {emit_reg i.res.(0)}\n
;!
mov{emit_string comp} %xcc, 1, {emit_reg i.res.(0)}\n
! end
! else begin
! let comp = name_for_int_comparison cmp
! and lbl = new_label() in
!
{emit_string comp},a {emit_label lbl}\n
;!
mov 1, {emit_reg i.res.(0)}\n
;!
mov 0, {emit_reg i.res.(0)}\n
;!
{emit_label lbl}:\n
! end
| Lop(Iintop_imm(Icheckbound, n)) ->
cmp {emit_reg i.arg.(0)}, {emit_int n}\n
;tleu 5\n
( 5 = ST_RANGE_CHECK *)*** 416,422 ****
| Lop(Inegf | Iabsf as op) ->
let instr = name_for_float_operation op in
{emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.res.(0)}\n
;!
fmovs {emit_reg(next_in_pair i.arg.(0))}, {emit_reg(next_in_pair i.res.(0))}\n
| Lop(Iaddf | Isubf | Imulf | Idivf as op) ->
let instr = name_for_float_operation op in
{emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n
--- 518,525 ----
| Lop(Inegf | Iabsf as op) ->
let instr = name_for_float_operation op in
{emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.res.(0)}\n
;! if !arch_version != SPARC_V9 then
!
fmovs {emit_reg(next_in_pair i.arg.(0))}, {emit_reg(next_in_pair i.res.(0))}\n
| Lop(Iaddf | Isubf | Imulf | Idivf as op) ->
let instr = name_for_float_operation op in
{emit_string instr} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n
*** 432,439 ****
st %f30, [%sp + 96]\n
;ld [%sp + 96], {emit_reg i.res.(0)}\n
;add %sp, 8, %sp\n
! | Lop(Ispecific sop) ->
! fatal_error "Emit: specific"
| Lreloadretaddr ->
let n = frame_size() in
ld [%sp + {emit_int(n - 4 + 96)}], %o7\n
--- 535,550 ----
st %f30, [%sp + 96]\n
;ld [%sp + 96], {emit_reg i.res.(0)}\n
;add %sp, 8, %sp\n
! | Lop(Ispecific(Icmov(cmp, n1, n2))) ->
! let suffix = name_for_int_movcc (Isigned cmp) in
!
cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n
;!
mov {emit_int n1}, {emit_reg i.res.(0)}\n
;!
mov{emit_string suffix} %icc, {emit_int n2}, {emit_reg i.res.(0)}\n
;! | Lop(Ispecific(Icmov_imm(cmp, op2, n1, n2))) ->
! let suffix = name_for_int_movcc (Isigned cmp) in
!
cmp {emit_reg i.arg.(0)}, {emit_int op2}\n
;!
mov {emit_int n1}, {emit_reg i.res.(0)}\n
;!
mov{emit_string suffix} %icc, {emit_int n2}, {emit_reg i.res.(0)}\n
;| Lreloadretaddr ->
let n = frame_size() in
ld [%sp + {emit_int(n - 4 + 96)}], %o7\n
*** 440,446 ****
| Lreturn ->
let n = frame_size() in
retl\n
;!
add %sp, {emit_int n}, %sp\n
| Llabel lbl ->
{emit_label lbl}:\n
| Lbranch lbl ->
--- 551,560 ----
| Lreturn ->
let n = frame_size() in
retl\n
;! if n = 0 then
!
nop\n
! else
!
add %sp, {emit_int n}, %sp\n
| Llabel lbl ->
{emit_label lbl}:\n
| Lbranch lbl ->
*** 465,471 ****
| Ifloattest(cmp, neg) ->
let comp = name_for_float_comparison cmp neg in
fcmpd {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n
;!
nop\n
;{emit_string comp} {emit_label lbl}\n
| Ioddtest ->
andcc {emit_reg i.arg.(0)}, 1, %g0\n
;--- 579,586 ----
| Ifloattest(cmp, neg) ->
let comp = name_for_float_comparison cmp neg in
fcmpd {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n
;! if !arch_version = SPARC_V9 then
!
nop\n
;{emit_string comp} {emit_label lbl}\n
| Ioddtest ->
andcc {emit_reg i.arg.(0)}, 1, %g0\n
;*** 544,549 ****
--- 659,665 ----
| Iintop(op) -> is_one_instr_op op
| Iintop_imm(op, _) -> is_one_instr_op op
| Iaddf | Isubf | Imulf | Idivf -> true
*** 595,601 ****
--- 711,720 ----
.text\n
;.align 4\n
;.global {emit_symbol fundecl.fun_name}\n
;{emit_symbol fundecl.fun_name}:\n
;let n = frame_size() in
if n > 0 then
sub %sp, {emit_int n}, %sp\n
;*** 603,608 ****
--- 722,728 ----
st %o7, [%sp + {emit_int(n - 4 + 96)}]\n
;{emit_label !tailrec_entry_point}:\n
;emit_all fundecl.fun_body;
List.iter emit_float_constant !float_constants
(* Emission of data *)
*** 674,681 ****
--- 794,805 ----
{emit_symbol lbl_end}:\n
;.word 0\n
;let lbl = Compilenv.current_unit_name() ^ "__frametable" in
.global {emit_symbol lbl}\n
;{emit_symbol lbl}:\n
;.word {emit_int (List.length !frame_descriptors)}\n
;List.iter emit_frame !frame_descriptors;
frame_descriptors := []
*** asmcomp/sparc/arch.ml.orig Mon Jul 22 12:37:54 2002
--- asmcomp/sparc/arch.ml Tue Sep 10 10:23:13 2002
*** 17,29 ****
open Misc
open Format
! type specific_operation = unit (* None worth mentioning *)
(* Addressing modes *)
type addressing_mode =
Ibased of string * int (* symbol + displ )
| Iindexed of int ( reg + displ *)
(* Sizes, endianness *)
--- 17,41 ----
open Misc
open Format
! (* SPARC V8 adds multiply and divide.
! SPARC V9 adds double precision float operations, conditional
! move, and more instructions that are only useful in 64 bit mode.
! Sun calls 32 bit V9 "V8+". *)
! type arch_version = SPARC_V7 | SPARC_V8 | SPARC_V9
let arch_version = ref SPARC_V9
(* V9 conditional move *)
type specific_operation =
| Icmov_imm of Cmm.comparison * int * int * int
(* Addressing modes *)
type addressing_mode =
Ibased of string * int (* symbol + displ )
| Iindexed of int ( reg + displ *)
| Iindexed2 of int
(* Sizes, endianness *)
*** 41,50 ****
--- 53,65 ----
match addr with
Ibased(s, n) -> Ibased(s, n + delta)
| Iindexed n -> Iindexed(n + delta)
let num_args_addressing = function
Ibased(s, n) -> 0
| Iindexed n -> 1
(* Printing operations and addressing modes *)
*** 56,61 ****
--- 71,80 ----
| Iindexed n ->
let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in
fprintf ppf "%a%s" printreg arg.(0) idx
| Iindexed2 0 ->
| Iindexed2 _ ->
let print_specific_operation printreg op ppf arg =
Misc.fatal_error "Arch_sparc.print_specific_operation"
*** asmcomp/sparc/selection.ml.orig Thu Dec 28 08:03:03 2000
--- asmcomp/sparc/selection.ml Sun Sep 15 09:57:48 2002
*** 35,63 ****
(Iindexed n, arg)
| Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int n])]) ->
(Iindexed n, Cop(Cadda, [arg1; arg2]))
| arg ->
(Iindexed 0, arg)
method select_operation op args =
! match (op, args) with
! (* Multiplication, division and modulus are turned into
calls to C library routines, except if the dividend is a power of 2. *)
! (Cmuli, [arg; Cconst_int n]) when n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Ilsl, Misc.log2 n), [arg])
! | (Cmuli, [Cconst_int n; arg]) when n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Ilsl, Misc.log2 n), [arg])
! | (Cmuli, _) ->
(Iextcall(".umul", false), args)
! | (Cdivi, [arg; Cconst_int n])
when self#is_immediate n && n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Idiv, n), [arg])
! | (Cdivi, _) ->
(Iextcall(".div", false), args)
! | (Cmodi, [arg; Cconst_int n])
when self#is_immediate n && n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Imod, n), [arg])
! | (Cmodi, _) ->
(Iextcall(".rem", false), args)
| _ ->
super#select_operation op args
--- 35,80 ----
(Iindexed n, arg)
| Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int n])]) ->
(Iindexed n, Cop(Cadda, [arg1; arg2]))
| Cop(Cadda, [arg1; arg2]) ->
| arg ->
(Iindexed 0, arg)
method select_operation op args =
! match (!arch_version, op, args) with
! (* For SPARC V7 multiplication, division and modulus are turned into
calls to C library routines, except if the dividend is a power of 2. )
! (SPARC_V7, Cmuli, [arg; Cconst_int n]) when n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Ilsl, Misc.log2 n), [arg])
! | (SPARC_V7, Cmuli, [Cconst_int n; arg]) when n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Ilsl, Misc.log2 n), [arg])
! | (SPARC_V7, Cmuli, ) ->
(Iextcall(".umul", false), args)
! | (, Cdivi, [arg; Cconst_int n])
when self#is_immediate n && n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Idiv, n), [arg])
! | (SPARC_V7, Cdivi, ) ->
(Iextcall(".div", false), args)
! | (, Cmodi, [arg; Cconst_int n])
when self#is_immediate n && n = 1 lsl (Misc.log2 n) ->
(Iintop_imm(Imod, n), [arg])
! ( Remainder on SPARC is slow and requires 5-7 instructions to calculate.
! It is not worth generating inline code. *)
! | (_, Cmodi, _) ->
(Iextcall(".rem", false), args)
| (SPARC_V9, Caddi, [Cop(Clsl, [Cop(Ccmpi(c),[op1;Cconst_int op2]); Cconst_int n1]); Cconst_int n2])
| (SPARC_V9, Caddi, [Cop(Clsl, [Cop(Ccmpi(c),oplist); Cconst_int n1]); Cconst_int n2])
| (SPARC_V9, Clsl, [Cop(Ccmpi(c),[op1;Cconst_int op2]); Cconst_int n])
| (SPARC_V9, Clsl, [Cop(Ccmpi(c),el); Cconst_int n])
| _ ->
super#select_operation op args
*** asmrun/sparc.S.orig Fri Feb 8 11:55:33 2002
--- asmrun/sparc.S Thu Sep 19 16:00:43 2002
*** 72,77 ****
--- 72,88 ----
#endif
#define Alloc_ptr %l6
#define Alloc_limit %l7
*** 85,96 ****
--- 96,115 ----
.text
.global Caml_alloc
.global Caml_call_gc
/* Required size in %g2 */
Caml_alloc:
#ifdef INDIRECT_LIMIT
ld [Alloc_limit], %g1
sub Alloc_ptr, %g2, Alloc_ptr
cmp Alloc_ptr, %g1
#else
#endif
*** 112,117 ****
--- 131,156 ----
sub %sp, 204 + 158, %sp
/* Save int regs on stack and save it into caml_gc_regs /
L100: add %sp, 96 + 158, %g2
std %o0, [%g2]
std %o2, [%g2 + 0x8]
std %o4, [%g2 + 0x10]
*** 120,125 ****
--- 159,165 ----
std %i4, [%g2 + 0x28]
std %l0, [%g2 + 0x30]
std %l2, [%g2 + 0x38]
st %l4, [%g2 + 0x40]
st %g3, [%g2 + 0x44]
st %g4, [%g2 + 0x48]
*** 146,151 ****
--- 186,209 ----
nop
/* Restore all regs used by the code generator /
add %sp, 96 + 158, %g2
ldd [%g2], %o0
ldd [%g2 + 0x8], %o2
ldd [%g2 + 0x10], %o4
*** 154,159 ****
--- 212,218 ----
ldd [%g2 + 0x28], %i4
ldd [%g2 + 0x30], %l0
ldd [%g2 + 0x38], %l2
ld [%g2 + 0x40], %l4
ld [%g2 + 0x44], %g3
ld [%g2 + 0x48], %g4
*** 177,185 ****
--- 236,250 ----
Load(Young_ptr, Alloc_ptr)
/* Allocate space for block */
Load(Caml_required_size, %g2)
ld [Alloc_limit], %g1
sub Alloc_ptr, %g2, Alloc_ptr
cmp Alloc_ptr, %g1 /* Check that we have enough free space */
blu L100 /* If not, call GC again /
nop
/ Return to caller */
*** 190,195 ****
--- 255,261 ----
/* Call a C function from Caml */
Caml_c_call:
/ Record lowest stack address and return address */
*** 212,217 ****
--- 278,284 ----
/* Start the Caml program */
/* Save all callee-save registers */
save %sp, -96, %sp
*** 225,235 ****
Load(Caml_bottom_of_stack, %l0)
Load(Caml_last_return_address, %l1)
Load(Caml_gc_regs, %l3)
! std %l0, [%sp + 96]
! st %l3, [%sp + 104]
/* Set up a trap frame to catch exceptions escaping the Caml code /
call L111
! nop
b L110
nop
L111: sub %sp, 8, %sp
--- 292,302 ----
Load(Caml_bottom_of_stack, %l0)
Load(Caml_last_return_address, %l1)
Load(Caml_gc_regs, %l3)
! st %l0, [%sp + 96]
! st %l1, [%sp + 100]
/ Set up a trap frame to catch exceptions escaping the Caml code */
call L111
! st %l3, [%sp + 104]
b L110
nop
L111: sub %sp, 8, %sp
*** 239,245 ****
--- 306,316 ----
mov %sp, Exn_ptr
/* Reload allocation pointers */
Load(Young_ptr, Alloc_ptr)
Address(Young_limit, Alloc_limit)
/* Call the Caml code */
L109: call %l2
nop
*** 248,254 ****
add %sp, 8, %sp
Store(Exn_ptr, Caml_exception_pointer)
/* Pop callback link, restoring the global variables /
! L112: ldd [%sp + 96], %l0
ld [%sp + 104], %l2
Store(%l0, Caml_bottom_of_stack)
Store(%l1, Caml_last_return_address)
--- 319,326 ----
add %sp, 8, %sp
Store(Exn_ptr, Caml_exception_pointer)
/ Pop callback link, restoring the global variables */
! L112: ld [%sp + 96], %l0
! ld [%sp + 100], %l1
ld [%sp + 104], %l2
Store(%l0, Caml_bottom_of_stack)
Store(%l1, Caml_last_return_address)
*** 256,277 ****
add %sp, 16, %sp
/* Save allocation pointer */
Store(Alloc_ptr, Young_ptr)
! restore
L110:
/* The trap handler /
Store(Exn_ptr, Caml_exception_pointer)
/ Encode exception bucket as an exception result */
! nop
/* Raise an exception from C */
Raise_caml_exception:
/* Save exception bucket in a register outside the reg windows /
mov %o0, %g2
--- 328,347 ----
add %sp, 16, %sp
/ Save allocation pointer /
Store(Alloc_ptr, Young_ptr)
/ Reload callee-save registers and return /
ret
! restore %o0, 0, %o0 / copy %o0 in this window to caller's %o0 /
L110:
/ The trap handler /
Store(Exn_ptr, Caml_exception_pointer)
/ Encode exception bucket as an exception result */
b L112
! or %o0, 2, %o0
/* Raise an exception from C */
/* Save exception bucket in a register outside the reg windows */
mov %o0, %g2
*** 288,294 ****
--- 358,368 ----
L107:
/* Reload allocation registers */
Load(Young_ptr, Alloc_ptr)
Address(Young_limit, Alloc_limit)
/* Branch to exception handler */
mov %g3, %sp
ld [%sp + 96], %g1
*** 338,345 ****
--- 412,424 ----
b L108
or %l2, %lo(Caml_apply3), %l2
.data
.global System_frametable
.word 1 /* one descriptor /
.word L109 / return address into callback */
*** asmrun/signals.c.orig Mon May 6 08:02:26 2002
--- asmrun/signals.c Sun Sep 1 13:17:19 2002
*** 32,37 ****
--- 32,39 ----
#include <sys/resource.h>
#endif
typedef void (*sighandler)(int sig);
extern sighandler win32_signal(int sig, sighandler action);
*** 57,62 ****
--- 59,69 ----
#endif
#endif
volatile int pending_signal = 0;
volatile int force_major_slice = 0;
*** 154,159 ****
--- 161,184 ----
async_signal_mode = 0;
}
void handle_signal(int sig, int code, struct sigcontext * context)
#elif defined(TARGET_power) && defined(SYS_aix)
*** 162,167 ****
--- 187,194 ----
void handle_signal(int sig, struct sigcontext * context)
#elif defined(TARGET_power) && defined(SYS_rhapsody)
void handle_signal(int sig, int code, struct sigcontext * context)
#else
void handle_signal(int sig)
#endif
*** 205,210 ****
--- 232,242 ----
/* Cached in register 30 */
CONTEXT_GPR(context, 30) = (unsigned long) young_limit;
#endif
}
}
}
*** 326,332 ****
--- 358,368 ----
#ifdef POSIX_SIGNALS
sigact.sa_handler = act;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
if (sigaction(sig, &sigact, &oldsigact) == -1) sys_error(NO_ARG);
oldact = oldsigact.sa_handler;
#else
*** 375,397 ****
}
#endif
#if defined(TARGET_sparc) && defined(SYS_solaris)
static void trap_handler(int sig, siginfo_t * info, void * arg)
{
ucontext_t * context;
! int * sp;
! if (info->si_code != ILL_ILLTRP) {
! fprintf(stderr, "Fatal error: illegal instruction, code 0x%x\n",
! info->si_code);
! exit(100);
! }
! /* Recover young_ptr and caml_exception_pointer from the %l5 and %l6 regs */
context = (ucontext_t *) arg;
! sp = (int *) context->uc_mcontext.gregs[REG_SP];
! caml_exception_pointer = (char *) sp[5];
! young_ptr = (char *) sp[6];
! array_bound_error();
}
#endif
--- 411,478 ----
}
#endif
{
ucontext_t * context;
! long * sp;
! int code = info->si_code;
! switch (sig)
! {
! case SIGILL:
! if (code != ILL_ILLTRP) {
! fprintf(stderr, "Fatal error: illegal instruction, code 0x%x\n",
! code);
! /* Illegal instruction exceptions occur before the instruction
! completes and will recur on return from the signal handler. /
! reraise(SIGILL, code == 0);
! return;
! /exit(100);/
! }
! break;
! case SIGFPE:
! if (code != FPE_INTDIV) {
! / Floating point exceptions occur after the instruction completes
! and will not recur on return from the signal handler. /
! reraise(SIGFPE, 1);
! return;
! }
! break;
! }
! / Recover young_ptr and caml_exception_pointer from the %l5 and %l6 regs. */
context = (ucontext_t *) arg;
! #ifdef __sparcv9
! sp = (long *) (CONTEXT_GPR(context, REG_SP) + 2047);
! #else
! sp = (long *) (CONTEXT_GPR(context, REG_SP));
! #endif
! caml_exception_pointer = (char ) sp[5]; / %l5 */
! young_ptr = (char ) sp[6]; / %l6 */
! switch (sig)
! {
! case SIGILL:
! array_bound_error();
! break;
! case SIGFPE:
! division_by_zero_error();
! break;
! }
}
#endif
*** 515,522 ****
--- 596,613 ----
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO | SA_NODEFER;
sigaction(SIGILL, &act, NULL);
#endif
#if defined(TARGET_power)
{
struct sigaction act;
*** asmrun/fail.c.orig Fri Dec 7 08:39:19 2001
--- asmrun/fail.c Sun Sep 1 13:17:53 2002
*** 176,178 ****
--- 182,197 ----
array_bound_error_bucket.arg = (value) array_bound_error_msg.data;
mlraise((value) &array_bound_error_bucket.exn);
}
+
The text was updated successfully, but these errors were encountered: