/src/xz/src/liblzma/simple/ia64.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: 0BSD |
2 | | |
3 | | /////////////////////////////////////////////////////////////////////////////// |
4 | | // |
5 | | /// \file ia64.c |
6 | | /// \brief Filter for IA64 (Itanium) binaries |
7 | | /// |
8 | | // Authors: Igor Pavlov |
9 | | // Lasse Collin |
10 | | // |
11 | | /////////////////////////////////////////////////////////////////////////////// |
12 | | |
13 | | #include "simple_private.h" |
14 | | |
15 | | |
16 | | static size_t |
17 | | ia64_code(void *simple lzma_attribute((__unused__)), |
18 | | uint32_t now_pos, bool is_encoder, |
19 | | uint8_t *buffer, size_t size) |
20 | 20.1k | { |
21 | 20.1k | static const uint32_t BRANCH_TABLE[32] = { |
22 | 20.1k | 0, 0, 0, 0, 0, 0, 0, 0, |
23 | 20.1k | 0, 0, 0, 0, 0, 0, 0, 0, |
24 | 20.1k | 4, 4, 6, 6, 0, 0, 7, 7, |
25 | 20.1k | 4, 4, 0, 0, 4, 4, 0, 0 |
26 | 20.1k | }; |
27 | | |
28 | 20.1k | size &= ~(size_t)15; |
29 | | |
30 | 20.1k | size_t i; |
31 | 154k | for (i = 0; i < size; i += 16) { |
32 | 134k | const uint32_t instr_template = buffer[i] & 0x1F; |
33 | 134k | const uint32_t mask = BRANCH_TABLE[instr_template]; |
34 | 134k | uint32_t bit_pos = 5; |
35 | | |
36 | 537k | for (size_t slot = 0; slot < 3; ++slot, bit_pos += 41) { |
37 | 402k | if (((mask >> slot) & 1) == 0) |
38 | 112k | continue; |
39 | | |
40 | 290k | const size_t byte_pos = (bit_pos >> 3); |
41 | 290k | const uint32_t bit_res = bit_pos & 0x7; |
42 | 290k | uint64_t instruction = 0; |
43 | | |
44 | 2.03M | for (size_t j = 0; j < 6; ++j) |
45 | 1.74M | instruction += (uint64_t)( |
46 | 1.74M | buffer[i + j + byte_pos]) |
47 | 1.74M | << (8 * j); |
48 | | |
49 | 290k | uint64_t inst_norm = instruction >> bit_res; |
50 | | |
51 | 290k | if (((inst_norm >> 37) & 0xF) == 0x5 |
52 | 94.9k | && ((inst_norm >> 9) & 0x7) == 0 |
53 | | /* && (inst_norm & 0x3F)== 0 */ |
54 | 290k | ) { |
55 | 1.79k | uint32_t src = (uint32_t)( |
56 | 1.79k | (inst_norm >> 13) & 0xFFFFF); |
57 | 1.79k | src |= ((inst_norm >> 36) & 1) << 20; |
58 | | |
59 | 1.79k | src <<= 4; |
60 | | |
61 | 1.79k | uint32_t dest; |
62 | 1.79k | if (is_encoder) |
63 | 0 | dest = now_pos + (uint32_t)(i) + src; |
64 | 1.79k | else |
65 | 1.79k | dest = src - (now_pos + (uint32_t)(i)); |
66 | | |
67 | 1.79k | dest >>= 4; |
68 | | |
69 | 1.79k | inst_norm &= ~((uint64_t)(0x8FFFFF) << 13); |
70 | 1.79k | inst_norm |= (uint64_t)(dest & 0xFFFFF) << 13; |
71 | 1.79k | inst_norm |= (uint64_t)(dest & 0x100000) |
72 | 1.79k | << (36 - 20); |
73 | | |
74 | 1.79k | instruction &= (1U << bit_res) - 1; |
75 | 1.79k | instruction |= (inst_norm << bit_res); |
76 | | |
77 | 12.5k | for (size_t j = 0; j < 6; j++) |
78 | 10.7k | buffer[i + j + byte_pos] = (uint8_t)( |
79 | 10.7k | instruction |
80 | 10.7k | >> (8 * j)); |
81 | 1.79k | } |
82 | 290k | } |
83 | 134k | } |
84 | | |
85 | 20.1k | return i; |
86 | 20.1k | } |
87 | | |
88 | | |
89 | | static lzma_ret |
90 | | ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, |
91 | | const lzma_filter_info *filters, bool is_encoder) |
92 | 723 | { |
93 | 723 | return lzma_simple_coder_init(next, allocator, filters, |
94 | 723 | &ia64_code, 0, 16, 16, is_encoder); |
95 | 723 | } |
96 | | |
97 | | |
98 | | #ifdef HAVE_ENCODER_IA64 |
99 | | extern lzma_ret |
100 | | lzma_simple_ia64_encoder_init(lzma_next_coder *next, |
101 | | const lzma_allocator *allocator, |
102 | | const lzma_filter_info *filters) |
103 | 0 | { |
104 | 0 | return ia64_coder_init(next, allocator, filters, true); |
105 | 0 | } |
106 | | #endif |
107 | | |
108 | | |
109 | | #ifdef HAVE_DECODER_IA64 |
110 | | extern lzma_ret |
111 | | lzma_simple_ia64_decoder_init(lzma_next_coder *next, |
112 | | const lzma_allocator *allocator, |
113 | | const lzma_filter_info *filters) |
114 | 723 | { |
115 | | return ia64_coder_init(next, allocator, filters, false); |
116 | 723 | } |
117 | | #endif |