Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/lzma/include/Bra.h
4253 views
1
/* Bra.h -- Branch converters for executables
2
2024-01-20 : Igor Pavlov : Public domain */
3
4
#ifndef ZIP7_INC_BRA_H
5
#define ZIP7_INC_BRA_H
6
7
#include "7zTypes.h"
8
9
EXTERN_C_BEGIN
10
11
/* #define PPC BAD_PPC_11 // for debug */
12
13
#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec
14
#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc
15
#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name)
16
#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name)
17
#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec
18
#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc
19
20
#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc)
21
#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state)
22
23
typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv));
24
typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt));
25
26
#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0
27
Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86));
28
Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86));
29
30
#define Z7_BRANCH_FUNCS_DECL(name) \
31
Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \
32
Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name));
33
34
Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64)
35
Z7_BRANCH_FUNCS_DECL (BranchConv_ARM)
36
Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT)
37
Z7_BRANCH_FUNCS_DECL (BranchConv_PPC)
38
Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC)
39
Z7_BRANCH_FUNCS_DECL (BranchConv_IA64)
40
Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV)
41
42
/*
43
These functions convert data that contain CPU instructions.
44
Each such function converts relative addresses to absolute addresses in some
45
branch instructions: CALL (in all converters) and JUMP (X86 converter only).
46
Such conversion allows to increase compression ratio, if we compress that data.
47
48
There are 2 types of converters:
49
Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc);
50
Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state);
51
Each Converter supports 2 versions: one for encoding
52
and one for decoding (_Enc/_Dec postfixes in function name).
53
54
In params:
55
data : data buffer
56
size : size of data
57
pc : current virtual Program Counter (Instruction Pointer) value
58
In/Out param:
59
state : pointer to state variable (for X86 converter only)
60
61
Return:
62
The pointer to position in (data) buffer after last byte that was processed.
63
If the caller calls converter again, it must call it starting with that position.
64
But the caller is allowed to move data in buffer. So pointer to
65
current processed position also will be changed for next call.
66
Also the caller must increase internal (pc) value for next call.
67
68
Each converter has some characteristics: Endian, Alignment, LookAhead.
69
Type Endian Alignment LookAhead
70
71
X86 little 1 4
72
ARMT little 2 2
73
RISCV little 2 6
74
ARM little 4 0
75
ARM64 little 4 0
76
PPC big 4 0
77
SPARC big 4 0
78
IA64 little 16 0
79
80
(data) must be aligned for (Alignment).
81
processed size can be calculated as:
82
SizeT processed = Conv(data, size, pc) - data;
83
if (processed == 0)
84
it means that converter needs more data for processing.
85
If (size < Alignment + LookAhead)
86
then (processed == 0) is allowed.
87
88
Example code for conversion in loop:
89
UInt32 pc = 0;
90
size = 0;
91
for (;;)
92
{
93
size += Load_more_input_data(data + size);
94
SizeT processed = Conv(data, size, pc) - data;
95
if (processed == 0 && no_more_input_data_after_size)
96
break; // we stop convert loop
97
data += processed;
98
size -= processed;
99
pc += processed;
100
}
101
*/
102
103
EXTERN_C_END
104
105
#endif
106
107