| 1896 | } |
| 1897 | |
| 1898 | expr expr::extract(unsigned high, unsigned low, unsigned depth) const { |
| 1899 | C(); |
| 1900 | assert(high >= low && high < bits()); |
| 1901 | |
| 1902 | if (low == 0 && high == bits()-1) |
| 1903 | return *this; |
| 1904 | |
| 1905 | if (depth-- == 0) |
| 1906 | goto end; |
| 1907 | |
| 1908 | { |
| 1909 | expr sub; |
| 1910 | unsigned high_2, low_2; |
| 1911 | if (isExtract(sub, high_2, low_2)) |
| 1912 | return sub.extract(high + low_2, low + low_2); |
| 1913 | } |
| 1914 | if (low == 0) { |
| 1915 | expr val; |
| 1916 | if (isSignExt(val)) { |
| 1917 | auto val_bits = val.bits(); |
| 1918 | if (high < val_bits) |
| 1919 | return val.extract(high, 0); |
| 1920 | return val.sext(high - val_bits + 1); |
| 1921 | } |
| 1922 | } |
| 1923 | { |
| 1924 | expr a, b; |
| 1925 | if (isAShr(a, b)) { |
| 1926 | uint64_t shift; |
| 1927 | if (b.isUInt(shift) && shift < a.bits() && high + shift < a.bits()) |
| 1928 | return a.extract(high + shift, low + shift); |
| 1929 | } |
| 1930 | } |
| 1931 | { |
| 1932 | expr a, b; |
| 1933 | if (isConcat(a, b)) { |
| 1934 | auto b_bw = b.bits(); |
| 1935 | if (high < b_bw) |
| 1936 | return b.extract(high, low); |
| 1937 | if (low >= b_bw) |
| 1938 | return a.extract(high - b_bw, low - b_bw); |
| 1939 | if (low == 0) |
| 1940 | return a.extract(high - b_bw, 0).concat(b); |
| 1941 | if (a.isConst() || b.isConst()) |
| 1942 | return a.extract(high - b_bw, 0).concat(b.extract(b_bw-1, low)); |
| 1943 | } |
| 1944 | } |
| 1945 | { |
| 1946 | expr cond, then, els; |
| 1947 | if (isIf(cond, then, els)) { |
| 1948 | then = then.extract(high, low, depth); |
| 1949 | els = els.extract(high, low, depth); |
| 1950 | if (then.eq(els)) |
| 1951 | return then; |
| 1952 | if (then.isConst() && els.isConst()) |
| 1953 | return mkIf(cond, then, els); |
| 1954 | } |
| 1955 | } |
no test coverage detected