]> git.proxmox.com Git - mirror_qemu.git/blob - scripts/coccinelle/tcg_gen_extract.cocci
qemu-iotests: convert `pwd` and $(pwd) to $PWD
[mirror_qemu.git] / scripts / coccinelle / tcg_gen_extract.cocci
1 // optimize TCG using extract op
2 //
3 // Copyright: (C) 2017 Philippe Mathieu-Daudé. GPLv2+.
4 // Confidence: High
5 // Options: --macro-file scripts/cocci-macro-file.h
6 //
7 // Nikunj A Dadhania optimization:
8 // http://lists.nongnu.org/archive/html/qemu-devel/2017-02/msg05211.html
9 // Aurelien Jarno optimization:
10 // http://lists.nongnu.org/archive/html/qemu-devel/2017-05/msg01466.html
11 //
12 // This script can be run either using spatch locally or via a docker image:
13 //
14 // $ spatch \
15 // --macro-file scripts/cocci-macro-file.h \
16 // --sp-file scripts/coccinelle/tcg_gen_extract.cocci \
17 // --keep-comments --in-place \
18 // --use-gitgrep --dir target
19 //
20 // $ docker run --rm -v $PWD:$PWD -w $PWD philmd/coccinelle \
21 // --macro-file scripts/cocci-macro-file.h \
22 // --sp-file scripts/coccinelle/tcg_gen_extract.cocci \
23 // --keep-comments --in-place \
24 // --use-gitgrep --dir target
25
26 @initialize:python@
27 @@
28 import sys
29 fd = sys.stderr
30 def debug(msg="", trailer="\n"):
31 fd.write("[DBG] " + msg + trailer)
32 def low_bits_count(value):
33 bits_count = 0
34 while (value & (1 << bits_count)):
35 bits_count += 1
36 return bits_count
37 def Mn(order): # Mersenne number
38 return (1 << order) - 1
39
40 @match@
41 identifier ret;
42 metavariable arg;
43 constant ofs, msk;
44 position shr_p, and_p;
45 @@
46 (
47 tcg_gen_shri_i32@shr_p
48 |
49 tcg_gen_shri_i64@shr_p
50 |
51 tcg_gen_shri_tl@shr_p
52 )(ret, arg, ofs);
53 ... WHEN != ret
54 (
55 tcg_gen_andi_i32@and_p
56 |
57 tcg_gen_andi_i64@and_p
58 |
59 tcg_gen_andi_tl@and_p
60 )(ret, ret, msk);
61
62 @script:python verify_len depends on match@
63 ret_s << match.ret;
64 msk_s << match.msk;
65 shr_p << match.shr_p;
66 extract_len;
67 @@
68 is_optimizable = False
69 debug("candidate at %s:%s" % (shr_p[0].file, shr_p[0].line))
70 try: # only eval integer, no #define like 'SR_M' (cpp did this, else some headers are missing).
71 msk_v = long(msk_s.strip("UL"), 0)
72 msk_b = low_bits_count(msk_v)
73 if msk_b == 0:
74 debug(" value: 0x%x low_bits: %d" % (msk_v, msk_b))
75 else:
76 debug(" value: 0x%x low_bits: %d [Mersenne number: 0x%x]" % (msk_v, msk_b, Mn(msk_b)))
77 is_optimizable = Mn(msk_b) == msk_v # check low_bits
78 coccinelle.extract_len = "%d" % msk_b
79 debug(" candidate %s optimizable" % ("IS" if is_optimizable else "is NOT"))
80 except:
81 debug(" ERROR (check included headers?)")
82 cocci.include_match(is_optimizable)
83 debug()
84
85 @replacement depends on verify_len@
86 identifier match.ret;
87 metavariable match.arg;
88 constant match.ofs, match.msk;
89 position match.shr_p, match.and_p;
90 identifier verify_len.extract_len;
91 @@
92 (
93 -tcg_gen_shri_i32@shr_p(ret, arg, ofs);
94 +tcg_gen_extract_i32(ret, arg, ofs, extract_len);
95 ... WHEN != ret
96 -tcg_gen_andi_i32@and_p(ret, ret, msk);
97 |
98 -tcg_gen_shri_i64@shr_p(ret, arg, ofs);
99 +tcg_gen_extract_i64(ret, arg, ofs, extract_len);
100 ... WHEN != ret
101 -tcg_gen_andi_i64@and_p(ret, ret, msk);
102 |
103 -tcg_gen_shri_tl@shr_p(ret, arg, ofs);
104 +tcg_gen_extract_tl(ret, arg, ofs, extract_len);
105 ... WHEN != ret
106 -tcg_gen_andi_tl@and_p(ret, ret, msk);
107 )