diff options
Diffstat (limited to 'asmcomp/amd64/emit.mlp')
| -rw-r--r-- | asmcomp/amd64/emit.mlp | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp index e2a53465e5..08745799b0 100644 --- a/asmcomp/amd64/emit.mlp +++ b/asmcomp/amd64/emit.mlp @@ -576,33 +576,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 -> @@ -635,7 +628,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 *) @@ -668,7 +662,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 @@ -713,9 +709,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 -> |
