1/*
2 * BCJ filter for SPARC instructions
3 *
4 * Authors: Lasse Collin <lasse.collin@tukaani.org>
5 *          Igor Pavlov <http://7-zip.org/>
6 *
7 * This file has been put into the public domain.
8 * You can do whatever you want with this file.
9 */
10
11package org.tukaani.xz.simple;
12
13public final class SPARC implements SimpleFilter {
14    private final boolean isEncoder;
15    private int pos;
16
17    public SPARC(boolean isEncoder, int startPos) {
18        this.isEncoder = isEncoder;
19        pos = startPos;
20    }
21
22    public int code(byte[] buf, int off, int len) {
23        int end = off + len - 4;
24        int i;
25
26        for (i = off; i <= end; i += 4) {
27            if ((buf[i] == 0x40 && (buf[i + 1] & 0xC0) == 0x00)
28                    || (buf[i] == 0x7F && (buf[i + 1] & 0xC0) == 0xC0)) {
29                int src = ((buf[i] & 0xFF) << 24)
30                          | ((buf[i + 1] & 0xFF) << 16)
31                          | ((buf[i + 2] & 0xFF) << 8)
32                          | (buf[i + 3] & 0xFF);
33                src <<= 2;
34
35                int dest;
36                if (isEncoder)
37                    dest = src + (pos + i - off);
38                else
39                    dest = src - (pos + i - off);
40
41                dest >>>= 2;
42                dest = (((0 - ((dest >>> 22) & 1)) << 22) & 0x3FFFFFFF)
43                       | (dest & 0x3FFFFF) | 0x40000000;
44
45                buf[i] = (byte)(dest >>> 24);
46                buf[i + 1] = (byte)(dest >>> 16);
47                buf[i + 2] = (byte)(dest >>> 8);
48                buf[i + 3] = (byte)dest;
49            }
50        }
51
52        i -= off;
53        pos += i;
54        return i;
55    }
56}
57