Discussion:
[Cocci] transform needing a calculation from a Python script
Allan, Bruce W
2018-03-01 19:13:45 UTC
Permalink
We have a macro that takes a right-justified contiguous set of bits and shifts it left to create a bitmask:

#define FOO(m, s) (m) << (s)

where m is in hex and s is an integer. I'd like to transform occurrences of it to the Linux kernel's GENMASK(high, low) macro (which creates a contiguous bitmask starting at bit position low and ending at position high), but am having problems trying to figure out how to do that.

For example, I'd like to transform:
#define BITMASK_A FOO(0x3F, 4) /* 0x3F0 */
to
#define BITMASK_A GENMASK(9, 4) /* 0x3F0 */

The value s in FOO() is the same as the value low in GENMASK(), but the value high in GENMASK() must be calculated from the values m and s in FOO(). One calculation would be to use the hamming weight (hweight) such as hweight(m) + s - 1. My Python-foo is non-existent but I have found online an example for calculating the hamming weight with the Python script 'def hweight(n): return bin(n).count("1")'. Is it possible to use this (or another) Python script in a Coccinelle script to do this transform, and if so, what would that look like? If the transform cannot use Python, is there another suggestion?

Thanks,
Bruce.
Julia Lawall
2018-03-01 19:46:26 UTC
Permalink
Post by Allan, Bruce W
We have a macro that takes a right-justified contiguous set of bits and
 
#define FOO(m, s)            (m) << (s)
 
where m is in hex and s is an integer.  I’d like to transform occurrences of
it to the Linux kernel’s GENMASK(high, low) macro (which creates a
contiguous bitmask starting at bit position low and ending at position
high), but am having problems trying to figure out how to do that.
 
               #define BITMASK_A         FOO(0x3F, 4)                     
/* 0x3F0 */
to
               #define BITMASK_A         GENMASK(9, 4)                 /*
0x3F0 */
 
The value s in FOO() is the same as the value low in GENMASK(), but the
value high in GENMASK() must be calculated from the values m and s in
FOO().  One calculation would be to use the hamming weight (hweight) such as
hweight(m) + s – 1.  My Python-foo is non-existent but I have found online
an example for calculating the hamming weight with the Python script ‘def
hweight(n): return bin(n).count("1")’.  Is it possible to use this (or
another) Python script in a Coccinelle script to do this transform, and if
so, what would that look like?  If the transform cannot use Python, is there
another suggestion?
I think that you can follow the model of the following code
(demos/pythontococci.cocci). Let me know if it is not clear.

julia

@a@
identifier x;
@@

foo(x);

@script:python b@
x << a.x;
y;
z;
@@

print y
coccinelle.y = x
coccinelle.z = "something"
print y

@c@
identifier b.y;
identifier b.z;
identifier a.x;
@@

- bar();
+ matched_bar(y,z,x);
Allan, Bruce W
2018-03-01 21:17:11 UTC
Permalink
-----Original Message-----
Sent: Thursday, March 01, 2018 11:46 AM
Subject: Re: [Cocci] transform needing a calculation from a Python script
Post by Allan, Bruce W
We have a macro that takes a right-justified contiguous set of bits and
#define FOO(m, s)            (m) << (s)
where m is in hex and s is an integer.  I’d like to transform occurrences of
it to the Linux kernel’s GENMASK(high, low) macro (which creates a
contiguous bitmask starting at bit position low and ending at position
high), but am having problems trying to figure out how to do that.
               #define BITMASK_A         FOO(0x3F, 4)
/* 0x3F0 */
to
               #define BITMASK_A         GENMASK(9, 4)                 /*
0x3F0 */
The value s in FOO() is the same as the value low in GENMASK(), but the
value high in GENMASK() must be calculated from the values m and s in
FOO().  One calculation would be to use the hamming weight (hweight) such
as
Post by Allan, Bruce W
hweight(m) + s – 1.  My Python-foo is non-existent but I have found online
an example for calculating the hamming weight with the Python script ‘def
hweight(n): return bin(n).count("1")’.  Is it possible to use this (or
another) Python script in a Coccinelle script to do this transform, and if
so, what would that look like?  If the transform cannot use Python, is there
another suggestion?
I think that you can follow the model of the following code
(demos/pythontococci.cocci). Let me know if it is not clear.
Sorry, no, it is not clear to me how this works.
julia
@a@
identifier x;
@@
foo(x);
@script:python b@
x << a.x;
y;
z;
@@
print y
coccinelle.y = x
coccinelle.z = "something"
print y
@c@
identifier b.y;
identifier b.z;
identifier a.x;
@@
- bar();
+ matched_bar(y,z,x);
Julia Lawall
2018-03-02 06:39:35 UTC
Permalink
Post by Allan, Bruce W
-----Original Message-----
Sent: Thursday, March 01, 2018 11:46 AM
Subject: Re: [Cocci] transform needing a calculation from a Python script
Post by Allan, Bruce W
We have a macro that takes a right-justified contiguous set of bits and
#define FOO(m, s)            (m) << (s)
where m is in hex and s is an integer.  I’d like to transform occurrences of
it to the Linux kernel’s GENMASK(high, low) macro (which creates a
contiguous bitmask starting at bit position low and ending at position
high), but am having problems trying to figure out how to do that.
               #define BITMASK_A         FOO(0x3F, 4)
/* 0x3F0 */
to
               #define BITMASK_A         GENMASK(9, 4)                 /*
0x3F0 */
The value s in FOO() is the same as the value low in GENMASK(), but the
value high in GENMASK() must be calculated from the values m and s in
FOO().  One calculation would be to use the hamming weight (hweight) such
as
Post by Allan, Bruce W
hweight(m) + s – 1.  My Python-foo is non-existent but I have found online
an example for calculating the hamming weight with the Python script ‘def
hweight(n): return bin(n).count("1")’.  Is it possible to use this (or
another) Python script in a Coccinelle script to do this transform, and if
so, what would that look like?  If the transform cannot use Python, is there
another suggestion?
I think that you can follow the model of the following code
(demos/pythontococci.cocci). Let me know if it is not clear.
Sorry, no, it is not clear to me how this works.
The first rule matches whatever you want to change and established some
metavariables that contain information you will want to give to python.

The second rule declares some new variables y and z, as well as inheriting
information from the first rule. This is where you call your python code,
and you assign the new variables to whatever you will need to compute your
result. The last rule uses the information obtained from the first and
second rules to make the transformation. It declares the metavariables
inherited from python as identifiers, but they can contain any
more complex expression as well.

julia
Post by Allan, Bruce W
julia
@a@
identifier x;
@@
foo(x);
@script:python b@
x << a.x;
y;
z;
@@
print y
coccinelle.y = x
coccinelle.z = "something"
print y
@c@
identifier b.y;
identifier b.z;
identifier a.x;
@@
- bar();
+ matched_bar(y,z,x);
Robert Larice
2018-03-03 09:05:22 UTC
Permalink
Hello,
attached is a very rough piece of .cocci which might
be an aproximation of your wish and julias hint.
I assembled it as a sort of excersice for myself.
Regards,
Robert
Julia Lawall
2018-03-03 09:40:44 UTC
Permalink
Post by Robert Larice
Hello,
attached is a very rough piece of .cocci which might
be an aproximation of your wish and julias hint.
I assembled it as a sort of excersice for myself.
It looks reasonable.

julia
Post by Robert Larice
Regards,
Robert
Continue reading on narkive:
Loading...