diff --git a/Makefile.target b/Makefile.target
index eb77210..db7f395 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -141,7 +141,11 @@ endif
 
 ifeq ($(ARCH),x86_64)
   ifneq ($(CONFIG_SOLARIS),yes)
-    BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
+    ifneq ($(CONFIG_DARWIN),yes)
+      BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
+    else
+      OP_CFLAGS+=-fomit-frame-pointer
+    endif
   endif
 endif
 
@@ -558,7 +562,9 @@ endif
 ifeq ($(ARCH),x86_64)
   VL_LDFLAGS+=-m64
   ifneq ($(CONFIG_SOLARIS),yes)
+   ifneq ($(CONFIG_DARWIN),yes)
     VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld
+   endif
   endif
 endif
 
diff --git a/configure b/configure
index 28b6770..08f1720 100755
--- a/configure
+++ b/configure
@@ -148,9 +148,19 @@ Darwin)
 bsd="yes"
 darwin="yes"
 darwin_user="yes"
-cocoa="yes"
-coreaudio="yes"
-OS_CFLAGS="-mdynamic-no-pic"
+# on Leopard most of the kernel is 32-bit, so we have to ask it if we can run 64-bit userspace code
+is_x86_64=`sysctl -n hw.optional.x86_64`
+if [ "$is_x86_64" = "1" ]; then
+    cpu=x86_64
+fi
+if [ "$cpu" = "x86_64" ] ; then
+    OS_CFLAGS="-arch x86_64"
+    LDFLAGS="-pagezero_size 0x1000000 -arch x86_64"
+#    CFLAGS="$CFLAGS -fomit-frame-pointer"
+else # no cocoa ported to 64 bit yet
+    cocoa="yes"
+    coreaudio="yes"
+fi
 ;;
 SunOS)
     solaris="yes"
@@ -244,7 +254,7 @@ for opt do
   ;;
   --extra-cflags=*) CFLAGS="$optarg"
   ;;
-  --extra-ldflags=*) LDFLAGS="$optarg"
+  --extra-ldflags=*) LDFLAGS="$LDFLAGS $optarg"
   ;;
   --cpu=*) cpu="$optarg"
   ;;
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 6f69bee..03fe208 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -35,8 +35,8 @@
 typedef unsigned char uint8_t;
 typedef unsigned short uint16_t;
 typedef unsigned int uint32_t;
-// Linux/Sparc64 defines uint64_t
-#if !(defined (__sparc_v9__) && defined(__linux__))
+// Linux/Sparc64 and Darwin/x86_64 defines uint64_t
+#if !(defined (__sparc_v9__) && defined(__linux__)) && !(defined(__APPLE__) && defined(__x86_64__))
 /* XXX may be done for all 64 bits targets ? */
 #if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
 typedef unsigned long uint64_t;
@@ -53,8 +53,8 @@ typedef signed char int8_t;
 #endif
 typedef signed short int16_t;
 typedef signed int int32_t;
-// Linux/Sparc64 defines int64_t
-#if !(defined (__sparc_v9__) && defined(__linux__))
+// Linux/Sparc64 and Darwin/x86_64 defines int64_t
+#if !(defined (__sparc_v9__) && defined(__linux__)) && !(defined(__APPLE__) && defined(__x86_64__))
 #if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
 typedef signed long int64_t;
 #else
