Skip to content

Commit 31209d6

Browse files
committed
Branch relaxation for AArch64
Fixes: #564
1 parent 24ff7f7 commit 31209d6

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

aarch64/Asmexpand.ml

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,70 @@ let expand_builtin_inline name args res =
407407
| _ ->
408408
raise (Error ("unrecognized builtin " ^ name))
409409

410+
(* Branch relaxation *)
411+
412+
module BInfo: BRANCH_INFORMATION = struct
413+
414+
let builtin_size = function
415+
| EF_annot _ -> 0
416+
| EF_debug _ -> 0
417+
| EF_inline_asm _ -> 32 (* hope it's no more than 8 instructions *)
418+
| _ -> assert false
419+
420+
let instr_size = function
421+
| Pfmovimmd _ | Pfmovimms _ -> 8
422+
| Pbtbl(_, tbl) -> 12 + 4 * List.length tbl
423+
| Plabel _ | Pcfi_adjust _ | Pcfi_rel_offset _ -> 0
424+
| Pbuiltin(ef, _, _) -> builtin_size ef
425+
| _ -> 4
426+
427+
let branch_overflow ~map pc lbl range =
428+
let displ = pc + 4 - map lbl in
429+
displ < -range || displ >= range
430+
431+
let need_relaxation ~map pc instr =
432+
match instr with
433+
| Pbc(_, lbl) | Pcbnz(_, _, lbl) | Pcbz(_, _, lbl) ->
434+
(* +/- 1 MB *)
435+
branch_overflow ~map pc lbl 0x100_000
436+
| Ptbnz(_, _, _, lbl) | Ptbz(_, _, _, lbl) ->
437+
(* +/- 32 KB *)
438+
branch_overflow ~map pc lbl 0x8_000
439+
| _ ->
440+
false
441+
442+
let negate_testcond = function
443+
| TCeq -> TCne | TCne -> TCeq
444+
| TChs -> TClo | TClo -> TChs
445+
| TCmi -> TCpl | TCpl -> TCmi
446+
| TChi -> TCls | TCls -> TChi
447+
| TCge -> TClt | TClt -> TCge
448+
| TCgt -> TCle | TCle -> TCgt
449+
450+
let relax_instruction instr =
451+
match instr with
452+
| Pbc(c, lbl) ->
453+
let lbl' = new_label() in
454+
[Pbc(negate_testcond c, lbl'); Pb lbl; Plabel lbl']
455+
| Pcbnz(sz, r, lbl) ->
456+
let lbl' = new_label() in
457+
[Pcbz(sz, r, lbl'); Pb lbl; Plabel lbl']
458+
| Pcbz(sz, r, lbl) ->
459+
let lbl' = new_label() in
460+
[Pcbnz(sz, r, lbl'); Pb lbl; Plabel lbl']
461+
| Ptbnz(sz, r, n, lbl) ->
462+
let lbl' = new_label() in
463+
[Ptbz(sz, r, n, lbl'); Pb lbl; Plabel lbl']
464+
| Ptbz(sz, r, n, lbl) ->
465+
let lbl' = new_label() in
466+
[Ptbnz(sz, r, n, lbl'); Pb lbl; Plabel lbl']
467+
| _ ->
468+
assert false
469+
470+
end
471+
472+
module BRelax = Branch_relaxation (BInfo)
473+
410474
(* Expansion of instructions *)
411475

412476
let expand_instruction instr =
@@ -478,7 +542,8 @@ let expand_function id fn =
478542
try
479543
set_current_function fn;
480544
expand id (* sp= *) 31 preg_to_dwarf expand_instruction fn.fn_code;
481-
Errors.OK (get_current_function ())
545+
let fn' = BRelax.relaxation (get_current_function ()) in
546+
Errors.OK fn'
482547
with Error s ->
483548
Errors.Error (Errors.msg s)
484549

0 commit comments

Comments
 (0)