qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

tcg_gen_extract.cocci (3010B)


      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 )