Skip to content

Commit 16df7e5

Browse files
committed
RISC-V: use PC-relative addressing instead of absolute addressing
This should support the "medium any" code model, where executables can be loaded at addresses above 2Gb. It might also reduce the number of link-time relocations. Also: use `lla` (load local address -> auipc/addi) instead of `la` for all local symbols, in preparation for better PIC support.
1 parent 1670ae7 commit 16df7e5

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

riscV/TargetPrinter.ml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,7 @@ module Target : TARGET =
115115
assert (ofs = Integers.Ptrofs.zero);
116116
fprintf oc " la %a, %s\n" ireg r (extern_atom id)
117117
end else begin
118-
fprintf oc " lui %a, %%hi(%a)\n"
119-
ireg r symbol_offset (id, ofs);
120-
fprintf oc " addi %a, %a, %%lo(%a)\n"
121-
ireg r ireg r symbol_offset (id, ofs)
118+
fprintf oc " lla %a, %a\n" ireg r symbol_offset (id, ofs)
122119
end
123120

124121
(* Emit .file / .loc debugging directives *)
@@ -138,9 +135,14 @@ module Target : TARGET =
138135

139136
(* Offset part of a load or store *)
140137

138+
let latest_auipc : (ident * Integers.Ptrofs.int) option ref = ref None
139+
141140
let offset oc = function
142-
| Ofsimm n -> ptrofs oc n
143-
| Ofslow(id, ofs) -> fprintf oc "%%lo(%a)" symbol_offset (id, ofs)
141+
| Ofsimm n ->
142+
ptrofs oc n
143+
| Ofslow(id, ofs) ->
144+
assert (!latest_auipc = Some(id, ofs));
145+
fprintf oc "%%pcrel_lo(1b)"
144146

145147
(* Printing of instructions *)
146148
let print_instruction oc = function
@@ -495,7 +497,8 @@ module Target : TARGET =
495497
| Ploadsymbol(rd, id, ofs) ->
496498
loadsymbol oc rd id ofs
497499
| Ploadsymbol_high(rd, id, ofs) ->
498-
fprintf oc " lui %a, %%hi(%a)\n" ireg rd symbol_offset (id, ofs)
500+
fprintf oc "1: auipc %a, %%pcrel_hi(%a)\n" ireg rd symbol_offset (id, ofs);
501+
latest_auipc := Some(id, ofs)
499502
| Ploadli(rd, n) ->
500503
let d = camlint64_of_coqint n in
501504
let lbl = label_literal64 d in
@@ -516,7 +519,7 @@ module Target : TARGET =
516519
List.iter (fun l -> fprintf oc "%a " print_label l) tbl;
517520
fprintf oc "]\n";
518521
fprintf oc " sll x5, %a, 2\n" ireg r;
519-
fprintf oc " la x31, %a\n" label lbl;
522+
fprintf oc " lla x31, %a\n" label lbl;
520523
fprintf oc " add x5, x31, x5\n";
521524
fprintf oc " lw x5, 0(x5)\n";
522525
fprintf oc " add x5, x31, x5\n";
@@ -584,6 +587,7 @@ module Target : TARGET =
584587

585588
let print_instructions oc fn =
586589
current_function_sig := fn.fn_sig;
590+
latest_auipc := None;
587591
List.iter (print_instruction oc) fn.fn_code
588592

589593

0 commit comments

Comments
 (0)