diff --git a/dyngen.c b/dyngen.c
index d301c71..933652f 100644
--- a/dyngen.c
+++ b/dyngen.c
@@ -196,16 +196,36 @@ typedef struct coff_rel {
 #include <mach-o/nlist.h>
 #include <mach-o/reloc.h>
 #include <mach-o/ppc/reloc.h>
+#include <mach-o/x86_64/reloc.h>
 
+#if defined(HOST_PPC)
+# define mach_check_cputype(x) ((x) == CPU_TYPE_POWERPC)
 # define check_mach_header(x) (x.magic == MH_MAGIC)
+# define SEGMENT_COMMAND segment_command
+# define MACH_HEADER mach_header
+# define SECTION section
+# define NLIST nlist
+#elif defined(HOST_X86_64)
+# define mach_check_cputype(x) ((x) == CPU_TYPE_X86_64)
+# define check_mach_header(x) (x.magic == MH_MAGIC_64)
+# define SEGMENT_COMMAND segment_command_64
+# define MACH_HEADER mach_header_64
+# define SECTION section_64
+# define NLIST nlist_64
+#endif
+
 typedef int32_t host_long;
 typedef uint32_t host_ulong;
 
 struct nlist_extended
 {
    union {
+#ifdef HOST_X86_64
+   unsigned int n_strx;
+#else
    char *n_name;
    long  n_strx;
+#endif
    } n_un;
    unsigned char n_type;
    unsigned char n_sect;
@@ -833,16 +853,16 @@ int load_object(const char *filename)
 #ifdef CONFIG_FORMAT_MACH
 
 /* File Header */
-struct mach_header 	mach_hdr;
+struct MACH_HEADER mach_hdr;
 
 /* commands */
-struct segment_command 	*segment = 0;
+struct SEGMENT_COMMAND *segment = 0;
 struct dysymtab_command *dysymtabcmd = 0;
 struct symtab_command 	*symtabcmd = 0;
 
 /* section */
-struct section 	*section_hdr;
-struct section *text_sec_hdr;
+struct SECTION *section_hdr;
+struct SECTION *text_sec_hdr;
 uint8_t 	**sdata;
 
 /* relocs */
@@ -850,7 +870,7 @@ struct relocation_info *relocs;
 
 /* symbols */
 EXE_SYM			*symtab;
-struct nlist 	*symtab_std;
+struct NLIST *symtab_std;
 char			*strtab;
 
 /* indirect symbols */
@@ -880,11 +900,11 @@ static char *get_sym_name(EXE_SYM *sym)
 }
 
 /* find a section index given its segname, sectname */
-static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
+static int find_mach_sec_index(struct SECTION *section_hdr, int shnum, const char *segname,
                                   const char *sectname)
 {
     int i;
-    struct section *sec = section_hdr;
+    struct SECTION *sec = section_hdr;
 
     for(i = 0; i < shnum; i++, sec++) {
         if (!sec->segname || !sec->sectname)
@@ -896,7 +916,7 @@ static int find_mach_sec_index(struct section *section_hdr, int shnum, const cha
 }
 
 /* find a section header given its segname, sectname */
-struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
+struct SECTION *find_mach_sec_hdr(struct SECTION *section_hdr, int shnum, const char *segname,
                                   const char *sectname)
 {
     int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);
@@ -949,7 +969,7 @@ static const char * find_sym_with_value_and_sec_number( int value, int sectnum,
  *  Find symbol name given a (virtual) address, and a section which is of type
  *  S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS
  */
-static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)
+static const char * find_reloc_name_in_sec_ptr(int address, struct SECTION * sec_hdr)
 {
     unsigned int tocindex, symindex, size;
     const char *name = 0;
@@ -1000,10 +1020,20 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
 	int other_half=0;
 
 	/* init the slide value */
+#ifdef HOST_X86_64 /* no scattered on x86_64 */
+switch(rel->r_length)
+        {
+            case 0: *sslide = *(uint8_t  *)(text + rel->r_address); break;
+            case 1: *sslide = *(uint16_t *)(text + rel->r_address); break;
+            case 2: *sslide = *(uint32_t *)(text + rel->r_address); break;
+            case 3: *sslide = *(uint64_t *)(text + rel->r_address); break;
+        }
+#else
 	*sslide = 0;
 
 	if(R_SCATTERED & rel->r_address)
 		return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
+#endif
 
 	if(rel->r_extern)
 	{
@@ -1079,7 +1109,7 @@ int load_object(const char *filename)
     struct load_command lc;
     unsigned int i, j;
 	EXE_SYM *sym;
-	struct nlist *syment;
+	struct NLIST *syment;
 
 	fd = open(filename, O_RDONLY);
     if (fd < 0)
@@ -1094,7 +1124,7 @@ int load_object(const char *filename)
         error("bad Mach header");
     }
 
-    if (mach_hdr.cputype != CPU_TYPE_POWERPC)
+    if (!mach_check_cputype(mach_hdr.cputype))
         error("Unsupported CPU");
 
     if (mach_hdr.filetype != MH_OBJECT)
@@ -1105,29 +1135,37 @@ int load_object(const char *filename)
     {
         if(read(fd, &lc, sizeof(struct load_command)) != sizeof(struct load_command))
             error("unable to read load_command");
-        if(lc.cmd == LC_SEGMENT)
-        {
+        switch(lc.cmd) {
+#ifdef HOST_X86_64
+          case LC_SEGMENT_64:
+#else
+          case LC_SEGMENT:
+#endif
             offset_to_segment = j;
             lseek(fd, offset_to_segment, SEEK_SET);
-            segment = malloc(sizeof(struct segment_command));
-            if(read(fd, segment, sizeof(struct segment_command)) != sizeof(struct segment_command))
+            segment = malloc(sizeof(struct SEGMENT_COMMAND));
+            if(read(fd, segment, sizeof(struct SEGMENT_COMMAND)) != sizeof(struct SEGMENT_COMMAND))
                 error("unable to read LC_SEGMENT");
-        }
-        if(lc.cmd == LC_DYSYMTAB)
-        {
+            break;
+
+          case LC_DYSYMTAB:
             offset_to_dysymtab = j;
             lseek(fd, offset_to_dysymtab, SEEK_SET);
             dysymtabcmd = malloc(sizeof(struct dysymtab_command));
             if(read(fd, dysymtabcmd, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command))
                 error("unable to read LC_DYSYMTAB");
-        }
-        if(lc.cmd == LC_SYMTAB)
-        {
+            break;
+
+         case LC_SYMTAB:
             offset_to_symtab = j;
             lseek(fd, offset_to_symtab, SEEK_SET);
             symtabcmd = malloc(sizeof(struct symtab_command));
             if(read(fd, symtabcmd, sizeof(struct symtab_command)) != sizeof(struct symtab_command))
                 error("unable to read LC_SYMTAB");
+            break;
+
+           default:
+             error("LC: unknown command: %#x", lc.cmd);
         }
         j+=lc.cmdsize;
 
@@ -1138,21 +1176,21 @@ int load_object(const char *filename)
         error("unable to find LC_SEGMENT");
 
     /* read section headers */
-    section_hdr = load_data(fd, offset_to_segment + sizeof(struct segment_command), segment->nsects * sizeof(struct section));
+    section_hdr = load_data(fd, offset_to_segment + sizeof(struct SEGMENT_COMMAND), segment->nsects * sizeof(struct SECTION));
 
     /* read all section data */
     sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
     memset(sdata, 0, sizeof(void *) * segment->nsects);
 
-	/* Load the data in section data */
-	for(i = 0; i < segment->nsects; i++) {
+    /* Load the data in section data */
+    for(i = 0; i < segment->nsects; i++) {
         sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
     }
 
     /* text section */
-	text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
-	i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
-	if (i == -1 || !text_sec_hdr)
+    text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
+    i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
+    if (i == -1 || !text_sec_hdr)
         error("could not find __TEXT,__text section");
     text = sdata[i];
 
@@ -1168,23 +1206,26 @@ int load_object(const char *filename)
         error("could not find __SYMTAB segment");
     nb_syms = symtabcmd->nsyms;
 
-    symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));
+    symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct NLIST));
     strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);
 
-	symtab = malloc(sizeof(EXE_SYM) * nb_syms);
+    symtab = malloc(sizeof(EXE_SYM) * nb_syms);
 
-	/* Now transform the symtab, to an extended version, with the sym size, and the C name */
-	for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
-        struct nlist *sym_follow, *sym_next = 0;
+    /* Now transform the symtab, to an extended version, with the sym size, and the C name */
+    for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
+        struct NLIST *sym_follow, *sym_next = 0;
         unsigned int j;
-		memset(sym, 0, sizeof(*sym));
+        char *ns;
+        memset(sym, 0, sizeof(*sym));
 
-		if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
+        if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
+            continue;
+        if ( ns = strchr((char*)(strtab + syment->n_un.n_strx), '.') ) /* no Exception handlers */
             continue;
 
-		memcpy(sym, syment, sizeof(*syment));
+        memcpy(sym, syment, sizeof(*syment));
 
-		/* Find the following symbol in order to get the current symbol size */
+        /* Find the following symbol in order to get the current symbol size */
         for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
             if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
                 continue;
@@ -1919,6 +1960,104 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
             }
 #elif defined(HOST_X86_64)
             {
+#ifdef CONFIG_FORMAT_MACH
+                struct relocation_info * rel;
+                char final_sym_name[256];
+                const char *sym_name;
+                const char *p;
+                int slide, sslide;
+                int i, bitsize;
+                char *bitlength;
+    
+                for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
+                    unsigned int offset, length, value = 0;
+                    unsigned int type, pcrel, isym = 0;
+                    unsigned int usesym = 0;
+                
+                    value = isym = rel->r_symbolnum;
+                    usesym = (rel->r_extern);
+                    offset = rel->r_address;
+                    length = rel->r_length;
+                    pcrel = rel->r_pcrel;
+                    type = rel->r_type;
+                
+                    slide = offset - start_offset;
+        
+                    if (!(offset >= start_offset && offset < start_offset + size)) 
+                        continue;  /* not in our range */
+
+                    sym_name = get_reloc_name(rel, &sslide);
+                    
+                    if (usesym && symtab[isym].n_type & N_STAB)
+                        continue; /* don't handle STAB (debug sym) */
+                    
+                    if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
+                        int n;
+                        n = strtol(p, NULL, 10);
+                        fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, slide);
+                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = 0l;\n", slide);
+                        continue; /* Nothing more to do */
+                    }
+                    
+                    if (!sym_name) {
+                        fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
+                                name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
+                        continue; /* dunno how to handle without final_sym_name */
+                    }
+
+                    get_reloc_expr(final_sym_name, sizeof(final_sym_name),
+                                   sym_name);
+
+                    if (length != 2)
+                        error("unsupported %d-bit relocation", 8 * (1 << length));
+
+                    switch(length) {
+                        case 0: // 8 bit
+                            bitlength = "8";
+                            bitsize = 1;
+                            break;
+                        case 1: // 16 bit
+                            bitlength = "16";
+                            bitsize = 2;
+                            break;
+                        case 2: // 32 bit
+                            bitlength = "32";
+                            bitsize = 4;
+                            break;
+                        case 3: // 64 bit
+                            bitlength = "64";
+                            bitsize = 8;
+                            break;
+                    }
+
+                    if(pcrel || strstart(sym_name,"__op_gen_label",&p)) {
+                        switch (type) {
+                             case X86_64_RELOC_UNSIGNED:
+                             case X86_64_RELOC_BRANCH:
+                             case X86_64_RELOC_SIGNED:
+                             case X86_64_RELOC_GOT_LOAD:
+                                 fprintf(outfile, "    *(uint%s_t *)(gen_code_ptr + %d) = (int%s_t)((long)%s - (long)(gen_code_ptr + %d + %d)) + %d;\n", 
+                                         bitlength, slide, bitlength, final_sym_name, slide, bitsize, sslide);
+                                 break;
+                             default:
+                                 printf("unsupported x86_64 relocation (%d) in %s\n", type, sym_name);
+                         }
+                     } else {
+                         switch (type) {
+                             case X86_64_RELOC_UNSIGNED:
+                                 fprintf(outfile, "    *(uint%s_t *)(gen_code_ptr + %d) = (uint%s_t)%s + %d;\n", 
+                                         bitlength, slide, bitlength, final_sym_name, sslide);
+                                 break;
+                             case X86_64_RELOC_SIGNED:
+                                 fprintf(outfile, "    *(uint%s_t *)(gen_code_ptr + %d) = (int%s_t)%s + %d;\n", 
+                                         bitlength, slide, bitlength, final_sym_name, sslide);
+                                 break;
+                             default:
+                                 printf("unsupported x86_64 relocation (%d) in %s\n", type, sym_name);
+                         }
+                    }
+                }
+#else
                 char relname[256];
                 int type;
                 int addend;
