/src/CMake/Utilities/cmliblzma/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 | 0 | { |
21 | 0 | static const uint32_t BRANCH_TABLE[32] = { |
22 | 0 | 0, 0, 0, 0, 0, 0, 0, 0, |
23 | 0 | 0, 0, 0, 0, 0, 0, 0, 0, |
24 | 0 | 4, 4, 6, 6, 0, 0, 7, 7, |
25 | 0 | 4, 4, 0, 0, 4, 4, 0, 0 |
26 | 0 | }; |
27 | |
|
28 | 0 | size_t i; |
29 | 0 | for (i = 0; i + 16 <= size; i += 16) { |
30 | 0 | const uint32_t instr_template = buffer[i] & 0x1F; |
31 | 0 | const uint32_t mask = BRANCH_TABLE[instr_template]; |
32 | 0 | uint32_t bit_pos = 5; |
33 | |
|
34 | 0 | for (size_t slot = 0; slot < 3; ++slot, bit_pos += 41) { |
35 | 0 | if (((mask >> slot) & 1) == 0) |
36 | 0 | continue; |
37 | | |
38 | 0 | const size_t byte_pos = (bit_pos >> 3); |
39 | 0 | const uint32_t bit_res = bit_pos & 0x7; |
40 | 0 | uint64_t instruction = 0; |
41 | |
|
42 | 0 | for (size_t j = 0; j < 6; ++j) |
43 | 0 | instruction += (uint64_t)( |
44 | 0 | buffer[i + j + byte_pos]) |
45 | 0 | << (8 * j); |
46 | |
|
47 | 0 | uint64_t inst_norm = instruction >> bit_res; |
48 | |
|
49 | 0 | if (((inst_norm >> 37) & 0xF) == 0x5 |
50 | 0 | && ((inst_norm >> 9) & 0x7) == 0 |
51 | | /* && (inst_norm & 0x3F)== 0 */ |
52 | 0 | ) { |
53 | 0 | uint32_t src = (uint32_t)( |
54 | 0 | (inst_norm >> 13) & 0xFFFFF); |
55 | 0 | src |= ((inst_norm >> 36) & 1) << 20; |
56 | |
|
57 | 0 | src <<= 4; |
58 | |
|
59 | 0 | uint32_t dest; |
60 | 0 | if (is_encoder) |
61 | 0 | dest = now_pos + (uint32_t)(i) + src; |
62 | 0 | else |
63 | 0 | dest = src - (now_pos + (uint32_t)(i)); |
64 | |
|
65 | 0 | dest >>= 4; |
66 | |
|
67 | 0 | inst_norm &= ~((uint64_t)(0x8FFFFF) << 13); |
68 | 0 | inst_norm |= (uint64_t)(dest & 0xFFFFF) << 13; |
69 | 0 | inst_norm |= (uint64_t)(dest & 0x100000) |
70 | 0 | << (36 - 20); |
71 | |
|
72 | 0 | instruction &= (1U << bit_res) - 1; |
73 | 0 | instruction |= (inst_norm << bit_res); |
74 | |
|
75 | 0 | for (size_t j = 0; j < 6; j++) |
76 | 0 | buffer[i + j + byte_pos] = (uint8_t)( |
77 | 0 | instruction |
78 | 0 | >> (8 * j)); |
79 | 0 | } |
80 | 0 | } |
81 | 0 | } |
82 | |
|
83 | 0 | return i; |
84 | 0 | } |
85 | | |
86 | | |
87 | | static lzma_ret |
88 | | ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, |
89 | | const lzma_filter_info *filters, bool is_encoder) |
90 | 0 | { |
91 | 0 | return lzma_simple_coder_init(next, allocator, filters, |
92 | 0 | &ia64_code, 0, 16, 16, is_encoder); |
93 | 0 | } |
94 | | |
95 | | |
96 | | #ifdef HAVE_ENCODER_IA64 |
97 | | extern lzma_ret |
98 | | lzma_simple_ia64_encoder_init(lzma_next_coder *next, |
99 | | const lzma_allocator *allocator, |
100 | | const lzma_filter_info *filters) |
101 | 0 | { |
102 | 0 | return ia64_coder_init(next, allocator, filters, true); |
103 | 0 | } |
104 | | #endif |
105 | | |
106 | | |
107 | | #ifdef HAVE_DECODER_IA64 |
108 | | extern lzma_ret |
109 | | lzma_simple_ia64_decoder_init(lzma_next_coder *next, |
110 | | const lzma_allocator *allocator, |
111 | | const lzma_filter_info *filters) |
112 | 0 | { |
113 | | return ia64_coder_init(next, allocator, filters, false); |
114 | 0 | } |
115 | | #endif |