diff options
Diffstat (limited to 'C/Bra.c')
-rw-r--r-- | C/Bra.c | 230 |
1 files changed, 230 insertions, 0 deletions
@@ -0,0 +1,230 @@ | |||
1 | /* Bra.c -- Converters for RISC code | ||
2 | 2021-02-09 : Igor Pavlov : Public domain */ | ||
3 | |||
4 | #include "Precomp.h" | ||
5 | |||
6 | #include "CpuArch.h" | ||
7 | #include "Bra.h" | ||
8 | |||
9 | SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) | ||
10 | { | ||
11 | Byte *p; | ||
12 | const Byte *lim; | ||
13 | size &= ~(size_t)3; | ||
14 | ip += 4; | ||
15 | p = data; | ||
16 | lim = data + size; | ||
17 | |||
18 | if (encoding) | ||
19 | |||
20 | for (;;) | ||
21 | { | ||
22 | for (;;) | ||
23 | { | ||
24 | if (p >= lim) | ||
25 | return (SizeT)(p - data); | ||
26 | p += 4; | ||
27 | if (p[-1] == 0xEB) | ||
28 | break; | ||
29 | } | ||
30 | { | ||
31 | UInt32 v = GetUi32(p - 4); | ||
32 | v <<= 2; | ||
33 | v += ip + (UInt32)(p - data); | ||
34 | v >>= 2; | ||
35 | v &= 0x00FFFFFF; | ||
36 | v |= 0xEB000000; | ||
37 | SetUi32(p - 4, v); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | for (;;) | ||
42 | { | ||
43 | for (;;) | ||
44 | { | ||
45 | if (p >= lim) | ||
46 | return (SizeT)(p - data); | ||
47 | p += 4; | ||
48 | if (p[-1] == 0xEB) | ||
49 | break; | ||
50 | } | ||
51 | { | ||
52 | UInt32 v = GetUi32(p - 4); | ||
53 | v <<= 2; | ||
54 | v -= ip + (UInt32)(p - data); | ||
55 | v >>= 2; | ||
56 | v &= 0x00FFFFFF; | ||
57 | v |= 0xEB000000; | ||
58 | SetUi32(p - 4, v); | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | |||
64 | SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) | ||
65 | { | ||
66 | Byte *p; | ||
67 | const Byte *lim; | ||
68 | size &= ~(size_t)1; | ||
69 | p = data; | ||
70 | lim = data + size - 4; | ||
71 | |||
72 | if (encoding) | ||
73 | |||
74 | for (;;) | ||
75 | { | ||
76 | UInt32 b1; | ||
77 | for (;;) | ||
78 | { | ||
79 | UInt32 b3; | ||
80 | if (p > lim) | ||
81 | return (SizeT)(p - data); | ||
82 | b1 = p[1]; | ||
83 | b3 = p[3]; | ||
84 | p += 2; | ||
85 | b1 ^= 8; | ||
86 | if ((b3 & b1) >= 0xF8) | ||
87 | break; | ||
88 | } | ||
89 | { | ||
90 | UInt32 v = | ||
91 | ((UInt32)b1 << 19) | ||
92 | + (((UInt32)p[1] & 0x7) << 8) | ||
93 | + (((UInt32)p[-2] << 11)) | ||
94 | + (p[0]); | ||
95 | |||
96 | p += 2; | ||
97 | { | ||
98 | UInt32 cur = (ip + (UInt32)(p - data)) >> 1; | ||
99 | v += cur; | ||
100 | } | ||
101 | |||
102 | p[-4] = (Byte)(v >> 11); | ||
103 | p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); | ||
104 | p[-2] = (Byte)v; | ||
105 | p[-1] = (Byte)(0xF8 | (v >> 8)); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | for (;;) | ||
110 | { | ||
111 | UInt32 b1; | ||
112 | for (;;) | ||
113 | { | ||
114 | UInt32 b3; | ||
115 | if (p > lim) | ||
116 | return (SizeT)(p - data); | ||
117 | b1 = p[1]; | ||
118 | b3 = p[3]; | ||
119 | p += 2; | ||
120 | b1 ^= 8; | ||
121 | if ((b3 & b1) >= 0xF8) | ||
122 | break; | ||
123 | } | ||
124 | { | ||
125 | UInt32 v = | ||
126 | ((UInt32)b1 << 19) | ||
127 | + (((UInt32)p[1] & 0x7) << 8) | ||
128 | + (((UInt32)p[-2] << 11)) | ||
129 | + (p[0]); | ||
130 | |||
131 | p += 2; | ||
132 | { | ||
133 | UInt32 cur = (ip + (UInt32)(p - data)) >> 1; | ||
134 | v -= cur; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); | ||
139 | SetUi16(p - 2, (UInt16)(v | 0xF800)); | ||
140 | */ | ||
141 | |||
142 | p[-4] = (Byte)(v >> 11); | ||
143 | p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); | ||
144 | p[-2] = (Byte)v; | ||
145 | p[-1] = (Byte)(0xF8 | (v >> 8)); | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
150 | |||
151 | SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) | ||
152 | { | ||
153 | Byte *p; | ||
154 | const Byte *lim; | ||
155 | size &= ~(size_t)3; | ||
156 | ip -= 4; | ||
157 | p = data; | ||
158 | lim = data + size; | ||
159 | |||
160 | for (;;) | ||
161 | { | ||
162 | for (;;) | ||
163 | { | ||
164 | if (p >= lim) | ||
165 | return (SizeT)(p - data); | ||
166 | p += 4; | ||
167 | /* if ((v & 0xFC000003) == 0x48000001) */ | ||
168 | if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) | ||
169 | break; | ||
170 | } | ||
171 | { | ||
172 | UInt32 v = GetBe32(p - 4); | ||
173 | if (encoding) | ||
174 | v += ip + (UInt32)(p - data); | ||
175 | else | ||
176 | v -= ip + (UInt32)(p - data); | ||
177 | v &= 0x03FFFFFF; | ||
178 | v |= 0x48000000; | ||
179 | SetBe32(p - 4, v); | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | |||
185 | SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) | ||
186 | { | ||
187 | Byte *p; | ||
188 | const Byte *lim; | ||
189 | size &= ~(size_t)3; | ||
190 | ip -= 4; | ||
191 | p = data; | ||
192 | lim = data + size; | ||
193 | |||
194 | for (;;) | ||
195 | { | ||
196 | for (;;) | ||
197 | { | ||
198 | if (p >= lim) | ||
199 | return (SizeT)(p - data); | ||
200 | /* | ||
201 | v = GetBe32(p); | ||
202 | p += 4; | ||
203 | m = v + ((UInt32)5 << 29); | ||
204 | m ^= (UInt32)7 << 29; | ||
205 | m += (UInt32)1 << 22; | ||
206 | if ((m & ((UInt32)0x1FF << 23)) == 0) | ||
207 | break; | ||
208 | */ | ||
209 | p += 4; | ||
210 | if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || | ||
211 | (p[-4] == 0x7F && (p[-3] >= 0xC0))) | ||
212 | break; | ||
213 | } | ||
214 | { | ||
215 | UInt32 v = GetBe32(p - 4); | ||
216 | v <<= 2; | ||
217 | if (encoding) | ||
218 | v += ip + (UInt32)(p - data); | ||
219 | else | ||
220 | v -= ip + (UInt32)(p - data); | ||
221 | |||
222 | v &= 0x01FFFFFF; | ||
223 | v -= (UInt32)1 << 24; | ||
224 | v ^= 0xFF000000; | ||
225 | v >>= 2; | ||
226 | v |= 0x40000000; | ||
227 | SetBe32(p - 4, v); | ||
228 | } | ||
229 | } | ||
230 | } | ||