@@ -1949,6 +2088,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                     }
                 }
                 }
+#endif
             }
 #elif defined(HOST_PPC)
             {
diff --git a/exec-all.h b/exec-all.h
index 285da99..ff7d33c 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -142,6 +142,9 @@ static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
 #if defined(__i386__) && !defined(_WIN32)
 #define USE_DIRECT_JUMP
 #endif
+#if defined(__x86_64__) && defined(__APPLE__)
+#define USE_DIRECT_JUMP
+#endif
 
 typedef struct TranslationBlock {
     target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
@@ -228,7 +231,7 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr
     asm volatile ("sync" : : : "memory");
     asm volatile ("isync" : : : "memory");
 }
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__x86_64__)
 static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
 {
     /* patch the branch destination */
@@ -320,6 +323,18 @@ do {\
 		  "1:\n");\
 } while (0)
 
+#elif defined(__x86_64__) && defined(USE_DIRECT_JUMP)
+
+#define GOTO_TB(opname, tbparam, n)\
+do {\
+    asm volatile (ASM_DATA_SECTION\
+		  ASM_OP_LABEL_NAME(n, opname) ":\n"\
+		  ".quad 1f\n"\
+		  ASM_PREVIOUS_SECTION \
+                  "jmp " ASM_NAME(__op_jmp) #n "\n"\
+		  "1:\n");\
+} while (0)
+
 #else
 
 /* jump to next block operations (more portable code, does not need
@@ -491,6 +506,12 @@ static inline int spin_trylock(spinlock_t *lock)
     return !testandset(lock);
 }
 #else
+/* On Darwin the compiler tries to be smart about spinlocking functions and replaces them itself */
+#ifdef __APPLE__
+#define spin_lock(x)
+#define spin_unlock(x)
+#define spin_trylock(x)
+#else
 static inline void spin_lock(spinlock_t *lock)
 {
 }
