Blame SOURCES/0010-Fix-immediates-range-when-adjusting-indexing-sp.patch

813db4
From bf083b3beeb9a622017137c246d2cfa863056cc0 Mon Sep 17 00:00:00 2001
813db4
From: Nicolas Ojeda Bar <n.oje.bar@gmail.com>
813db4
Date: Tue, 22 Nov 2016 22:30:35 +0100
813db4
Subject: [PATCH 10/12] Fix immediates' range when adjusting/indexing sp
813db4
813db4
---
813db4
 asmcomp/riscv/arch.ml      |  3 +++
813db4
 asmcomp/riscv/emit.mlp     | 53 ++++++++++++++++++++++++++++++++++------------
813db4
 asmcomp/riscv/selection.ml |  2 +-
813db4
 3 files changed, 44 insertions(+), 14 deletions(-)
813db4
813db4
diff --git a/asmcomp/riscv/arch.ml b/asmcomp/riscv/arch.ml
813db4
index 61a38b1dd..22c807c49 100644
813db4
--- a/asmcomp/riscv/arch.ml
813db4
+++ b/asmcomp/riscv/arch.ml
813db4
@@ -32,6 +32,9 @@ let spacetime_node_hole_pointer_is_live_before = function
813db4
 type addressing_mode =
813db4
   | Iindexed of int                     (* reg + displ *)
813db4
 
813db4
+let is_immediate n =
813db4
+  (n <= 2047) && (n >= -2048)
813db4
+
813db4
 (* Sizes, endianness *)
813db4
 
813db4
 let big_endian = false
813db4
diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp
813db4
index 6d0e3aefd..97c49ce80 100644
813db4
--- a/asmcomp/riscv/emit.mlp
813db4
+++ b/asmcomp/riscv/emit.mlp
813db4
@@ -93,6 +93,34 @@ let emit_stack r =
813db4
       let ofs = slot_offset s (register_class r) in `{emit_int ofs}(sp)`
813db4
   | _ -> fatal_error "Emit.emit_stack"
813db4
 
813db4
+(* Adjust sp by the given byte amount *)
813db4
+
813db4
+let emit_stack_adjustment = function
813db4
+  | 0 -> ()
813db4
+  | n when is_immediate n ->
813db4
+      `	addi	sp, sp, {emit_int n}\n`
813db4
+  | n ->
813db4
+      `	li	{emit_reg reg_tmp1}, {emit_int n}\n`;
813db4
+      `	add	sp, sp, {emit_reg reg_tmp1}\n`
813db4
+
813db4
+let emit_store src ofs =
813db4
+  if is_immediate ofs then
813db4
+    `	{emit_string stg}	{emit_reg src}, {emit_int ofs}(sp)\n`
813db4
+  else begin
813db4
+    `	li	{emit_reg reg_tmp1}, {emit_int ofs}\n`;
813db4
+    `	add	{emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`;
813db4
+    `	{emit_string stg}	{emit_reg src}, 0({emit_reg reg_tmp1})\n`
813db4
+  end
813db4
+
813db4
+let emit_load dst ofs =
813db4
+  if is_immediate ofs then
813db4
+    `	{emit_string lg}	{emit_reg dst}, {emit_int ofs}(sp)\n`
813db4
+  else begin
813db4
+    `	li	{emit_reg reg_tmp1}, {emit_int ofs}\n`;
813db4
+    `	add	{emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`;
813db4
+    `	{emit_string lg}	{emit_reg dst}, 0({emit_reg reg_tmp1})\n`
813db4
+  end
813db4
+
813db4
 (* Record live pointers at call points *)
813db4
 
813db4
 let record_frame_label ?label live raise_ dbg =
813db4
@@ -218,6 +246,7 @@ let name_for_specific = function
813db4
 
813db4
 (* Name of current function *)
813db4
 let function_name = ref ""
813db4
+
813db4
 (* Entry point for tail recursive calls *)
813db4
 let tailrec_entry_point = ref 0
813db4
 
813db4
@@ -234,12 +263,14 @@ let emit_instr i =
813db4
             `	mv      {emit_reg dst}, {emit_reg src}\n`
813db4
         | {loc = Reg _; typ = Float}, {loc = Reg _; typ = Float} ->
813db4
             `	fmv.d   {emit_reg dst}, {emit_reg src}\n`
813db4
-        | {loc = Reg _; typ = (Val | Int | Addr)}, {loc = Stack _} ->
813db4
-            `	{emit_string stg}	{emit_reg src}, {emit_stack dst}\n`
813db4
+        | {loc = Reg _; typ = (Val | Int | Addr)}, {loc = Stack s} ->
813db4
+            let ofs = slot_offset s (register_class dst) in
813db4
+            emit_store src ofs
813db4
         | {loc = Reg _; typ = Float}, {loc = Stack _} ->
