Skip to content

Commit addaaca

Browse files
Nicolas PitreJunio C Hamano
authored andcommitted
improve base85 generated assembly code
This code is arguably pretty hot, if you use binary patches of course. This patch helps gcc generate both smaller and faster code especially in the error free path. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 42d0ee8 commit addaaca

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

base85.c

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,34 +44,38 @@ int decode_85(char *dst, char *buffer, int len)
4444
say2("decode 85 <%.*s>", len/4*5, buffer);
4545
while (len) {
4646
unsigned acc = 0;
47-
int cnt;
48-
for (cnt = 0; cnt < 5; cnt++, buffer++) {
49-
int ch = *((unsigned char *)buffer);
50-
int de = de85[ch];
51-
if (!de)
47+
int de, cnt = 4;
48+
unsigned char ch;
49+
do {
50+
ch = *buffer++;
51+
de = de85[ch];
52+
if (--de < 0)
5253
return error("invalid base85 alphabet %c", ch);
53-
de--;
54-
if (cnt == 4) {
55-
/*
56-
* Detect overflow. The largest
57-
* 5-letter possible is "|NsC0" to
58-
* encode 0xffffffff, and "|NsC" gives
59-
* 0x03030303 at this point (i.e.
60-
* 0xffffffff = 0x03030303 * 85).
61-
*/
62-
if (0x03030303 < acc ||
63-
(0x03030303 == acc && de))
64-
error("invalid base85 sequence %.5s",
65-
buffer-3);
66-
}
6754
acc = acc * 85 + de;
68-
say1(" <%08x>", acc);
69-
}
55+
} while (--cnt);
56+
ch = *buffer++;
57+
de = de85[ch];
58+
if (--de < 0)
59+
return error("invalid base85 alphabet %c", ch);
60+
/*
61+
* Detect overflow. The largest
62+
* 5-letter possible is "|NsC0" to
63+
* encode 0xffffffff, and "|NsC" gives
64+
* 0x03030303 at this point (i.e.
65+
* 0xffffffff = 0x03030303 * 85).
66+
*/
67+
if (0x03030303 < acc ||
68+
0xffffffff - de < (acc *= 85))
69+
error("invalid base85 sequence %.5s", buffer-5);
70+
acc += de;
7071
say1(" %08x", acc);
71-
for (cnt = 0; cnt < 4 && len; cnt++, len--) {
72-
*dst++ = (acc >> 24) & 0xff;
73-
acc = acc << 8;
74-
}
72+
73+
cnt = (len < 4) ? len : 4;
74+
len -= cnt;
75+
do {
76+
acc = (acc << 8) | (acc >> 24);
77+
*dst++ = acc;
78+
} while (--cnt);
7579
}
7680
say("\n");
7781

@@ -86,15 +90,17 @@ void encode_85(char *buf, unsigned char *data, int bytes)
8690
while (bytes) {
8791
unsigned acc = 0;
8892
int cnt;
89-
for (cnt = 0; cnt < 4 && bytes; cnt++, bytes--) {
93+
for (cnt = 24; cnt >= 0; cnt -= 8) {
9094
int ch = *data++;
91-
acc |= ch << ((3-cnt)*8);
95+
acc |= ch << cnt;
96+
if (--bytes == 0)
97+
break;
9298
}
9399
say1(" %08x", acc);
94-
for (cnt = 0; cnt < 5; cnt++) {
100+
for (cnt = 4; cnt >= 0; cnt--) {
95101
int val = acc % 85;
96102
acc /= 85;
97-
buf[4-cnt] = en85[val];
103+
buf[cnt] = en85[val];
98104
}
99105
buf += 5;
100106
}

0 commit comments

Comments
 (0)