diff options
author | Bernhard Schommer <bernhardschommer@gmail.com> | 2015-09-14 19:41:39 +0200 |
---|---|---|
committer | Bernhard Schommer <bernhardschommer@gmail.com> | 2015-09-14 19:41:39 +0200 |
commit | 9dc0dd73f75875b301c886df40087192d0fad386 (patch) | |
tree | 64d362acab74e67e6c2f80fde7e8622563c4b865 /powerpc/Asmexpand.ml | |
parent | 0de3d126e70dfedfd6f74710da31c4b9636f900a (diff) | |
download | compcert-9dc0dd73f75875b301c886df40087192d0fad386.tar.gz compcert-9dc0dd73f75875b301c886df40087192d0fad386.zip |
Use fix registers for atomic builtins.
In order to avoid clashes during register allocation etc. The
builtins now use fixed registers and mark additional registers as
destroyed for temporaries.
Diffstat (limited to 'powerpc/Asmexpand.ml')
-rw-r--r-- | powerpc/Asmexpand.ml | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml index 5e26e8a6..23c66382 100644 --- a/powerpc/Asmexpand.ml +++ b/powerpc/Asmexpand.ml @@ -506,20 +506,23 @@ let expand_builtin_inline name args res = emit (Pisync); emit (Pstw (a1,Cint _0, a2)); | "__builtin_sync_fetch_and_add", [BA (IR a1); BA(IR a2)], BR (IR res) -> - let tmpres = if a1 = res then - GPR11 - else - res in let lbl = new_label() in emit (Psync); emit (Plabel lbl); - emit (Plwarx (tmpres,GPR0,a1)); - emit (Padd (a2,tmpres,a2)); - emit (Pstwcx_ (a2,GPR0,a1)); + emit (Plwarx (res,GPR0,a1)); + emit (Padd (GPR10,res,a2)); + emit (Pstwcx_ (GPR10,GPR0,a1)); + emit (Pbne lbl); + emit (Pisync); + | "__builtin_sync_fetch_and_add", [BA (IR a1); BA(IR a2)], BR_none -> + let lbl = new_label() in + emit (Psync); + emit (Plabel lbl); + emit (Plwarx (GPR3,GPR0,a1)); + emit (Padd (GPR10,GPR3,a2)); + emit (Pstwcx_ (GPR10,GPR0,a1)); emit (Pbne lbl); emit (Pisync); - if (tmpres <> res) then - emit (Pmr (res,tmpres)) | "__builtin_atomic_compare_exchange", [BA (IR dst); BA(IR exp); BA (IR des)], BR (IR res) -> let lbls = new_label () and lblneq = new_label () @@ -542,6 +545,27 @@ let expand_builtin_inline name args res = emit (Pstw (GPR12,(Cint _0),exp)); emit (Plabel lblsucc); emit (Pmr (res,dst)); + | "__builtin_atomic_compare_exchange", [BA (IR dst); BA(IR exp); BA (IR des)], BR_none -> + let lbls = new_label () + and lblneq = new_label () + and lblsucc = new_label () in + emit (Plwz (GPR10,Cint _0,exp)); + emit (Plwz (GPR11,Cint _0,des)); + emit (Psync); + emit (Plabel lbls); + emit (Plwarx (GPR12,GPR0,dst)); + emit (Pcmpw (GPR12,GPR10)); + emit (Pbne lblneq); + emit (Pstwcx_ (GPR11,GPR0,dst)); + emit (Pbne lbls); + emit (Plabel lblneq); + emit (Pisync); + emit (Pmfcr dst); + emit (Prlwinm (dst,dst,(Z.of_uint 3),_1)); + emit (Pcmpwi (dst,(Cint _0))); + emit (Pbne lblsucc); + emit (Pstw (GPR12,(Cint _0),exp)); + emit (Plabel lblsucc); (* Catch-all *) | _ -> raise (Error ("unrecognized builtin " ^ name)) |