From 00e3b7b59515c086fb92751c15d61b0352f9fde9 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Tue, 15 Dec 2015 10:01:49 +0100 Subject: bug 17752, add builtin64_set_spr and builtin64_get_spr for PowerPC --- powerpc/Asmexpand.ml | 19 +++++++++++++++++-- powerpc/CBuiltins.ml | 5 +++++ powerpc/Machregs.v | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'powerpc') diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml index 08f6b96f..ee9dcccb 100644 --- a/powerpc/Asmexpand.ml +++ b/powerpc/Asmexpand.ml @@ -38,6 +38,7 @@ let _2 = coqint_of_camlint 2l let _4 = coqint_of_camlint 4l let _6 = coqint_of_camlint 6l let _8 = coqint_of_camlint 8l +let _31 = coqint_of_camlint 31l let _32 = coqint_of_camlint 32l let _m4 = coqint_of_camlint (-4l) let _m8 = coqint_of_camlint (-8l) @@ -366,7 +367,7 @@ let expand_builtin_inline name args res = (* less than 32 bits zero? *) emit (Pcmpwi (res, Cint _32)); emit (Pbf (CRbit_2, lbl)); - (* high bits all zero, count bits in low word and increment by 32*) + (* high bits all zero, count bits in low word and increment by 32 *) emit (Pcntlzw(res, al)); emit (Paddi(res, res, Cint _32)); emit (Plabel lbl) @@ -504,6 +505,20 @@ let expand_builtin_inline name args res = emit (Pmtspr(n, a1)) | "__builtin_set_spr", _, _ -> raise (Error "the first argument of __builtin_set_spr must be a constant") + (* Special registers in 32bit hybrid mode *) + | "__builtin64_get_spr", [BA_int n], BR_splitlong(BR(IR rh), BR(IR rl)) -> + emit (Pmfspr(rl, n)); + emit (Prldicl(rh, rl, _32, _32)); + emit (Prldicl(rl, rl, _0, _32)) + | "__builtin64_get_spr", _, _ -> + raise (Error "the argument of __builtin64_get_spr must be a constant") + | "__builtin64_set_spr", [BA_int n; BA_splitlong(BA(IR ah), BA(IR al))], _ -> + emit (Prldicr(GPR10, ah, _32, _31)); + emit (Prldicl(al, al, _0, _32)); + emit (Pori(GPR10, al, Cint _0)); + emit (Pmtspr(n, GPR10)) + | "__builtin64_set_spr", _, _ -> + raise (Error "the first argument of __builtin64_set_spr must be a constant") (* Move registers *) | "__builtin_mr", [BA_int dst; BA_int src], _ -> (match int_to_int_reg (Z.to_int dst), int_to_int_reg (Z.to_int src) with @@ -666,7 +681,7 @@ let expand_instruction instr = emit (Pcfi_adjust _m8) | Pfcfiu(r1, r2) -> assert (Archi.ppc64); - emit (Prldicl(GPR0, r2, _0, coqint_of_camlint 32l)); + emit (Prldicl(GPR0, r2, _0, _32)); emit (Pstdu(GPR0, Cint _m8, GPR1)); emit (Pcfi_adjust _8); emit (Plfd(r1, Cint _0, GPR1)); diff --git a/powerpc/CBuiltins.ml b/powerpc/CBuiltins.ml index 3ca8c17e..1e7c9a1d 100644 --- a/powerpc/CBuiltins.ml +++ b/powerpc/CBuiltins.ml @@ -115,6 +115,11 @@ let builtins = { (TInt(IUInt, []), [TInt(IInt, [])], false); "__builtin_set_spr", (TVoid [], [TInt(IInt, []); TInt(IUInt, [])], false); + (* Access to special registers in 32bit hybrid mode*) + "__builtin64_get_spr", + (TInt(IULongLong, []), [TInt(IInt, [])], false); + "__builtin64_set_spr", + (TVoid [], [TInt(IInt, []); TInt(IULongLong, [])], false); (* Move register *) "__builtin_mr", (TVoid [], [TInt(IInt, []); TInt(IInt, [])], false); diff --git a/powerpc/Machregs.v b/powerpc/Machregs.v index b56812e5..7137bce2 100644 --- a/powerpc/Machregs.v +++ b/powerpc/Machregs.v @@ -163,7 +163,8 @@ Fixpoint destroyed_by_clobber (cl: list string): list mreg := Definition destroyed_by_builtin (ef: external_function): list mreg := match ef with | EF_builtin id sg => - if string_dec id "__builtin_atomic_exchange" then R10::nil + if string_dec id "__builtin64_set_spr" then R10::nil + else if string_dec id "__builtin_atomic_exchange" then R10::nil else if string_dec id "__builtin_atomic_compare_exchange" then R10::R11::nil else F13 :: nil | EF_vload _ => R11 :: nil -- cgit