Blob Blame History Raw
From ab30529b723d451fd0ea8ac64d24fc417af55541 Mon Sep 17 00:00:00 2001
From: Nicolas Ojeda Bar <n.oje.bar@gmail.com>
Date: Wed, 23 Nov 2016 12:38:28 +0100
Subject: [PATCH 10/10] Another immediate range fix

---
 asmcomp/riscv/emit.mlp | 57 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 23 deletions(-)

diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp
index 97c49ce..6cc1908 100644
--- a/asmcomp/riscv/emit.mlp
+++ b/asmcomp/riscv/emit.mlp
@@ -85,14 +85,6 @@ let emit_reg = function
   | {loc = Reg r} -> emit_string (register_name r)
   | _ -> fatal_error "Emit.emit_reg"
 
-(* Output a stack reference *)
-
-let emit_stack r =
-  match r.loc with
-    Stack s ->
-      let ofs = slot_offset s (register_class r) in `{emit_int ofs}(sp)`
-  | _ -> fatal_error "Emit.emit_stack"
-
 (* Adjust sp by the given byte amount *)
 
 let emit_stack_adjustment = function
@@ -103,7 +95,27 @@ let emit_stack_adjustment = function
       `	li	{emit_reg reg_tmp1}, {emit_int n}\n`;
       `	add	sp, sp, {emit_reg reg_tmp1}\n`
 
-let emit_store src ofs =
+let reload_ra n =
+  let ofs = n - size_addr in
+  if is_immediate ofs then
+    `	{emit_string lg}	ra, {emit_int ofs}(sp)\n`
+  else begin
+    `	li	{emit_reg reg_tmp1}, {emit_int ofs}\n`;
+    `	add	{emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`;
+    `	{emit_string lg}	ra, 0({emit_reg reg_tmp1})\n`
+  end
+
+let store_ra n =
+  let ofs = n - size_addr in
+  if is_immediate ofs then
+    `	{emit_string stg}	ra, {emit_int(n - size_addr)}(sp)\n`
+  else begin
+    `	li	{emit_reg reg_tmp1}, {emit_int ofs}\n`;
+    `	add	{emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`;
+    `	{emit_string stg}	ra, 0({emit_reg reg_tmp1})\n`
+  end
+
+let emit_store stg src ofs =
   if is_immediate ofs then
     `	{emit_string stg}	{emit_reg src}, {emit_int ofs}(sp)\n`
   else begin
@@ -112,7 +124,7 @@ let emit_store src ofs =
     `	{emit_string stg}	{emit_reg src}, 0({emit_reg reg_tmp1})\n`
   end
 
-let emit_load dst ofs =
+let emit_load lg dst ofs =
   if is_immediate ofs then
     `	{emit_string lg}	{emit_reg dst}, {emit_int ofs}(sp)\n`
   else begin
@@ -265,14 +277,16 @@ let emit_instr i =
             `	fmv.d   {emit_reg dst}, {emit_reg src}\n`
         | {loc = Reg _; typ = (Val | Int | Addr)}, {loc = Stack s} ->
             let ofs = slot_offset s (register_class dst) in
-            emit_store src ofs
-        | {loc = Reg _; typ = Float}, {loc = Stack _} ->
-            `	fsd	{emit_reg src}, {emit_stack dst}\n`
+            emit_store stg src ofs
+        | {loc = Reg _; typ = Float}, {loc = Stack s} ->
+            let ofs = slot_offset s (register_class dst) in
+            emit_store "fsd" src ofs
         | {loc = Stack s; typ = (Val | Int | Addr)}, {loc = Reg _} ->
             let ofs = slot_offset s (register_class src) in
-            emit_load dst ofs
-        | {loc = Stack _; typ = Float}, {loc = Reg _} ->
-            `	fld	{emit_reg dst}, {emit_stack src}\n`
+            emit_load lg dst ofs
+        | {loc = Stack s; typ = Float}, {loc = Reg _} ->
+            let ofs = slot_offset s (register_class src) in
+            emit_load "fld" dst ofs
         | _ ->
             fatal_error "Emit: Imove"
       end
@@ -292,8 +306,7 @@ let emit_instr i =
       record_frame ~label i.live false i.dbg
   | Lop(Itailcall_ind {label_after = _}) ->
       let n = frame_size() in
-      if !contains_calls then
-        `	{emit_string lg}	ra, {emit_int(n - size_addr)}(sp)\n`;
+      if !contains_calls then reload_ra n;
       emit_stack_adjustment n;
       `	jr	{emit_reg i.arg.(0)}\n`
   | Lop(Itailcall_imm {func; label_after = _}) ->
@@ -301,8 +314,7 @@ let emit_instr i =
         `	j	{emit_label !tailrec_entry_point}\n`
       end else begin
         let n = frame_size() in
-        if !contains_calls then
-          `	{emit_string lg}	ra, {emit_int(n - size_addr)}(sp)\n`;
+        if !contains_calls then reload_ra n;
         emit_stack_adjustment n;
         `	tail	{emit_symbol func}\n`
       end
@@ -424,7 +436,7 @@ let emit_instr i =
       `	{emit_string instr}	{emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}\n`
   | Lreloadretaddr ->
       let n = frame_size () in
-      `	{emit_string lg}	ra, {emit_int(n - size_addr)}(sp)\n`
+      reload_ra n
   | Lreturn ->
       let n = frame_size() in
       emit_stack_adjustment n;
@@ -542,8 +554,7 @@ let fundecl fundecl =
   `{emit_symbol fundecl.fun_name}:\n`;
   let n = frame_size() in
   emit_stack_adjustment (-n);
-  if !contains_calls then
-    `	{emit_string stg}	ra, {emit_int(n - size_addr)}(sp)\n`;
+  if !contains_calls then store_ra n;
   `{emit_label !tailrec_entry_point}:\n`;
   emit_all fundecl.fun_body;
   List.iter emit_call_gc !call_gc_sites;
-- 
2.9.3