813db4
             `	fsd	{emit_reg src}, {emit_stack dst}\n`
813db4
-        | {loc = Stack _; typ = (Val | Int | Addr)}, {loc = Reg _ } ->
813db4
-            `	{emit_string lg}	{emit_reg dst}, {emit_stack src}\n`
813db4
+        | {loc = Stack s; typ = (Val | Int | Addr)}, {loc = Reg _} ->
813db4
+            let ofs = slot_offset s (register_class src) in
813db4
+            emit_load dst ofs
813db4
         | {loc = Stack _; typ = Float}, {loc = Reg _} ->
813db4
             `	fld	{emit_reg dst}, {emit_stack src}\n`
813db4
         | _ ->
813db4
@@ -263,8 +294,7 @@ let emit_instr i =
813db4
       let n = frame_size() in
813db4
       if !contains_calls then
813db4
         `	{emit_string lg}	ra, {emit_int(n - size_addr)}(sp)\n`;
813db4
-      if n > 0 then
813db4
-        `	addi	sp, sp, {emit_int n}\n`;
813db4
+      emit_stack_adjustment n;
813db4
       `	jr	{emit_reg i.arg.(0)}\n`
813db4
   | Lop(Itailcall_imm {func; label_after = _}) ->
813db4
       if func = !function_name then begin
813db4
@@ -273,8 +303,7 @@ let emit_instr i =
813db4
         let n = frame_size() in
813db4
         if !contains_calls then
813db4
           `	{emit_string lg}	ra, {emit_int(n - size_addr)}(sp)\n`;
813db4
-        if n > 0 then
813db4
-          `	addi	sp, sp, {emit_int n}\n`;
813db4
+        emit_stack_adjustment n;
813db4
         `	tail	{emit_symbol func}\n`
813db4
       end
813db4
   | Lop(Iextcall{func; alloc = true; label_after = label}) ->
813db4
@@ -285,7 +314,7 @@ let emit_instr i =
813db4
       `	call	{emit_symbol func}\n`
813db4
   | Lop(Istackoffset n) ->
813db4
       assert (n mod 16 = 0);
813db4
-      `	addi	sp, sp, {emit_int (-n)}\n`;
813db4
+      emit_stack_adjustment (-n);
813db4
       stack_offset := !stack_offset + n
813db4
   | Lop(Iload(Single, Iindexed ofs)) ->
813db4
       `	flw	{emit_reg i.res.(0)}, {emit_int ofs}({emit_reg i.arg.(0)})\n`;
813db4
@@ -398,8 +427,7 @@ let emit_instr i =
813db4
       `	{emit_string lg}	ra, {emit_int(n - size_addr)}(sp)\n`
813db4
   | Lreturn ->
813db4
       let n = frame_size() in
813db4
-      if n > 0 then
813db4
-        `	addi	sp, sp, {emit_int n}\n`;
813db4
+      emit_stack_adjustment n;
813db4
       `	ret\n`
813db4
   | Llabel lbl ->
813db4
       `{emit_label lbl}:\n`
813db4
@@ -513,8 +541,7 @@ let fundecl fundecl =
813db4
   `	.align	2\n`;
813db4
   `{emit_symbol fundecl.fun_name}:\n`;
813db4
   let n = frame_size() in
813db4
-  if n > 0 then
813db4
-    `	addi	sp, sp, {emit_int(-n)}\n`;
813db4
+  emit_stack_adjustment (-n);
813db4
   if !contains_calls then
813db4
     `	{emit_string stg}	ra, {emit_int(n - size_addr)}(sp)\n`;
813db4
   `{emit_label !tailrec_entry_point}:\n`;
813db4
diff --git a/asmcomp/riscv/selection.ml b/asmcomp/riscv/selection.ml
813db4
index ad2b26e9b..283233679 100644
813db4
--- a/asmcomp/riscv/selection.ml
813db4
+++ b/asmcomp/riscv/selection.ml
813db4
@@ -22,7 +22,7 @@ class selector = object (self)
813db4
 
813db4
 inherit Selectgen.selector_generic as super
813db4
 
813db4
-method is_immediate n = (n <= 0x7FF) && (n >= -0x800)
813db4
+method is_immediate n = is_immediate n
813db4
 
813db4
 method select_addressing _ = function
813db4
   | Cop(Cadda, [arg; Cconst_int n]) when self#is_immediate n ->
813db4
-- 
813db4
2.13.2
813db4