1 /* 2 * BCJ filter for Itanium (IA-64) 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 IA64 implements SimpleFilter { 14 private static final int[] BRANCH_TABLE = { 15 0, 0, 0, 0, 0, 0, 0, 0, 16 0, 0, 0, 0, 0, 0, 0, 0, 17 4, 4, 6, 6, 0, 0, 7, 7, 18 4, 4, 0, 0, 4, 4, 0, 0 }; 19 20 private final boolean isEncoder; 21 private int pos; 22 IA64(boolean isEncoder, int startPos)23 public IA64(boolean isEncoder, int startPos) { 24 this.isEncoder = isEncoder; 25 pos = startPos; 26 } 27 code(byte[] buf, int off, int len)28 public int code(byte[] buf, int off, int len) { 29 int end = off + len - 16; 30 int i; 31 32 for (i = off; i <= end; i += 16) { 33 int instrTemplate = buf[i] & 0x1F; 34 int mask = BRANCH_TABLE[instrTemplate]; 35 36 for (int slot = 0, bitPos = 5; slot < 3; ++slot, bitPos += 41) { 37 if (((mask >>> slot) & 1) == 0) 38 continue; 39 40 int bytePos = bitPos >>> 3; 41 int bitRes = bitPos & 7; 42 43 long instr = 0; 44 for (int j = 0; j < 6; ++j) 45 instr |= (buf[i + bytePos + j] & 0xFFL) << (8 * j); 46 47 long instrNorm = instr >>> bitRes; 48 49 if (((instrNorm >>> 37) & 0x0F) != 0x05 50 || ((instrNorm >>> 9) & 0x07) != 0x00) 51 continue; 52 53 int src = (int)((instrNorm >>> 13) & 0x0FFFFF); 54 src |= ((int)(instrNorm >>> 36) & 1) << 20; 55 src <<= 4; 56 57 int dest; 58 if (isEncoder) 59 dest = src + (pos + i - off); 60 else 61 dest = src - (pos + i - off); 62 63 dest >>>= 4; 64 65 instrNorm &= ~(0x8FFFFFL << 13); 66 instrNorm |= (dest & 0x0FFFFFL) << 13; 67 instrNorm |= (dest & 0x100000L) << (36 - 20); 68 69 instr &= (1 << bitRes) - 1; 70 instr |= instrNorm << bitRes; 71 72 for (int j = 0; j < 6; ++j) 73 buf[i + bytePos + j] = (byte)(instr >>> (8 * j)); 74 } 75 } 76 77 i -= off; 78 pos += i; 79 return i; 80 } 81 } 82