diff --git a/libretro-common/utils/Makefile b/libretro-common/utils/Makefile
new file mode 100644
index 0000000000..bb24667712
--- /dev/null
+++ b/libretro-common/utils/Makefile
@@ -0,0 +1,92 @@
+compiler    := gcc
+extra_flags :=
+use_neon    := 0
+release	   := release
+DYLIB	      := 
+
+ifeq ($(platform),)
+platform = unix
+ifeq ($(shell uname -a),)
+   platform = win
+else ifneq ($(findstring MINGW,$(shell uname -a)),)
+   platform = win
+else ifneq ($(findstring Darwin,$(shell uname -a)),)
+   platform = osx
+   arch = intel
+ifeq ($(shell uname -p),powerpc)
+   arch = ppc
+endif
+else ifneq ($(findstring win,$(shell uname -a)),)
+   platform = win
+endif
+endif
+
+ifeq ($(platform),gcc)
+extra_rules_gcc := $(shell $(compiler) -dumpmachine)
+endif
+
+ifneq (,$(findstring armv7,$(extra_rules_gcc)))
+extra_flags += -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon
+use_neon := 1
+endif
+
+ifneq (,$(findstring hardfloat,$(extra_rules_gcc)))
+extra_flags += -mfloat-abi=hard
+endif
+
+ifeq (release,$(build))
+extra_flags += -O2
+endif
+
+ifeq (debug,$(build))
+extra_flags += -O0 -g
+endif
+
+ldflags := -shared -Wl,--version-script=link.T
+
+ifeq ($(platform), unix)
+DYLIB =
+else ifeq ($(platform), osx)
+compiler := $(CC)
+DYLIB = 
+ldflags := -dynamiclib
+else
+extra_flags += -static-libgcc -static-libstdc++
+DYLIB = exe
+endif
+
+CC      := $(compiler)
+CXX     := $(subst CC,++,$(compiler))
+flags   := -fPIC $(extra_flags) -I../../libretro-common/include
+asflags := -fPIC  $(extra_flags)
+objects :=
+LDFLAGS := -lz
+flags   += -std=c99
+
+
+ifeq (1,$(use_neon))
+ASMFLAGS := -INEON/asm
+asflags += -mfpu=neon
+endif
+           
+objects += crc32$(DYLIB) djb2$(DYLIB) md5$(DYLIB) sha1$(DYLIB)
+
+all: build;
+
+%.o: %.S
+	$(CC) -c -o $@ $(asflags) $(LDFLAGS)  $(ASMFLAGS)  $<
+
+%.o: %.c
+	$(CC) -c -o $@ $(flags) $<
+
+%.$(DYLIB): %.o
+	$(CC) -o $@ $(ldflags) $(flags) $^
+
+build: $(objects)
+
+clean:
+	rm -f *.o
+	rm -f *.$(DYLIB)
+
+strip:
+	strip -s *.$(DYLIB)
diff --git a/libretro-common/utils/md5.c b/libretro-common/utils/md5.c
index a69d02d72b..74131dd93d 100644
--- a/libretro-common/utils/md5.c
+++ b/libretro-common/utils/md5.c
@@ -49,10 +49,6 @@ typedef struct
    unsigned char digest[16];     /* actual digest after MD5Final call */
 } MD5_CTX;
 
-void MD5Init(void);
-void MD5Update(void);
-void MD5Final(void);
-
 /*
  **********************************************************************
  ** End of md5.h                                                     **
@@ -95,9 +91,6 @@ void MD5Final(void);
 /* -- include the following line if the md5.h header file is separate -- */
 /* #include "md5.h" */
 
-/* forward declaration */
-static void Transform(void);
-
 static unsigned char PADDING[64] = {
   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -153,79 +146,6 @@ void MD5Init(MD5_CTX *mdContext)
    mdContext->buf[3] = (UINT4)0x10325476;
 }
 
