11e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan/*
21e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * BCJ filter for little endian ARM instructions
31e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan *
41e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * Authors: Lasse Collin <lasse.collin@tukaani.org>
51e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan *          Igor Pavlov <http://7-zip.org/>
61e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan *
71e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * This file has been put into the public domain.
81e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan * You can do whatever you want with this file.
91e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan */
101e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
111e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanpackage org.tukaani.xz.simple;
121e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
131e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnanpublic final class ARM implements SimpleFilter {
141e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    private final boolean isEncoder;
151e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    private int pos;
161e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
171e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public ARM(boolean isEncoder, int startPos) {
181e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        this.isEncoder = isEncoder;
191e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        pos = startPos + 8;
201e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
211e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
221e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    public int code(byte[] buf, int off, int len) {
231e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        int end = off + len - 4;
241e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        int i;
251e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
261e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        for (i = off; i <= end; i += 4) {
271e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan            if ((buf[i + 3] & 0xFF) == 0xEB) {
281e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                int src = ((buf[i + 2] & 0xFF) << 16)
291e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                          | ((buf[i + 1] & 0xFF) << 8)
301e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                          | (buf[i] & 0xFF);
311e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                src <<= 2;
321e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
331e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                int dest;
341e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                if (isEncoder)
351e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                    dest = src + (pos + i - off);
361e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                else
371e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                    dest = src - (pos + i - off);
381e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
391e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                dest >>>= 2;
401e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                buf[i + 2] = (byte)(dest >>> 16);
411e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                buf[i + 1] = (byte)(dest >>> 8);
421e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan                buf[i] = (byte)dest;
431e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan            }
441e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        }
451e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan
461e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        i -= off;
471e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        pos += i;
481e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan        return i;
491e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan    }
501e977d75f657dacb4cb5c36ab6054bcf66b08076Vinod Krishnan}
51