From ab30529b723d451fd0ea8ac64d24fc417af55541 Mon Sep 17 00:00:00 2001 From: Nicolas Ojeda Bar 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