From c29a9abe07523eeafc09e630b6a9d14581632e9f Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Fri, 8 Jul 2016 14:24:44 +0200 Subject: bug 19318, add implementation of __builtin_ctz, __builtin_ctzl and __builtin_ctzll for PowerPC --- powerpc/Asmexpand.ml | 26 ++++++++++++++++++++++++++ powerpc/CBuiltins.ml | 6 ++++++ 2 files changed, 32 insertions(+) diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml index d299e2cd..a27eeeb7 100644 --- a/powerpc/Asmexpand.ml +++ b/powerpc/Asmexpand.ml @@ -38,6 +38,8 @@ 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 _64 = coqint_of_camlint 64l +let _m1 = coqint_of_camlint (-1l) let _m4 = coqint_of_camlint (-4l) let _m8 = coqint_of_camlint (-8l) @@ -369,6 +371,30 @@ let expand_builtin_inline name args res = (* high bits all zero, count bits in low word and increment by 32 *) emit (Padd(res, res, GPR0)); emit (Plabel lbl) + | ("__builtin_ctz" | "__builtin_ctzl"), [BA(IR a1)], BR(IR res) -> + emit (Paddi(GPR0, a1, Cint _m1)); (* tmp := x-1 *) + emit (Pandc(res, GPR0, a1)); (* res := tmp & ~(x) *) + emit (Pcntlzw(res, res)); (* res := #leading zeros *) + emit (Psubfic(res, res, Cint _32)) (* res := 32 - #leading zeros *) + | "__builtin_ctzll", [BA_splitlong(BA(IR ah), BA(IR al))], BR(IR res) -> + let lbl1 = new_label () in + let lbl2 = new_label () in + (* low word equal to zero? *) + emit (Pcmpwi (al, Cint _0)); + emit (Pbf (CRbit_2, lbl1)); + (* low word is zero, count trailing zeros in high word and increment by 32 *) + emit (Paddi(GPR0, ah, Cint _m1)); + emit (Pandc(res, GPR0, ah)); + emit (Pcntlzw(res, res)); + emit (Psubfic(res, res, Cint _64)); + emit (Pb lbl2); + (* count trailing zeros in low word *) + emit (Plabel lbl1); + emit (Paddi(GPR0, al, Cint _m1)); + emit (Pandc(res, GPR0, al)); + emit (Pcntlzw(res, res)); + emit (Psubfic(res, res, Cint _32)); + emit (Plabel lbl2) | "__builtin_cmpb", [BA(IR a1); BA(IR a2)], BR(IR res) -> emit (Pcmpb (res,a1,a2)) | ("__builtin_bswap" | "__builtin_bswap32"), [BA(IR a1)], BR(IR res) -> diff --git a/powerpc/CBuiltins.ml b/powerpc/CBuiltins.ml index d244cba0..d33d6252 100644 --- a/powerpc/CBuiltins.ml +++ b/powerpc/CBuiltins.ml @@ -34,6 +34,12 @@ let builtins = { (TInt(IInt, []), [TInt(IULong, [])], false); "__builtin_clzll", (TInt(IInt, []), [TInt(IULongLong, [])], false); + "__builtin_ctz", + (TInt(IInt, []), [TInt(IUInt, [])], false); + "__builtin_ctzl", + (TInt(IInt, []), [TInt(IULong, [])], false); + "__builtin_ctzll", + (TInt(IInt, []), [TInt(IULongLong, [])], false); "__builtin_bswap", (TInt(IUInt, []), [TInt(IUInt, [])], false); "__builtin_bswap32", -- cgit From 2cb9e645e6630d053bc72e484fe27dda5955e0ae Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Fri, 8 Jul 2016 14:43:58 +0200 Subject: bug 19318, add implementation of __builtin_ctz, __builtin_ctzl and __builtin_ctzll for ARM --- arm/Asmexpand.ml | 30 ++++++++++++++++++++++++++++++ arm/CBuiltins.ml | 6 ++++++ 2 files changed, 36 insertions(+) diff --git a/arm/Asmexpand.ml b/arm/Asmexpand.ml index 8aef64e4..855ca9ad 100644 --- a/arm/Asmexpand.ml +++ b/arm/Asmexpand.ml @@ -30,6 +30,9 @@ let _2 = coqint_of_camlint 2l let _4 = coqint_of_camlint 4l let _8 = coqint_of_camlint 8l let _16 = coqint_of_camlint 16l +let _32 = coqint_of_camlint 32l +let _64 = coqint_of_camlint 64l +let _m1 = coqint_of_camlint (-1l) (* Emit instruction sequences that set or offset a register by a constant. *) (* No S suffix because they are applied to SP most of the time. *) @@ -294,6 +297,33 @@ let expand_builtin_inline name args res = emit (Pmovite (TCeq, IR14, SOreg IR14, SOimm _0)); emit (Pclz (res, ah)); emit (Padd (res, res, SOreg IR14)) + | ("__builtin_ctz" | "__builtin_ctzl"), [BA(IR a1)], BR(IR res) -> + emit (Padd(IR14, a1, SOimm _m1)); (* tmp := x-1 *) + emit (Pmvn(res, SOreg a1)); (* res := ~(x) *) + emit (Pand(res, IR14, SOreg res)); (* res := tmp & ~(x) *) + emit (Pclz(res, res)); (* res := #leading zeros *) + emit (Prsb(res, res, SOimm _32)) (* res := 32 - #leading zeros *) + | "__builtin_ctzll", [BA_splitlong(BA(IR ah), BA(IR al))], BR(IR res) -> + let lbl1 = new_label () in + let lbl2 = new_label () in + (* low word equal to zero? *) + emit (Pcmp (al, SOimm _0)); + emit (Pbne lbl1); + (* low word is zero, count trailing zeros in high word and increment by 32 *) + emit (Padd(IR14, ah, SOimm _m1)); + emit (Pmvn(res, SOreg ah)); + emit (Pand(res, IR14, SOreg res)); + emit (Pclz(res, res)); + emit (Prsb(res, res, SOimm _64)); + emit (Pb lbl2); + (* count trailing zeros in low word *) + emit (Plabel lbl1); + emit (Padd(IR14, al, SOimm _m1)); + emit (Pmvn(res, SOreg al)); + emit (Pand(res, IR14, SOreg res)); + emit (Pclz(res, res)); + emit (Prsb(res, res, SOimm _32)); + emit (Plabel lbl2) (* Float arithmetic *) | "__builtin_fabs", [BA(FR a1)], BR(FR res) -> emit (Pfabsd (res,a1)) diff --git a/arm/CBuiltins.ml b/arm/CBuiltins.ml index 1b06b93b..2015607a 100644 --- a/arm/CBuiltins.ml +++ b/arm/CBuiltins.ml @@ -35,6 +35,12 @@ let builtins = { (TInt(IInt, []), [TInt(IULong, [])], false); "__builtin_clzll", (TInt(IInt, []), [TInt(IULongLong, [])], false); + "__builtin_ctz", + (TInt(IInt, []), [TInt(IUInt, [])], false); + "__builtin_ctzl", + (TInt(IInt, []), [TInt(IULong, [])], false); + "__builtin_ctzll", + (TInt(IInt, []), [TInt(IULongLong, [])], false); (* Float arithmetic *) "__builtin_fsqrt", (TFloat(FDouble, []), [TFloat(FDouble, [])], false); -- cgit