diff options
Diffstat (limited to 'asmcomp')
-rw-r--r-- | asmcomp/alpha/emit.mlp | 4 | ||||
-rw-r--r-- | asmcomp/amd64/emit.mlp | 48 | ||||
-rw-r--r-- | asmcomp/amd64/proc.ml | 3 | ||||
-rw-r--r-- | asmcomp/arm/emit.mlp | 3 | ||||
-rw-r--r-- | asmcomp/asmlink.ml | 1 | ||||
-rw-r--r-- | asmcomp/emitaux.ml | 21 | ||||
-rw-r--r-- | asmcomp/emitaux.mli | 3 | ||||
-rw-r--r-- | asmcomp/hppa/emit.mlp | 8 | ||||
-rw-r--r-- | asmcomp/i386/emit.mlp | 11 | ||||
-rw-r--r-- | asmcomp/ia64/emit.mlp | 4 | ||||
-rw-r--r-- | asmcomp/mips/emit.mlp | 5 | ||||
-rw-r--r-- | asmcomp/power/emit.mlp | 15 | ||||
-rw-r--r-- | asmcomp/sparc/emit.mlp | 7 |
13 files changed, 84 insertions, 49 deletions
diff --git a/asmcomp/alpha/emit.mlp b/asmcomp/alpha/emit.mlp index b3890a4482..3c04b7a47a 100644 --- a/asmcomp/alpha/emit.mlp +++ b/asmcomp/alpha/emit.mlp @@ -793,9 +793,9 @@ let emit_item = function long decimal constants *) ` .quad 0x{emit_string(Nativeint.format "%x" n)}\n` | Csingle f -> - ` .float {emit_string f}\n` + emit_float32_directive ".long" f | Cdouble f -> - ` .double {emit_string f}\n` + emit_float64_directive ".quad" f | Csymbol_address s -> ` .quad {emit_symbol s}\n` | Clabel_address lbl -> diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp index 11bf78224b..950748d6e2 100644 --- a/asmcomp/amd64/emit.mlp +++ b/asmcomp/amd64/emit.mlp @@ -575,33 +575,26 @@ let emit_instr fallthrough i = end | Lswitch jumptbl -> let lbl = new_label() in - if !pic_code || !Clflags.dlcode then begin - (* PR#4424: r11 is known to be clobbered by the Lswitch, - meaning that no variable that is live across the Lswitch - is assigned to r11. However, the argument to Lswitch - can still be assigned to r11, so we need to special-case - this situation. *) - if i.arg.(0).loc = Reg 9 (* ie r11, cf amd64/proc.ml *) then begin - ` salq $3, %r11\n`; - ` pushq %r11\n`; - ` leaq {emit_label lbl}(%rip), %r11\n`; - ` addq 0(%rsp), %r11\n`; - ` addq $8, %rsp\n`; - ` jmp *(%r11)\n` - end else begin - ` leaq {emit_label lbl}(%rip), %r11\n`; - ` jmp *(%r11, {emit_reg i.arg.(0)}, 8)\n` - end - end else begin - ` jmp *{emit_label lbl}(, {emit_reg i.arg.(0)}, 8)\n` - end; + (* rax and rdx are clobbered by the Lswitch, + meaning that no variable that is live across the Lswitch + is assigned to rax or rdx. However, the argument to Lswitch + can still be assigned to one of these two registers, so + we must be careful not to clobber it before use. *) + let (tmp1, tmp2) = + if i.arg.(0).loc = Reg 0 (* rax *) + then (phys_reg 4 (*rdx*), phys_reg 0 (*rax*)) + else (phys_reg 0 (*rax*), phys_reg 4 (*rdx*)) in + ` leaq {emit_label lbl}(%rip), {emit_reg tmp1}\n`; + ` movslq ({emit_reg tmp1}, {emit_reg i.arg.(0)}, 4), {emit_reg tmp2}\n`; + ` addq {emit_reg tmp2}, {emit_reg tmp1}\n`; + ` jmp *{emit_reg tmp1}\n`; if macosx then ` .const\n` else ` .section .rodata\n`; - emit_align 8; + emit_align 4; `{emit_label lbl}:`; for i = 0 to Array.length jumptbl - 1 do - ` .quad {emit_label jumptbl.(i)}\n` + ` .long {emit_label jumptbl.(i)} - {emit_label lbl}\n` done; ` .text\n` | Lsetuptrap lbl -> @@ -634,7 +627,8 @@ let rec emit_all fallthrough i = (* Emission of the floating-point constants *) let emit_float_constant (lbl, cst) = - `{emit_label lbl}: .double {emit_string cst}\n` + `{emit_label lbl}:`; + emit_float64_directive ".quad" cst (* Emission of the profiling prelude *) @@ -667,7 +661,9 @@ let fundecl fundecl = bound_error_call := 0; ` .text\n`; emit_align 16; - if macosx && is_generic_function fundecl.fun_name + if macosx + && not !Clflags.output_c_object + && is_generic_function fundecl.fun_name then (* PR#4690 *) ` .private_extern {emit_symbol fundecl.fun_name}\n` else @@ -712,9 +708,9 @@ let emit_item = function | Cint n -> ` .quad {emit_nativeint n}\n` | Csingle f -> - ` .float {emit_string f}\n` + emit_float32_directive ".long" f | Cdouble f -> - ` .double {emit_string f}\n` + emit_float64_directive ".quad" f | Csymbol_address s -> ` .quad {emit_symbol s}\n` | Clabel_address lbl -> diff --git a/asmcomp/amd64/proc.ml b/asmcomp/amd64/proc.ml index da2f886bbc..c0807b88d4 100644 --- a/asmcomp/amd64/proc.ml +++ b/asmcomp/amd64/proc.ml @@ -92,7 +92,6 @@ let phys_reg n = let rax = phys_reg 0 let rcx = phys_reg 5 let rdx = phys_reg 4 -let r11 = phys_reg 9 let rxmm15 = phys_reg 115 let stack_slot slot ty = @@ -170,7 +169,7 @@ let destroyed_at_oper = function | Iop(Istore(Single, _)) -> [| rxmm15 |] | Iop(Ialloc _ | Iintop(Icomp _) | Iintop_imm((Idiv|Imod|Icomp _), _)) -> [| rax |] - | Iswitch(_, _) when !pic_code || !Clflags.dlcode -> [| r11 |] + | Iswitch(_, _) -> [| rax; rdx |] | _ -> [||] let destroyed_at_raise = all_phys_regs diff --git a/asmcomp/arm/emit.mlp b/asmcomp/arm/emit.mlp index 5d9e5cf7cc..a2a6b4dad3 100644 --- a/asmcomp/arm/emit.mlp +++ b/asmcomp/arm/emit.mlp @@ -585,6 +585,9 @@ let emit_item = function | Csingle f -> ` .float {emit_string f}\n` | Cdouble f -> + (* FIXME: this version of the ARM port is mixed-endian, so we + use .double instead of emit_float64_directive. The next + version is little-endian, so we'll use emit_float64 then. *) ` .align 0\n`; ` .double {emit_string f}\n` | Csymbol_address s -> diff --git a/asmcomp/asmlink.ml b/asmcomp/asmlink.ml index c7b9ec87ea..c1b03106a0 100644 --- a/asmcomp/asmlink.ml +++ b/asmcomp/asmlink.ml @@ -259,6 +259,7 @@ let link_shared ppf objfiles output_name = (fun (info, file_name, crc) -> check_consistency file_name info crc) units_tolink; Clflags.ccobjs := !Clflags.ccobjs @ !lib_ccobjs; + Clflags.ccopts := !lib_ccopts @ !Clflags.ccopts; let objfiles = List.rev (List.map object_file_name objfiles) @ !Clflags.ccobjs in diff --git a/asmcomp/emitaux.ml b/asmcomp/emitaux.ml index e851c8187d..35338eed9b 100644 --- a/asmcomp/emitaux.ml +++ b/asmcomp/emitaux.ml @@ -93,6 +93,27 @@ let emit_bytes_directive directive s = done; if !pos > 0 then emit_char '\n' +(* PR#4813: assemblers do strange things with float literals indeed, + so we convert to IEEE representation ourselves and emit float + literals as 32- or 64-bit integers. *) + +let emit_float64_directive directive f = + let x = Int64.bits_of_float (float_of_string f) in + emit_printf "\t%s\t0x%Lx\n" directive x + +let emit_float64_split_directive directive f = + let x = Int64.bits_of_float (float_of_string f) in + let lo = Int64.logand x 0xFFFF_FFFFL + and hi = Int64.shift_right_logical x 32 in + emit_printf "\t%s\t0x%Lx, 0x%Lx\n" + directive + (if Arch.big_endian then hi else lo) + (if Arch.big_endian then lo else hi) + +let emit_float32_directive directive f = + let x = Int32.bits_of_float (float_of_string f) in + emit_printf "\t%s\t0x%lx\n" directive x + (* Record live pointers at call points *) type frame_descr = diff --git a/asmcomp/emitaux.mli b/asmcomp/emitaux.mli index 112e276a12..4f666be736 100644 --- a/asmcomp/emitaux.mli +++ b/asmcomp/emitaux.mli @@ -25,6 +25,9 @@ val emit_char: char -> unit val emit_string_literal: string -> unit val emit_string_directive: string -> string -> unit val emit_bytes_directive: string -> string -> unit +val emit_float64_directive: string -> string -> unit +val emit_float64_split_directive: string -> string -> unit +val emit_float32_directive: string -> string -> unit type frame_descr = { fd_lbl: int; (* Return address *) diff --git a/asmcomp/hppa/emit.mlp b/asmcomp/hppa/emit.mlp index b8880fc4fd..2c81b78925 100644 --- a/asmcomp/hppa/emit.mlp +++ b/asmcomp/hppa/emit.mlp @@ -299,7 +299,9 @@ let emit_float_constants () = ` .text\n`; emit_align 8; List.iter - (fun (lbl, cst) -> `{emit_label lbl}: .double {emit_string cst}\n`) + (fun (lbl, cst) -> + `{emit_label lbl}:`; + emit_float64_split_directive ".long" cst) !float_constants; float_constants := [] @@ -972,9 +974,9 @@ let emit_item = function | Cint n -> ` .long {emit_nativeint n}\n` | Csingle f -> - ` .float {emit_string f}\n` + emit_float32_directive ".long" f | Cdouble f -> - ` .double {emit_string f}\n` + emit_float64_split_directive ".long" f | Csymbol_address s -> use_symbol s; ` .long {emit_symbol s}\n` diff --git a/asmcomp/i386/emit.mlp b/asmcomp/i386/emit.mlp index 9f43155613..5d4802faa3 100644 --- a/asmcomp/i386/emit.mlp +++ b/asmcomp/i386/emit.mlp @@ -815,7 +815,8 @@ let rec emit_all fallthrough i = let emit_float_constant (lbl, cst) = ` .data\n`; - `{emit_label lbl}: .double {emit_string cst}\n` + `{emit_label lbl}:`; + emit_float64_split_directive ".long" cst (* Emission of external symbol references (for MacOSX) *) @@ -888,7 +889,9 @@ let fundecl fundecl = bound_error_call := 0; ` .text\n`; emit_align 16; - if macosx && is_generic_function fundecl.fun_name + if macosx + && not !Clflags.output_c_object + && is_generic_function fundecl.fun_name then (* PR#4690 *) ` .private_extern {emit_symbol fundecl.fun_name}\n` else @@ -928,9 +931,9 @@ let emit_item = function | Cint n -> ` .long {emit_nativeint n}\n` | Csingle f -> - ` .float {emit_string f}\n` + emit_float32_directive ".long" f | Cdouble f -> - ` .double {emit_string f}\n` + emit_float64_split_directive ".long" f | Csymbol_address s -> ` .long {emit_symbol s}\n` | Clabel_address lbl -> diff --git a/asmcomp/ia64/emit.mlp b/asmcomp/ia64/emit.mlp index e59f711bc5..fb84e9e08c 100644 --- a/asmcomp/ia64/emit.mlp +++ b/asmcomp/ia64/emit.mlp @@ -1287,9 +1287,9 @@ let emit_item = function | Cint n -> ` data8 {emit_nativeint n}\n` | Csingle f -> - ` real4 {emit_string f}\n` + emit_float32_directive "data4" f | Cdouble f -> - ` real8 {emit_string f}\n` + emit_float64_directive "data8" f | Csymbol_address s -> ` data8 {emit_symbol s}#\n` | Clabel_address lbl -> diff --git a/asmcomp/mips/emit.mlp b/asmcomp/mips/emit.mlp index 198f6265d7..6908ccfd48 100644 --- a/asmcomp/mips/emit.mlp +++ b/asmcomp/mips/emit.mlp @@ -527,10 +527,9 @@ let emit_item = function | Cint n -> ` .word {emit_nativeint n}\n` | Csingle f -> - ` .float {emit_string f}\n` + emit_float32_directive ".word" f | Cdouble f -> - ` .align 0\n`; (* Prevent alignment on 8-byte boundary *) - ` .double {emit_string f}\n` + emit_float64_split_directive ".word" f | Csymbol_address s -> ` .word {emit_symbol s}\n` | Clabel_address lbl -> diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp index baab697ae0..ec3abbde47 100644 --- a/asmcomp/power/emit.mlp +++ b/asmcomp/power/emit.mlp @@ -835,7 +835,9 @@ let fundecl fundecl = call_gc_label := 0; float_literals := []; int_literals := []; - if Config.system = "rhapsody" && is_generic_function fundecl.fun_name + if Config.system = "rhapsody" + && not !Clflags.output_c_object + && is_generic_function fundecl.fun_name then (* PR#4690 *) ` .private_extern {emit_symbol fundecl.fun_name}\n` else @@ -871,7 +873,10 @@ let fundecl fundecl = ` .align 3\n`; List.iter (fun (f, lbl) -> - `{emit_label lbl}: .double 0d{emit_string f}\n`) + `{emit_label lbl}:`; + if ppc64 + then emit_float64_directive ".quad" f + else emit_float64_split_directive ".long" f) !float_literals; List.iter (fun (n, lbl) -> @@ -902,9 +907,11 @@ let emit_item = function | Cint n -> ` {emit_string datag} {emit_nativeint n}\n` | Csingle f -> - ` .float 0d{emit_string f}\n` + emit_float32_directive ".long" f | Cdouble f -> - ` .double 0d{emit_string f}\n` + if ppc64 + then emit_float64_directive ".quad" f + else emit_float64_split_directive ".long" f | Csymbol_address s -> ` {emit_string datag} {emit_symbol s}\n` | Clabel_address lbl -> diff --git a/asmcomp/sparc/emit.mlp b/asmcomp/sparc/emit.mlp index 7393d9084e..f44f813e53 100644 --- a/asmcomp/sparc/emit.mlp +++ b/asmcomp/sparc/emit.mlp @@ -195,7 +195,8 @@ 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` + `{emit_label lbl}:`; + emit_float64_split_directive ".word" cst (* Emission of the profiling prelude *) let emit_profile () = @@ -723,9 +724,9 @@ let emit_item = function | Cint n -> ` .word {emit_nativeint n}\n` | Csingle f -> - ` .single 0r{emit_string f}\n` + emit_float32_directive ".word" f | Cdouble f -> - ` .double 0r{emit_string f}\n` + emit_float64_split_directive ".word" f | Csymbol_address s -> ` .word {emit_symbol s}\n` | Clabel_address lbl -> |