aboutsummaryrefslogtreecommitdiffstats
path: root/verilog/Asmexpand.ml
diff options
context:
space:
mode:
Diffstat (limited to 'verilog/Asmexpand.ml')
-rw-r--r--verilog/Asmexpand.ml59
1 files changed, 35 insertions, 24 deletions
diff --git a/verilog/Asmexpand.ml b/verilog/Asmexpand.ml
index 1b3961e0..b76ad3a3 100644
--- a/verilog/Asmexpand.ml
+++ b/verilog/Asmexpand.ml
@@ -408,24 +408,6 @@ let expand_builtin_inline name args res =
(* Float arithmetic *)
| ("__builtin_fsqrt" | "__builtin_sqrt"), [BA(FR a1)], BR(FR res) ->
emit (Psqrtsd (res,a1))
- | "__builtin_fmax", [BA(FR a1); BA(FR a2)], BR(FR res) ->
- if res = a1 then
- emit (Pmaxsd (res,a2))
- else if res = a2 then
- emit (Pmaxsd (res,a1))
- else begin
- emit (Pmovsd_ff (res,a1));
- emit (Pmaxsd (res,a2))
- end
- | "__builtin_fmin", [BA(FR a1); BA(FR a2)], BR(FR res) ->
- if res = a1 then
- emit (Pminsd (res,a2))
- else if res = a2 then
- emit (Pminsd (res,a1))
- else begin
- emit (Pmovsd_ff (res,a1));
- emit (Pminsd (res,a2))
- end
| "__builtin_fmadd", _, _ ->
expand_fma args res
(fun r1 r2 r3 -> Pfmadd132(r1, r2, r3))
@@ -491,7 +473,8 @@ let expand_builtin_inline name args res =
(* Vararg stuff *)
| "__builtin_va_start", [BA(IR a)], _ ->
assert (a = RDX);
- if Archi.ptr64 then expand_builtin_va_start_elf64 a
+ if Archi.win64 then expand_builtin_va_start_win64 a
+ else if Archi.ptr64 then expand_builtin_va_start_elf64 a
else expand_builtin_va_start_32 a
(* Synchronization *)
| "__builtin_membar", [], _ ->
@@ -522,7 +505,14 @@ let fixup_funcall_elf64 sg =
registers.
*)
-let copy_fregs_to_iregs args fr ir =
+let rec copy_fregs_to_iregs args fr ir =
+ match (ir, fr, args) with
+ | (i1 :: ir, f1 :: fr, (Tfloat | Tsingle) :: args) ->
+ emit (Pmovq_rf (i1, f1));
+ copy_fregs_to_iregs args fr ir
+ | (i1 :: ir, f1 :: fr, _ :: args) ->
+ copy_fregs_to_iregs args fr ir
+ | _ ->
()
let fixup_funcall_win64 sg =
@@ -530,8 +520,10 @@ let fixup_funcall_win64 sg =
copy_fregs_to_iregs sg.sig_args [XMM0; XMM1; XMM2; XMM3] [RCX; RDX; R8; R9]
let fixup_funcall sg =
- if Archi.ptr64 then
- fixup_funcall_elf64 sg
+ if Archi.ptr64
+ then if Archi.win64
+ then fixup_funcall_win64 sg
+ else fixup_funcall_elf64 sg
else ()
(* Expansion of instructions *)
@@ -539,7 +531,23 @@ let fixup_funcall sg =
let expand_instruction instr =
match instr with
| Pallocframe (sz, ofs_ra, ofs_link) ->
- if Archi.ptr64 then begin
+ if Archi.win64 then begin
+ let sz = sp_adjustment_win64 sz in
+ if is_current_function_variadic() then
+ (* Save parameters passed in registers in reserved stack area *)
+ emit (Pcall_s (intern_string "__compcert_va_saveregs",
+ {sig_args = []; sig_res = Tvoid; sig_cc = cc_default}));
+ (* Allocate frame *)
+ let sz' = Z.of_uint sz in
+ emit (Psubl_ri (RSP, sz'));
+ emit (Pcfi_adjust sz');
+ (* Stack chaining *)
+ let addr1 = linear_addr RSP (Z.of_uint (sz + 8)) in
+ let addr2 = linear_addr RSP ofs_link in
+ emit_leaq RAX addr1;
+ emit (Pmovq_mr (addr2, RAX));
+ current_function_stacksize := Int64.of_int (sz + 8)
+ end else if Archi.ptr64 then begin
let (sz, save_regs) = sp_adjustment_elf64 sz in
(* Allocate frame *)
let sz' = Z.of_uint sz in
@@ -572,7 +580,10 @@ let expand_instruction instr =
PrintAsmaux.current_function_stacksize := Int32.of_int sz
end
| Pfreeframe(sz, ofs_ra, ofs_link) ->
- if Archi.ptr64 then begin
+ if Archi.win64 then begin
+ let sz = sp_adjustment_win64 sz in
+ emit (Paddq_ri (RSP, Z.of_uint sz))
+ end else if Archi.ptr64 then begin
let (sz, _) = sp_adjustment_elf64 sz in
emit (Paddq_ri (RSP, Z.of_uint sz))
end else begin