Import from http://svn.freenode.net/ircd-seven/private/beu/seven (r196).
[seven-1.x.git] / src / fnvhash.s
blob013b83801d95ea0838ca4194204e62efe6153645
1 /*
2 * charybdis: a slightly useful ircd.
3 * fnvhash.s: x86-optimised FNV hashing implementation
5 * Copyright (c) 2006 charybdis development team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
22 * $Id: fnvhash.s 26 2006-09-20 18:02:06Z spb $
25 /* Safely moves hashv from %edx to %eax and returns back to the calling parent. */
26 fnv_out:
27 movzbl 12(%ebp), %ecx
28 movl -4(%ebp), %eax
29 movl %eax, %edx
30 shrl %cl, %edx
31 movl 12(%ebp), %eax
32 xorl $2, %eax
33 decl %eax
34 andl -4(%ebp), %eax
35 xorl %edx, %eax
36 movl %eax, -4(%ebp)
37 movl -4(%ebp), %eax
38 leave
39 ret
42 * Capitalizes the contents of %eax and adds it to the hashv in %edx.
43 * Returns hashv in register %eax.
44 * - nenolod
46 .globl fnv_hash_upper
47 .type fnv_hash_upper, @function
48 fnv_hash_upper:
49 pushl %ebp
50 movl %esp, %ebp
51 subl $4, %esp
52 movl $-2128831035, -4(%ebp) /* u_int32_t h = FNV1_32_INIT */
53 .eat_data_upper: /* while loop construct */
54 movl 8(%ebp), %eax /* move value of *s to %eax */
55 cmpb $0, (%eax) /* is eax == 0? */
56 jne .hash_capitalized /* if no, then capitalize and hash */
57 jmp fnv_out /* if yes, then exit out of the loop */
58 .hash_capitalized:
59 movl 8(%ebp), %eax
60 movzbl (%eax), %eax /* increment s (%eax) */
61 movzbl ToUpperTab(%eax), %edx /* hashv ^= ToUpperTab(%eax) */
62 leal -4(%ebp), %eax
63 xorl %edx, (%eax) /* hashv = 0 */
64 incl 8(%ebp)
65 movl -4(%ebp), %eax
66 imull $16777619, %eax, %eax /* FNV1_32_PRIME */
67 movl %eax, -4(%ebp) /* add this byte to hashv, and */
68 jmp .eat_data_upper /* go back for more... */
71 * Hashes (no case change) the contents of %eax and adds it to the hashv in %edx.
72 * Returns hashv in register %eax.
73 * - nenolod
75 .globl fnv_hash
76 .type fnv_hash, @function
77 fnv_hash:
78 pushl %ebp
79 movl %esp, %ebp
80 subl $4, %esp
81 movl $-2128831035, -4(%ebp) /* u_int32_t h = FNV1_32_INIT */
82 .eat_data: /* again, the while loop construct */
83 movl 8(%ebp), %eax /* move value of *s to eax */
84 cmpb $0, (%eax) /* is eax == 0? */
85 jne .hash_lowercase /* if not, jump to .hash_lowercase */
86 jmp fnv_out /* otherwise, jump to fnv_out */
87 .hash_lowercase:
88 movl 8(%ebp), %eax
89 movzbl (%eax), %edx
90 leal -4(%ebp), %eax
91 xorl %edx, (%eax)
92 incl 8(%ebp) /* h << 1 */
93 movl -4(%ebp), %eax
94 imull $16777619, %eax, %eax /* FNV1_32_PRIME */
95 movl %eax, -4(%ebp) /* add this byte to hashv, then */
96 jmp .eat_data /* check for more... */
99 * Hashes (no case change) the contents of %eax and adds it to the hashv in %edx.
100 * Returns hashv in register %eax.
102 * Bounds checking is performed.
103 * - nenolod
105 .globl fnv_hash_len
106 .type fnv_hash_len, @function
107 fnv_hash_len:
108 pushl %ebp
109 movl %esp, %ebp
110 subl $8, %esp
111 movl $-2128831035, -4(%ebp)
112 movl 16(%ebp), %eax
113 addl 8(%ebp), %eax
114 movl %eax, -8(%ebp)
115 .eat_data_len:
116 movl 8(%ebp), %eax
117 cmpb $0, (%eax)
118 je fnv_out
119 movl 8(%ebp), %eax
120 cmpl -8(%ebp), %eax
121 jb .hash_lowercase_len
122 jmp fnv_out
123 .hash_lowercase_len:
124 movl 8(%ebp), %eax
125 movzbl (%eax), %edx
126 leal -4(%ebp), %eax
127 xorl %edx, (%eax)
128 incl 8(%ebp)
129 movl -4(%ebp), %eax
130 imull $16777619, %eax, %eax /* FNV1_32_PRIME */
131 movl %eax, -4(%ebp)
132 jmp .eat_data_len
135 * Hashes (no case change) the contents of %eax and adds it to the hashv in %edx.
136 * Returns hashv in register %eax.
138 * Bounds checking is performed.
139 * - nenolod
141 .globl fnv_hash_upper_len
142 .type fnv_hash_upper_len, @function
143 fnv_hash_upper_len:
144 pushl %ebp
145 movl %esp, %ebp
146 subl $8, %esp
147 movl $-2128831035, -4(%ebp)
148 movl 16(%ebp), %eax
149 addl 8(%ebp), %eax
150 movl %eax, -8(%ebp)
151 .eat_upper_len:
152 movl 8(%ebp), %eax
153 cmpb $0, (%eax)
154 je fnv_out
155 movl 8(%ebp), %eax
156 cmpl -8(%ebp), %eax
157 jb .hash_uppercase_len
158 jmp fnv_out
159 .hash_uppercase_len:
160 movl 8(%ebp), %eax
161 movzbl (%eax), %eax
162 movzbl ToUpperTab(%eax), %edx
163 leal -4(%ebp), %eax
164 xorl %edx, (%eax)
165 incl 8(%ebp)
166 movl -4(%ebp), %eax
167 imull $16777619, %eax, %eax /* FNV1_32_PRIME */
168 movl %eax, -4(%ebp)
169 jmp .eat_upper_len