@@ -504,6 +525,7 @@ static inline int spin_trylock(spinlock_t *lock)
     return 1;
 }
 #endif
+#endif
 
 extern spinlock_t tb_lock;
 
diff --git a/exec.c b/exec.c
index 046e967..1859f01 100644
--- a/exec.c
+++ b/exec.c
@@ -481,7 +481,9 @@ static inline void tb_jmp_remove(TranslationBlock *tb, int n)
    another TB */
 static inline void tb_reset_jump(TranslationBlock *tb, int n)
 {
+#if !(defined(__APPLE__) && defined(__x86_64__))
     tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
+#endif
 }
 
 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 5f95d06..10ad262 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -50,11 +50,17 @@ these four paragraphs for those parts of this code that are retained.
 typedef uint8_t flag;
 typedef uint8_t uint8;
 typedef int8_t int8;
+#ifndef _UINT16
 typedef int uint16;
+#endif
 typedef int int16;
+#ifndef _UINT32
 typedef unsigned int uint32;
+#endif
 typedef signed int int32;
+#ifndef _UINT64
 typedef uint64_t uint64;
+#endif
 typedef int64_t int64;
 
 /*----------------------------------------------------------------------------
diff --git a/host-utils.h b/host-utils.h
index dafd032..de1e8a9 100644
--- a/host-utils.h
+++ b/host-utils.h
@@ -23,6 +23,8 @@
  * THE SOFTWARE.
  */
 
+#include "osdep.h"
+
 #if defined(__x86_64__)
 #define __HAVE_FAST_MULU64__
 static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
diff --git a/osdep.h b/osdep.h
index 0acffa4..5755348 100644
--- a/osdep.h
+++ b/osdep.h
@@ -33,7 +33,9 @@
 #define always_inline __attribute__ (( always_inline )) __inline__
 #endif
 #endif
+#if !((__GNUC__ < 3) || defined(__APPLE__))
 #define inline always_inline
+#endif
 
 #ifdef __i386__
 #define REGPARM(n) __attribute((regparm(n)))
