/* Bra.h -- Branch converters for executables12024-01-20 : Igor Pavlov : Public domain */23#ifndef ZIP7_INC_BRA_H4#define ZIP7_INC_BRA_H56#include "7zTypes.h"78EXTERN_C_BEGIN910/* #define PPC BAD_PPC_11 // for debug */1112#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec13#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc14#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name)15#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name)16#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec17#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc1819#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc)20#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state)2122typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv));23typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt));2425#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 026Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86));27Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86));2829#define Z7_BRANCH_FUNCS_DECL(name) \30Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \31Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name));3233Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64)34Z7_BRANCH_FUNCS_DECL (BranchConv_ARM)35Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT)36Z7_BRANCH_FUNCS_DECL (BranchConv_PPC)37Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC)38Z7_BRANCH_FUNCS_DECL (BranchConv_IA64)39Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV)4041/*42These functions convert data that contain CPU instructions.43Each such function converts relative addresses to absolute addresses in some44branch instructions: CALL (in all converters) and JUMP (X86 converter only).45Such conversion allows to increase compression ratio, if we compress that data.4647There are 2 types of converters:48Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc);49Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state);50Each Converter supports 2 versions: one for encoding51and one for decoding (_Enc/_Dec postfixes in function name).5253In params:54data : data buffer55size : size of data56pc : current virtual Program Counter (Instruction Pointer) value57In/Out param:58state : pointer to state variable (for X86 converter only)5960Return:61The pointer to position in (data) buffer after last byte that was processed.62If the caller calls converter again, it must call it starting with that position.63But the caller is allowed to move data in buffer. So pointer to64current processed position also will be changed for next call.65Also the caller must increase internal (pc) value for next call.6667Each converter has some characteristics: Endian, Alignment, LookAhead.68Type Endian Alignment LookAhead6970X86 little 1 471ARMT little 2 272RISCV little 2 673ARM little 4 074ARM64 little 4 075PPC big 4 076SPARC big 4 077IA64 little 16 07879(data) must be aligned for (Alignment).80processed size can be calculated as:81SizeT processed = Conv(data, size, pc) - data;82if (processed == 0)83it means that converter needs more data for processing.84If (size < Alignment + LookAhead)85then (processed == 0) is allowed.8687Example code for conversion in loop:88UInt32 pc = 0;89size = 0;90for (;;)91{92size += Load_more_input_data(data + size);93SizeT processed = Conv(data, size, pc) - data;94if (processed == 0 && no_more_input_data_after_size)95break; // we stop convert loop96data += processed;97size -= processed;98pc += processed;99}100*/101102EXTERN_C_END103104#endif105106107