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 
11 package org.tukaani.xz.simple;
12 
13 public final class SPARC implements SimpleFilter {
14     private final boolean isEncoder;
15     private int pos;
16 
SPARC(boolean isEncoder, int startPos)17     public SPARC(boolean isEncoder, int startPos) {
18         this.isEncoder = isEncoder;
19         pos = startPos;
20     }
21 
code(byte[] buf, int off, int len)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