tstellar / rpms / ocaml

Forked from rpms/ocaml 3 years ago
Clone
Blob Blame History Raw
From 5bc92d0cdb5cb26b8d8d517f30914c2b18e85f2b Mon Sep 17 00:00:00 2001
From: Xavier Leroy <xavier.leroy@college-de-france.fr>
Date: Thu, 30 Apr 2020 16:19:16 +0200
Subject: [PATCH 7/7] Update C calling conventions to the RISC-V ELF psABI

The original implementation of loc_external_arguments and
loc_external_results was following an older ABI,
where an FP argument passed in an FP register "burns" an integer register.

In the ELF psABI, integer registers and FP registers are used independently,
as in the OCaml calling convention.  Plus, if all FP registers are used
but an integer register remains, the integer register is used to pass
the next FP argument.

Fixes: #9515
(cherry picked from commit ea6896f9f184305cc455d3af18cd1cb75cdcd93d)
---
 asmcomp/riscv/proc.ml | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/asmcomp/riscv/proc.ml b/asmcomp/riscv/proc.ml
index 70909cd83..4c7b58612 100644
--- a/asmcomp/riscv/proc.ml
+++ b/asmcomp/riscv/proc.ml
@@ -187,6 +187,8 @@ let loc_results res =
      first integer args in a0 .. a7
      first float args in fa0 .. fa7
      remaining args on stack.
+   A FP argument can be passed in an integer register if all FP registers
+   are exhausted but integer registers remain.
    Return values in a0 .. a1 or fa0 .. fa1. *)
 
 let external_calling_conventions
@@ -202,8 +204,7 @@ let external_calling_conventions
         | Val | Int | Addr as ty ->
             if !int <= last_int then begin
               loc.(i) <- [| phys_reg !int |];
-              incr int;
-              incr float;
+              incr int
             end else begin
               loc.(i) <- [| stack_slot (make_stack !ofs) ty |];
               ofs := !ofs + size_int
@@ -211,8 +212,10 @@ let external_calling_conventions
         | Float ->
             if !float <= last_float then begin
               loc.(i) <- [| phys_reg !float |];
-              incr float;
-              incr int;
+              incr float
+            end else if !int <= last_int then begin
+              loc.(i) <- [| phys_reg !int |];
+              incr int
             end else begin
               loc.(i) <- [| stack_slot (make_stack !ofs) Float |];
               ofs := !ofs + size_float
-- 
2.24.1