-void MD5Update (MD5_CTX *mdContext,
-      unsigned char *inBuf, unsigned int inLen)
-{
-   UINT4 in[16];
-   int mdi;
-   unsigned int i, ii;
-
-   /* compute number of bytes mod 64 */
-   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-   /* update number of bits */
-   if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
-      mdContext->i[1]++;
-   mdContext->i[0] += ((UINT4)inLen << 3);
-   mdContext->i[1] += ((UINT4)inLen >> 29);
-
-   while (inLen--)
-   {
-      /* add new character to buffer, increment mdi */
-      mdContext->in[mdi++] = *inBuf++;
-
-      /* transform if necessary */
-      if (mdi == 0x40)
-      {
-         for (i = 0, ii = 0; i < 16; i++, ii += 4)
-            in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-               (((UINT4)mdContext->in[ii+2]) << 16) |
-               (((UINT4)mdContext->in[ii+1]) << 8) |
-               ((UINT4)mdContext->in[ii]);
-         Transform (mdContext->buf, in);
-         mdi = 0;
-      }
-   }
-}
-
-void MD5Final (MD5_CTX *mdContext)
-{
-   UINT4 in[16];
-   int mdi;
-   unsigned int i, ii;
-   unsigned int padLen;
-
-   /* save number of bits */
-   in[14] = mdContext->i[0];
-   in[15] = mdContext->i[1];
-
-   /* compute number of bytes mod 64 */
-   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-   /* pad out to 56 mod 64 */
-   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
-   MD5Update (mdContext, PADDING, padLen);
-
-   /* append length in bits and transform */
-   for (i = 0, ii = 0; i < 14; i++, ii += 4)
-      in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-         (((UINT4)mdContext->in[ii+2]) << 16) |
-         (((UINT4)mdContext->in[ii+1]) << 8) |
-         ((UINT4)mdContext->in[ii]);
-   Transform (mdContext->buf, in);
-
-   /* store buffer in digest */
-   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
-      mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
-      mdContext->digest[ii+1] =
-         (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
-      mdContext->digest[ii+2] =
-         (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
-      mdContext->digest[ii+3] =
-         (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
-   }
-}
-
 /* Basic MD5 step. Transform buf based on in.
  */
 static void Transform (UINT4 *buf, UINT4 *in)
@@ -326,6 +246,80 @@ static void Transform (UINT4 *buf, UINT4 *in)
    buf[3] += d;
 }
 
+void MD5Update (MD5_CTX *mdContext,
+      unsigned char *inBuf, unsigned int inLen)
+{
+   UINT4 in[16];
+   int mdi;
+   unsigned int i, ii;
+
+   /* compute number of bytes mod 64 */
+   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+   /* update number of bits */
+   if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
+      mdContext->i[1]++;
+   mdContext->i[0] += ((UINT4)inLen << 3);
+   mdContext->i[1] += ((UINT4)inLen >> 29);
+
+   while (inLen--)
+   {
+      /* add new character to buffer, increment mdi */
+      mdContext->in[mdi++] = *inBuf++;
+
+      /* transform if necessary */
+      if (mdi == 0x40)
+      {
+         for (i = 0, ii = 0; i < 16; i++, ii += 4)
+            in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+               (((UINT4)mdContext->in[ii+2]) << 16) |
+               (((UINT4)mdContext->in[ii+1]) << 8) |
+               ((UINT4)mdContext->in[ii]);
+         Transform (mdContext->buf, in);
+         mdi = 0;
+      }
+   }
+}
+
+void MD5Final (MD5_CTX *mdContext)
+{
+   UINT4 in[16];
+   int mdi;
+   unsigned int i, ii;
+   unsigned int padLen;
+
+   /* save number of bits */
+   in[14] = mdContext->i[0];
+   in[15] = mdContext->i[1];
+
+   /* compute number of bytes mod 64 */
+   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+   /* pad out to 56 mod 64 */
+   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+   MD5Update (mdContext, PADDING, padLen);
+
+   /* append length in bits and transform */
+   for (i = 0, ii = 0; i < 14; i++, ii += 4)
+      in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+         (((UINT4)mdContext->in[ii+2]) << 16) |
+         (((UINT4)mdContext->in[ii+1]) << 8) |
+         ((UINT4)mdContext->in[ii]);
+   Transform (mdContext->buf, in);
+
+   /* store buffer in digest */
+   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+      mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
+      mdContext->digest[ii+1] =
+         (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
+      mdContext->digest[ii+2] =
+         (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+      mdContext->digest[ii+3] =
+         (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+   }
+}
+
+
 /*
  **********************************************************************
  ** End of md5.c                                                     **