cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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@@
     28import sys
     29fd = sys.stderr
     30def debug(msg="", trailer="\n"):
     31    fd.write("[DBG] " + msg + trailer)
     32def low_bits_count(value):
     33    bits_count = 0
     34    while (value & (1 << bits_count)):
     35        bits_count += 1
     36    return bits_count
     37def Mn(order): # Mersenne number
     38    return (1 << order) - 1
     39
     40@match@
     41identifier ret;
     42metavariable arg;
     43constant ofs, msk;
     44position 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@
     63ret_s << match.ret;
     64msk_s << match.msk;
     65shr_p << match.shr_p;
     66extract_len;
     67@@
     68is_optimizable = False
     69debug("candidate at %s:%s" % (shr_p[0].file, shr_p[0].line))
     70try: # 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"))
     80except:
     81    debug("  ERROR (check included headers?)")
     82cocci.include_match(is_optimizable)
     83debug()
     84
     85@replacement depends on verify_len@
     86identifier match.ret;
     87metavariable match.arg;
     88constant match.ofs, match.msk;
     89position match.shr_p, match.and_p;
     90identifier 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)