diff options
author | Bernhard Schommer <bernhardschommer@gmail.com> | 2015-09-10 10:05:12 +0200 |
---|---|---|
committer | Bernhard Schommer <bernhardschommer@gmail.com> | 2015-09-10 10:05:12 +0200 |
commit | be6dc9e64912901b8217f56656d770f957d15cb4 (patch) | |
tree | 8777f4731052528ff2f9265a7ce2ba2bd81db3a8 /powerpc/Asmexpand.ml | |
parent | 2dce91b8e2cae0b49c8870df6c727e25aaa180d8 (diff) | |
parent | 9d85d044fad9d35efe2612b7a5518f7f9074572f (diff) | |
download | compcert-be6dc9e64912901b8217f56656d770f957d15cb4.tar.gz compcert-be6dc9e64912901b8217f56656d770f957d15cb4.zip |
Merge branch 'master' into atomic-builtins
Conflicts:
powerpc/CBuiltins.ml
Diffstat (limited to 'powerpc/Asmexpand.ml')
-rw-r--r-- | powerpc/Asmexpand.ml | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml index c6bda75c..beaef42f 100644 --- a/powerpc/Asmexpand.ml +++ b/powerpc/Asmexpand.ml @@ -507,6 +507,43 @@ let expand_builtin_inline name args res = emit (Pbne lbl); 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 (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 () + and lblsucc = new_label () in + emit (Plwz (GPR10,Cint _0,exp)); + emit (Plwz (GPR11,Cint _0,exp)); + 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); + emit (Pmr (res,dst)); (* Catch-all *) | _ -> raise (Error ("unrecognized builtin " ^ name)) |