Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

An early stab at an LLVM IR version of hash, will

 probably drop and go with C.
  • Loading branch information...
commit 5b9cbb032cb20bed990943bd1673c182b34b3be7 1 parent 786b91a
@scooby authored
Showing with 170 additions and 0 deletions.
  1. +170 −0 lolir.ll
View
170 lolir.ll
@@ -0,0 +1,170 @@
+
+; //---------------------------------------------------------------------------
+; // MurmurHash3 was written by Austin Appleby, and is placed in the public
+; // domain. The author hereby disclaims copyright to this source code.
+;
+; // Note - The x86 and x64 versions do _not_ produce the same results, as the
+; // algorithms are optimized for their respective platforms. You can still
+; // compile and run any of them on any platform, but your performance with the
+; // non-native version will be less than optimal.
+
+; Adapted by Benjamin Samuel from original C++ at:
+; http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp?r=131
+
+%word = type i32
+
+define hidden fastcc i32 @rotl32(i32 %x, i8 %r) inlinehint {
+ %a = shl i32 %x, %r
+ %rr = sub i32 32, %r
+ %b = shr i32 %x, %rr
+ %c = or i32 %a, %b
+ ret i32 %d
+}
+
+define hidden fastcc i32 @getblock32(i32* %p, i32 %i) inlinehint {
+ ; p[i], for uint32_t* p
+ %a = mul nuw i32 %i, 4
+ %b = ptrtoint i32* %p to i32
+ %c = add nuw i32 %b, %a
+ %d = inttoptr i32 %c to i32*
+ %e = load %d
+ ret i32 %e
+}
+
+define hidden fastcc i32 @getbyte32(i8* %p, i32 %i) inlinehint {
+ ; looks up a byte, zero-extends to 32 bits
+ %a = mul nuw i32 %i, 1
+ %b = ptrtoint i8* %p to i32
+ %c = add nuw i32 %b, %a
+ %d = inttoptr i32 %c to i8*
+ %e = load %d
+ %f = zext i8 %e to i32
+ ret i32 %f
+}
+
+define hidden fastcc i32 @fmix32(i32 %h) inlinehint {
+ ; h ^= h >> 16;
+ %hs = shr i32 %h , 16
+ %h = xor i32 %h, %hs
+ ; h *= 0x85ebca6b;
+ %h = mul i32 %h, 0x85ebca6b
+ ; h ^= h >> 13;
+ %hs = shr i32 %h, 13
+ %h = xor i32 %h, %hs
+ ; h *= 0xc2b2ae35;
+ %h = mul i32 %h, 0xc2b2ae35
+ ; h ^= h >> 16;
+ %hs = shr i32 %h, 16
+ %h = xor i32 %h, %hs
+ ret i32 %h
+}
+
+; void MurmurHash3_x86_32 ( const void * key, int len,
+; uint32_t seed, void * out )
+; Note: returning the hash directly, to emulate C behavior
+; just write a wrapper.
+define hidden fastcc i32 @murmur3_x86_32(i8* %key, i32 %len, i32 %seed) {
+ ; const uint8_t * data = (const uint8_t*)key;
+ %data = %key
+ ; nblocks = len / 4;
+ %nblocks = div i32 %len, 4
+ ; same as c
+ %h1 = %seed
+ %c1 = 0xcc9e2d51
+ %c2 = 0x1b873593
+
+ Body:
+
+ ; const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
+ ; data is byte ptr
+ %datai = ptrtoint i8* data to i32
+ %z1 = mul i32 %nblocks, 4
+ %z2 = add i32 %datai, %z1
+ %blocks = inttoptr i32 %z2 to i32*
+
+ ; for(int i = -nblocks; i; i++)
+ %i = sub i32 0, %nblocks
+
+ BodyForTest:
+ %bft_cmp = icmp eq i32 %i, 0
+ br i1 %bft_cmp, label %BodyForExit, label %BodyForStart
+
+ BodyForStart:
+ ; uint32_t k1 = getblock(blocks,i);
+ %k1 = call i32 @getblock32(i32* %blocks, i32 %i)
+ ; k1 *= c1;
+ %k1 = mul i32 %k1, %c1
+ ; k1 = ROTL32(k1,15);
+ %k1 = call i32 @rotl32(i32 %k1, i8 15)
+ ; k1 *= c2;
+ %k1 = mul i32 %k1, %c2
+
+ ; h1 ^= k1;
+ %h1 = xor i32 %h1, %k1
+ ; h1 = ROTL32(h1,13);
+ %h1 = call i32 @rotl32(i32 %h1, i8 13)
+ ; h1 = h1*5+0xe6546b64;
+
+ BodyForEnds:
+ %i = add i32 %i, 1
+ br label %BodyForTest
+
+ BodyForExit:
+
+ ; // tail
+ ; const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
+ ; Same as blocks, only this is an i8*
+ %tail = bitcast i32* %blocks to i8*
+
+ ; uint32_t k1 = 0;
+ %k1 = 0
+
+ ; switch(len & 3)
+ %switch_val = and i32 %len, 3
+ ; case 3:
+ %case = icmp eq i32 %switch_val, 3
+ br i1 %case, label %Case3, label %NotCase3
+ Case3:
+ ; k1 ^= tail[2] << 16;
+ %z1 = call i32 @getbyte32(i8* %tail, i32 2)
+ %z1 = shl i32 %z1, 16
+ %k1 = xor i32 %k1, %z1
+ ; case 2:
+ br label %Case2
+ NotCase3:
+ %case = icmp eq i32 %switch_val, 2
+ br i1 %case, label %Case2, label %NotCase2
+ Case2:
+ ; k1 ^= tail[1] << 8;
+ %z1 = call i32 @getbyte32(i8* %tail, i32 1)
+ %z1 = shl i32 %z1, 8
+ %k1 = xor i32 %k1, %z1
+ ; case 1:
+ br label %Case1
+ NotCase2:
+ %case = icmp eq i32 %switch_val, 1
+ br i1 %case, label %Case1, label %NotCase1
+ Case1:
+ ; k1 ^= tail[0];
+ %z1 = call i32 @getbyte32(i8* %tail, i32 0)
+ %k1 = xor i32 %k1, %z1
+ ; k1 *= c1;
+ %k1 = mul i32 %k1, %c1
+ ; k1 = ROTL32(k1,16);
+ %k1 = call i32 @rotl32(i32 %k1, i8 16)
+ ; k1 *= c2;
+ %k1 = mul i32 %k1, %c2
+ ; h1 ^= k1;
+ %h1 = xor i32 %h1, %k1
+
+ ; switch ends
+ NotCase1:
+
+ ; // finalization
+ ; h1 ^= len;
+ %h1 = xor %h1, %len
+ ; h1 = fmix(h1);
+ %h1 = call i32 fmix32(i32 %h1)
+ ; *(uint32_t*)out = h1;
+ ret i32 %h1
+}
Please sign in to comment.
Something went wrong with that request. Please try again.