xref: /dflybsd-src/contrib/xz/src/liblzma/simple/ia64.c (revision b5feb3da7c498482b19d14ac6f2b1901005f7d94)
12940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
22940b44dSPeter Avalos //
32940b44dSPeter Avalos /// \file       ia64.c
42940b44dSPeter Avalos /// \brief      Filter for IA64 (Itanium) binaries
52940b44dSPeter Avalos ///
62940b44dSPeter Avalos //  Authors:    Igor Pavlov
72940b44dSPeter Avalos //              Lasse Collin
82940b44dSPeter Avalos //
92940b44dSPeter Avalos //  This file has been put into the public domain.
102940b44dSPeter Avalos //  You can do whatever you want with this file.
112940b44dSPeter Avalos //
122940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
132940b44dSPeter Avalos 
142940b44dSPeter Avalos #include "simple_private.h"
152940b44dSPeter Avalos 
162940b44dSPeter Avalos 
172940b44dSPeter Avalos static size_t
ia64_code(void * simple lzma_attribute ((__unused__)),uint32_t now_pos,bool is_encoder,uint8_t * buffer,size_t size)1846a2189dSzrj ia64_code(void *simple lzma_attribute((__unused__)),
192940b44dSPeter Avalos 		uint32_t now_pos, bool is_encoder,
202940b44dSPeter Avalos 		uint8_t *buffer, size_t size)
212940b44dSPeter Avalos {
222940b44dSPeter Avalos 	static const uint32_t BRANCH_TABLE[32] = {
232940b44dSPeter Avalos 		0, 0, 0, 0, 0, 0, 0, 0,
242940b44dSPeter Avalos 		0, 0, 0, 0, 0, 0, 0, 0,
252940b44dSPeter Avalos 		4, 4, 6, 6, 0, 0, 7, 7,
262940b44dSPeter Avalos 		4, 4, 0, 0, 4, 4, 0, 0
272940b44dSPeter Avalos 	};
282940b44dSPeter Avalos 
292940b44dSPeter Avalos 	size_t i;
302940b44dSPeter Avalos 	for (i = 0; i + 16 <= size; i += 16) {
312940b44dSPeter Avalos 		const uint32_t instr_template = buffer[i] & 0x1F;
322940b44dSPeter Avalos 		const uint32_t mask = BRANCH_TABLE[instr_template];
332940b44dSPeter Avalos 		uint32_t bit_pos = 5;
342940b44dSPeter Avalos 
352940b44dSPeter Avalos 		for (size_t slot = 0; slot < 3; ++slot, bit_pos += 41) {
362940b44dSPeter Avalos 			if (((mask >> slot) & 1) == 0)
372940b44dSPeter Avalos 				continue;
382940b44dSPeter Avalos 
392940b44dSPeter Avalos 			const size_t byte_pos = (bit_pos >> 3);
402940b44dSPeter Avalos 			const uint32_t bit_res = bit_pos & 0x7;
412940b44dSPeter Avalos 			uint64_t instruction = 0;
422940b44dSPeter Avalos 
432940b44dSPeter Avalos 			for (size_t j = 0; j < 6; ++j)
442940b44dSPeter Avalos 				instruction += (uint64_t)(
452940b44dSPeter Avalos 						buffer[i + j + byte_pos])
462940b44dSPeter Avalos 						<< (8 * j);
472940b44dSPeter Avalos 
482940b44dSPeter Avalos 			uint64_t inst_norm = instruction >> bit_res;
492940b44dSPeter Avalos 
502940b44dSPeter Avalos 			if (((inst_norm >> 37) & 0xF) == 0x5
512940b44dSPeter Avalos 					&& ((inst_norm >> 9) & 0x7) == 0
522940b44dSPeter Avalos 					/* &&  (inst_norm & 0x3F)== 0 */
532940b44dSPeter Avalos 					) {
542940b44dSPeter Avalos 				uint32_t src = (uint32_t)(
552940b44dSPeter Avalos 						(inst_norm >> 13) & 0xFFFFF);
562940b44dSPeter Avalos 				src |= ((inst_norm >> 36) & 1) << 20;
572940b44dSPeter Avalos 
582940b44dSPeter Avalos 				src <<= 4;
592940b44dSPeter Avalos 
602940b44dSPeter Avalos 				uint32_t dest;
612940b44dSPeter Avalos 				if (is_encoder)
622940b44dSPeter Avalos 					dest = now_pos + (uint32_t)(i) + src;
632940b44dSPeter Avalos 				else
642940b44dSPeter Avalos 					dest = src - (now_pos + (uint32_t)(i));
652940b44dSPeter Avalos 
662940b44dSPeter Avalos 				dest >>= 4;
672940b44dSPeter Avalos 
682940b44dSPeter Avalos 				inst_norm &= ~((uint64_t)(0x8FFFFF) << 13);
692940b44dSPeter Avalos 				inst_norm |= (uint64_t)(dest & 0xFFFFF) << 13;
702940b44dSPeter Avalos 				inst_norm |= (uint64_t)(dest & 0x100000)
712940b44dSPeter Avalos 						<< (36 - 20);
722940b44dSPeter Avalos 
73*e151908bSDaniel Fojt 				instruction &= (1U << bit_res) - 1;
742940b44dSPeter Avalos 				instruction |= (inst_norm << bit_res);
752940b44dSPeter Avalos 
762940b44dSPeter Avalos 				for (size_t j = 0; j < 6; j++)
772940b44dSPeter Avalos 					buffer[i + j + byte_pos] = (uint8_t)(
782940b44dSPeter Avalos 							instruction
792940b44dSPeter Avalos 							>> (8 * j));
802940b44dSPeter Avalos 			}
812940b44dSPeter Avalos 		}
822940b44dSPeter Avalos 	}
832940b44dSPeter Avalos 
842940b44dSPeter Avalos 	return i;
852940b44dSPeter Avalos }
862940b44dSPeter Avalos 
872940b44dSPeter Avalos 
882940b44dSPeter Avalos static lzma_ret
ia64_coder_init(lzma_next_coder * next,const lzma_allocator * allocator,const lzma_filter_info * filters,bool is_encoder)8915ab8c86SJohn Marino ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
902940b44dSPeter Avalos 		const lzma_filter_info *filters, bool is_encoder)
912940b44dSPeter Avalos {
922940b44dSPeter Avalos 	return lzma_simple_coder_init(next, allocator, filters,
932940b44dSPeter Avalos 			&ia64_code, 0, 16, 16, is_encoder);
942940b44dSPeter Avalos }
952940b44dSPeter Avalos 
962940b44dSPeter Avalos 
972940b44dSPeter Avalos extern lzma_ret
lzma_simple_ia64_encoder_init(lzma_next_coder * next,const lzma_allocator * allocator,const lzma_filter_info * filters)982940b44dSPeter Avalos lzma_simple_ia64_encoder_init(lzma_next_coder *next,
9915ab8c86SJohn Marino 		const lzma_allocator *allocator,
10015ab8c86SJohn Marino 		const lzma_filter_info *filters)
1012940b44dSPeter Avalos {
1022940b44dSPeter Avalos 	return ia64_coder_init(next, allocator, filters, true);
1032940b44dSPeter Avalos }
1042940b44dSPeter Avalos 
1052940b44dSPeter Avalos 
1062940b44dSPeter Avalos extern lzma_ret
lzma_simple_ia64_decoder_init(lzma_next_coder * next,const lzma_allocator * allocator,const lzma_filter_info * filters)1072940b44dSPeter Avalos lzma_simple_ia64_decoder_init(lzma_next_coder *next,
10815ab8c86SJohn Marino 		const lzma_allocator *allocator,
10915ab8c86SJohn Marino 		const lzma_filter_info *filters)
1102940b44dSPeter Avalos {
1112940b44dSPeter Avalos 	return ia64_coder_init(next, allocator, filters, false);
1122940b44dSPeter Avalos }
113