aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Regalloc.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavierleroy@users.noreply.github.com>2015-04-22 14:27:12 +0200
committerXavier Leroy <xavierleroy@users.noreply.github.com>2015-04-22 14:27:12 +0200
commit0bf99217426a44046ef0aaa7f84a9b2a3646ed89 (patch)
treee4f983980a5001792b90ed8f3dbd8fa241e43eb1 /backend/Regalloc.ml
parent08b2b46f15e70b11c044e4e9a7c8438a96d57ed7 (diff)
parentca4aa822693f4d98de99fd3f13c1523d733e1cb0 (diff)
downloadcompcert-0bf99217426a44046ef0aaa7f84a9b2a3646ed89.tar.gz
compcert-0bf99217426a44046ef0aaa7f84a9b2a3646ed89.zip
Merge pull request #40 from AbsInt/inline-asm
GCC-style extended inline asm. The subset implemented is: - zero or one output - output constraints "=r" (to register) or "=m" (to memory) - zero, one or several inputs - input constraints "r" (in register), "m" (in memory), "i" and "n" (compile-time integer constant) - clobbered registers (the 3rd argument) - both anonymous (%3) and named (%[name]) operands - modifiers %R and %Q to refer to the most significant / least significant part of a register pair holding a 64-bit integer. (Undocumented GCC ARM feature.) All asm statements are treated as "volatile", possibly modifying memory and condition codes.
Diffstat (limited to 'backend/Regalloc.ml')
-rw-r--r--backend/Regalloc.ml18
1 files changed, 17 insertions, 1 deletions
diff --git a/backend/Regalloc.ml b/backend/Regalloc.ml
index 3a7f5d99..c286e946 100644
--- a/backend/Regalloc.ml
+++ b/backend/Regalloc.ml
@@ -510,6 +510,9 @@ let add_interfs_live g live v =
let add_interfs_list g v vl =
List.iter (IRC.add_interf g v) vl
+let add_interfs_list_mreg g vl mr =
+ List.iter (fun v -> IRC.add_interf g v (L (R mr))) vl
+
let rec add_interfs_pairwise g = function
| [] -> ()
| v1 :: vl -> add_interfs_list g v1 vl; add_interfs_pairwise g vl
@@ -578,7 +581,20 @@ let add_interfs_instr g instr live =
add_interfs_pairwise g res;
add_interfs_destroyed g across (destroyed_by_builtin ef);
begin match ef, args, res with
- | EF_annot_val _, [arg], [res] -> IRC.add_pref g arg res (* like a move *)
+ | EF_annot_val _, [arg], [res] ->
+ (* like a move *)
+ IRC.add_pref g arg res
+ | EF_inline_asm(txt, sg, clob), _, _ ->
+ (* clobbered regs interfere with live set
+ and also with res and args for GCC compatibility *)
+ List.iter (fun c ->
+ match Machregsaux.register_by_name (extern_atom c) with
+ | None -> ()
+ | Some mr ->
+ add_interfs_destroyed g across [mr];
+ add_interfs_list_mreg g args mr;
+ if sg.sig_res <> None then add_interfs_list_mreg g res mr)
+ clob
| _ -> ()
end
| Xannot(ef, args) ->