1 /* 2 * BCJ filter for little endian ARM-Thumb instructions 3 * 4 * Authors: Lasse Collin <lasse.collin (at) 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 ARMThumb implements SimpleFilter { 14 private final boolean isEncoder; 15 private int pos; 16 17 public ARMThumb(boolean isEncoder, int startPos) { 18 this.isEncoder = isEncoder; 19 pos = startPos + 4; 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 += 2) { 27 if ((buf[i + 1] & 0xF8) == 0xF0 && (buf[i + 3] & 0xF8) == 0xF8) { 28 int src = ((buf[i + 1] & 0x07) << 19) 29 | ((buf[i] & 0xFF) << 11) 30 | ((buf[i + 3] & 0x07) << 8) 31 | (buf[i + 2] & 0xFF); 32 src <<= 1; 33 34 int dest; 35 if (isEncoder) 36 dest = src + (pos + i - off); 37 else 38 dest = src - (pos + i - off); 39 40 dest >>>= 1; 41 buf[i + 1] = (byte)(0xF0 | ((dest >>> 19) & 0x07)); 42 buf[i] = (byte)(dest >>> 11); 43 buf[i + 3] = (byte)(0xF8 | ((dest >>> 8) & 0x07)); 44 buf[i + 2] = (byte)dest; 45 i += 2; 46 } 47 } 48 49 i -= off; 50 pos += i; 51 return i; 52 } 53 } 54