Index: qemu-0.9.1-aix/audio/audio.c
===================================================================
--- qemu-0.9.1-aix.orig/audio/audio.c	2008-04-10 13:17:42.-467989984 +0200
+++ qemu-0.9.1-aix/audio/audio.c	2008-04-10 13:17:44.101108488 +0200
@@ -74,7 +74,7 @@
     struct fixed_settings fixed_out;
     struct fixed_settings fixed_in;
     union {
-        int hz;
+        int hertz;
         int64_t ticks;
     } period;
     int plive;
@@ -1533,7 +1533,7 @@
      "Number of voices for ADC", NULL, 0},
 
     /* Misc */
-    {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hz,
+    {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hertz,
      "Timer period in HZ (0 - use lowest possible)", NULL, 0},
 
     {"PLIVE", AUD_OPT_BOOL, &conf.plive,
@@ -1794,16 +1794,16 @@
     if (done) {
         VMChangeStateEntry *e;
 
-        if (conf.period.hz <= 0) {
-            if (conf.period.hz < 0) {
+        if (conf.period.hertz <= 0) {
+            if (conf.period.hertz < 0) {
                 dolog ("warning: Timer period is negative - %d "
                        "treating as zero\n",
-                       conf.period.hz);
+                       conf.period.hertz);
             }
             conf.period.ticks = 1;
         }
         else {
-            conf.period.ticks = ticks_per_sec / conf.period.hz;
+            conf.period.ticks = ticks_per_sec / conf.period.hertz;
         }
 
         e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
Index: qemu-0.9.1-aix/configure
===================================================================
--- qemu-0.9.1-aix.orig/configure	2008-04-10 13:17:42.-921249488 +0200
+++ qemu-0.9.1-aix/configure	2008-04-10 13:17:44.1510808896 +0200
@@ -187,6 +187,12 @@
         oss=yes
     fi
 ;;
+AIX)
+    cpu="powerpc"
+    make="gmake"
+    check_gcc="no"
+    aix="yes"
+;;
 *)
 oss="yes"
 linux="yes"
@@ -868,6 +874,10 @@
   echo "CONFIG_DARWIN=yes" >> $config_mak
   echo "#define CONFIG_DARWIN 1" >> $config_h
 fi
+if test "$aix" = "yes" ; then
+  echo "CONFIG_AIX=yes" >> $config_mak
+  echo "#define CONFIG_AIX 1" >> $config_h
+fi
 if test "$solaris" = "yes" ; then
   echo "CONFIG_SOLARIS=yes" >> $config_mak
   echo "#define HOST_SOLARIS $solarisrev" >> $config_h
Index: qemu-0.9.1-aix/exec-all.h
===================================================================
--- qemu-0.9.1-aix.orig/exec-all.h	2008-04-10 13:16:45.-2022321712 +0200
+++ qemu-0.9.1-aix/exec-all.h	2008-04-10 13:17:44.1445694824 +0200
@@ -286,6 +286,9 @@
 #elif defined(__APPLE__)
 #define ASM_DATA_SECTION ".data\n"
 #define ASM_PREVIOUS_SECTION ".text\n"
+#elif defined(_AIX)
+#define ASM_DATA_SECTION ".csect .data[RW],3\n"
+#define ASM_PREVIOUS_SECTION ".csect .text[PR]\n"
 #else
 #define ASM_DATA_SECTION ".section \".data\"\n"
 #define ASM_PREVIOUS_SECTION ".previous\n"
@@ -295,7 +298,14 @@
     ASM_NAME(__op_label) #n "." ASM_NAME(opname)
 
 #if defined(__powerpc__)
-
+#if defined(_AIX)
+#define GOTO_TB(opname, tbparam, n)\
+do {\
+    asm volatile ("\tb " ASM_NAME(.__op_jmp) #n "\n"\
+		  "\t.globl ." ASM_OP_LABEL_NAME(n, opname) "\n"\
+		  "." ASM_OP_LABEL_NAME(n, opname) ":\n");\
+} while (0)
+#else
 /* we patch the jump instruction directly */
 #define GOTO_TB(opname, tbparam, n)\
 do {\
@@ -306,6 +316,7 @@
                   "b " ASM_NAME(__op_jmp) #n "\n"\
 		  "1:\n");\
 } while (0)
+#endif
 
 #elif defined(__i386__) && defined(USE_DIRECT_JUMP)
 
@@ -345,12 +356,11 @@
 {
     int ret;
     __asm__ __volatile__ (
-                          "0:    lwarx %0,0,%1\n"
+                          "	 lwarx %0,0,%1\n"
                           "      xor. %0,%3,%0\n"
-                          "      bne 1f\n"
+                          "      bne $ + 12\n"
                           "      stwcx. %2,0,%1\n"
-                          "      bne- 0b\n"
-                          "1:    "
+                          "      bne- $ - 16\n"
                           : "=&r" (ret)
                           : "r" (p), "r" (1), "r" (0)
                           : "cr0", "memory");
Index: qemu-0.9.1-aix/fpu/softfloat.h
===================================================================
--- qemu-0.9.1-aix.orig/fpu/softfloat.h	2008-04-10 13:16:45.-2087285784 +0200
+++ qemu-0.9.1-aix/fpu/softfloat.h	2008-04-10 13:17:44.-29041656 +0200
@@ -51,7 +51,7 @@
 typedef uint8_t uint8;
 typedef int8_t int8;
 typedef int uint16;
-typedef int int16;
+typedef int16_t int16;
 typedef unsigned int uint32;
 typedef signed int int32;
 typedef uint64_t uint64;
Index: qemu-0.9.1-aix/vl.c
===================================================================
--- qemu-0.9.1-aix.orig/vl.c	2008-04-10 13:17:43.-532585056 +0200
+++ qemu-0.9.1-aix/vl.c	2008-04-10 13:17:44.1316186680 +0200
@@ -67,7 +67,7 @@
 #elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
 #include <freebsd/stdlib.h>
 #else
-#ifndef __sun__
+#if !defined(__sun__) && !defined(_AIX)
 #include <linux/if.h>
 #include <linux/if_tun.h>
 #include <pty.h>
@@ -83,9 +83,11 @@
 #include <linux/parport.h>
 #else
 #include <sys/stat.h>
+#if !defined(_AIX)
 #include <sys/ethernet.h>
 #include <sys/sockio.h>
 #include <netinet/arp.h>
+#endif
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
@@ -3886,7 +3888,7 @@
 
 #endif /* CONFIG_SLIRP */
 
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(_AIX)
 
 typedef struct TAPState {
     VLANClientState *vc;
@@ -4770,7 +4772,7 @@
         ret = net_slirp_init(vlan);
     } else
 #endif
-#ifdef _WIN32
+#if defined(_WIN32)
     if (!strcmp(device, "tap")) {
         char ifname[64];
         if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
@@ -4780,6 +4782,7 @@
         vlan->nb_host_devs++;
         ret = tap_win32_init(vlan, ifname);
     } else
+#elif defined(_AIX)
 #else
     if (!strcmp(device, "tap")) {
         char ifname[64];
@@ -9056,7 +9059,7 @@
     main_loop();
     quit_timers();
 
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(_AIX)
     /* close network clients */
     for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
         VLANClientState *vc;
Index: qemu-0.9.1-aix/dyngen.c
===================================================================
--- qemu-0.9.1-aix.orig/dyngen.c	2008-04-10 13:16:46.-14318480 +0200
+++ qemu-0.9.1-aix/dyngen.c	2008-04-10 13:17:44.1253651608 +0200
@@ -38,6 +38,8 @@
 #define CONFIG_FORMAT_COFF
 #elif defined(CONFIG_DARWIN)
 #define CONFIG_FORMAT_MACH
+#elif defined(CONFIG_AIX)
+#define CONFIG_FORMAT_XCOFF
 #else
 #define CONFIG_FORMAT_ELF
 #endif
@@ -219,6 +221,36 @@
 
 #endif /* CONFIG_FORMAT_MACH */
 
+#ifdef CONFIG_FORMAT_XCOFF
+
+typedef int32_t host_long;
+typedef uint32_t host_ulong;
+
+#include <nlist.h>
+#include <xcoff.h>
+
+#define FILENAMELEN 256
+
+typedef struct xcoff_sym {
+    struct syment *st_syment;
+    char st_name[FILENAMELEN];
+    uint32_t st_value;
+    int  st_size;
+    uint8_t st_type;
+    uint8_t st_shndx;
+} coff_Sym;
+
+typedef struct xcoff_rel {
+    struct reloc *xcoff_reloc;
+    int  xcoff_offset;
+    int  xcoff_size;
+    int  xcoff_type;
+} xcoff_Rel;
+
+#define EXE_RELOC struct xcoff_rel
+#define EXE_SYM struct xcoff_sym
+#endif /* CONFIG_FORMAT_XCOFF */
+
 #include "bswap.h"
 
 enum {
@@ -228,7 +260,12 @@
 };
 
 /* all dynamically generated functions begin with this code */
+
+#if defined(CONFIG_FORMAT_XCOFF)
+#define OP_PREFIX ".op_"
+#else
 #define OP_PREFIX "op_"
+#endif
 
 int do_swap;
 
@@ -748,6 +785,7 @@
     if (!data_sec)
         error("could not find .data section");
     coff_data_shndx = data_sec - shdr;
+    data = sdata[coff_data_shndx];
 
     coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ);
     for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) {
@@ -1212,10 +1250,302 @@
 
 #endif /* CONFIG_FORMAT_MACH */
 
-void get_reloc_expr(char *name, int name_size, const char *sym_name)
+#ifdef CONFIG_FORMAT_XCOFF
+
+/* XCOFF file info */
+
+struct scnhdr *shdr;
+uint8_t **sdata;
+struct filehdr fhdr;
+struct syment *xcoff_symtab;
+char *strtab;
+int xcoff_text_shndx, xcoff_data_shndx;
+EXE_RELOC *data_relocs;
+int data_nb_relocs;
+
+int data_shndx;
+
+#define STRTAB_SIZE 4
+
+#define T_FUNCTION  0x20
+#define C_EXTERNAL  2
+
+/* Utility functions */
+
+void sym_ent_name(struct syment *ext_sym, EXE_SYM *sym)
+{
+    char *q;
+    int c, i, len;
+
+   if (ext_sym->n_zeroes == 0) {
+      pstrcpy(sym->st_name, sizeof(sym->st_name), strtab + ext_sym->n_offset);
+   } else {
+        q = sym->st_name;
+        for(i = 0; i < SYMNMLEN; i++) {
+            c = ext_sym->n_name[i];
+            if (c == '\0')
+                break;
+            *q++ = c;
+        }
+        *q = '\0';
+    }
+
+    /* now convert the name to a C name (suppress the leading '_') */
+    if (sym->st_name[0] == '_') {
+        len = strlen(sym->st_name);
+        memmove(sym->st_name, sym->st_name + 1, len - 1);
+        sym->st_name[len - 1] = '\0';
+    }
+}
+
+char *name_for_dotdata(struct xcoff_rel *rel)
+{
+	int i;
+	struct xcoff_sym *sym;
+	uint32_t text_data;
+
+	text_data = (uint32_t)(text + rel->xcoff_offset);
+
+	for (i = 0, sym = symtab; i < nb_syms; i++, sym++) {
+		if (sym->st_syment->n_scnum == data_shndx &&
+                    text_data >= sym->st_value &&
+                    text_data < sym->st_value + sym->st_size) {
+
+                    return sym->st_name;
+		}
+	}
+	return NULL;
+}
+
+static char *get_sym_name(EXE_SYM *sym)
+{
+    return sym->st_name;
+}
+
+static char *get_rel_sym_name(EXE_RELOC *rel)
+{
+    char *name;
+    name = get_sym_name(symtab + rel->xcoff_reloc->r_symndx);
+    if (name[0] == 0)
+        return NULL;
+    if (!strcmp(name, ".data"))
+        name = name_for_dotdata(rel);
+    return name;
+}
+
+static host_ulong get_rel_offset(EXE_RELOC *rel)
+{
+    return rel->xcoff_offset;
+}
+
+
+/* Used by dyngen common code */
+
+struct scnhdr *find_xcoff_section(struct scnhdr *shdr,
+				  int shnum, const char *name)
 {
+    int i;
+    const char *shname;
+    struct scnhdr *sec;
+
+    for(i = 0; i < shnum; i++) {
+        sec = &shdr[i];
+        if (!sec->s_name)
+            continue;
+        shname = sec->s_name;
+        if (!strcmp(shname, name))
+            return sec;
+    }
+    return NULL;
+}
+
+/* load a xcoff object file */
+int load_object(const char *filename)
+{
+    int fd;
+    struct scnhdr *sec, *text_sec, *data_sec;
+    int i;
+    struct syment *ext_sym;
+    struct reloc *xcoff_relocs;
+    struct reloc *ext_rel;
+    uint32_t *n_strtab;
+    EXE_SYM *sym;
+    EXE_RELOC *rel;
     const char *p;
+    int aux_size, j;
+
+    fd = open(filename, O_RDONLY);
+    if (fd < 0)
+        error("can't open file '%s'", filename);
+
+    /* Read XCOFF header.  */
+    if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr))
+        error("unable to read file header");
+
+    /* Check XCOFF identification.  */
+    if (fhdr.f_magic != U802TOCMAGIC) {
+        error("bad XCOFF header");
+    }
+    do_swap = 0;
+
+    /* read section headers */
+
+    shdr = load_data(fd, sizeof(struct filehdr) + fhdr.f_opthdr,
+                     fhdr.f_nscns * sizeof(struct scnhdr));
+
+    /* read all section data */
 
+    sdata = malloc(sizeof(void *) * fhdr.f_nscns);
+    memset(sdata, 0, sizeof(void *) * fhdr.f_nscns);
+
+    for(i = 0;i < fhdr.f_nscns; i++) {
+        sec = &shdr[i];
+        if (!strstart(sec->s_name,  ".bss", &p))
+            sdata[i] = load_data(fd, sec->s_scnptr, sec->s_size);
+    }
+
+
+    /* text section */
+
+    text_sec = find_xcoff_section(shdr, fhdr.f_nscns, ".text");
+    if (!text_sec)
+        error("could not find .text section");
+    xcoff_text_shndx = text_sec - shdr;
+    text = sdata[xcoff_text_shndx];
+
+    /* data section */
+
+    data_sec = find_xcoff_section(shdr, fhdr.f_nscns, ".data");
+    if (!data_sec)
+        error("could not find .data section");
+    xcoff_data_shndx = data_sec - shdr;
+
+    xcoff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms * SYMESZ);
+
+    n_strtab = load_data(fd, fhdr.f_symptr + fhdr.f_nsyms * SYMESZ,
+			 STRTAB_SIZE);
+    strtab = load_data(fd, fhdr.f_symptr + fhdr.f_nsyms * SYMESZ, *n_strtab);
+
+    nb_syms = fhdr.f_nsyms;
+
+    for (i = 0, ext_sym = xcoff_symtab; i < nb_syms;
+         i++, ext_sym = (struct syment *)((char*)ext_sym + SYMESZ)) {
+        if (strstart(ext_sym->n_name, ".text", NULL))
+            text_shndx = ext_sym->n_scnum;
+        if (strstart(ext_sym->n_name, ".data", NULL))
+            data_shndx = ext_sym->n_scnum;
+    }
+
+    /* set xcoff symbol */
+
+    symtab = malloc(sizeof(struct xcoff_sym) * nb_syms);
+
+    for (i = 0, ext_sym = xcoff_symtab, sym = symtab;
+         i < nb_syms; i++, sym++, ext_sym = (struct syment *)((char*)ext_sym + SYMESZ)) {
+
+        memset(sym, 0, sizeof(*sym));
+	if (ext_sym->n_sclass == C_NULL)
+		continue;
+	if (ext_sym->n_scnum == N_DEBUG)
+		continue;
+
+        sym->st_syment = ext_sym;
+        sym_ent_name(ext_sym, sym);
+        sym->st_value = ext_sym->n_value;
+        aux_size = ext_sym->n_numaux;
+
+        if (ext_sym->n_scnum == text_shndx &&
+            ISFCN(ext_sym->n_type)) {
+
+            for (j = aux_size + 1; j < nb_syms - i; j++) {
+                struct syment *next_sym = (struct syment *)((char*)ext_sym + j * SYMESZ);
+
+                if (next_sym->n_sclass != C_NULL &&
+		    next_sym->n_scnum == text_shndx &&
+                    ISFCN(next_sym->n_type)){
+                    sym->st_size = next_sym->n_value - ext_sym->n_value;
+                    break;
+                } else if (j == nb_syms - i - 1) {
+                    sec = &shdr[xcoff_text_shndx];
+                    sym->st_size = sec->s_size - ext_sym->n_value;
+                    break;
+                }
+            }
+
+        } else if (ext_sym->n_scnum == data_shndx &&
+                   ext_sym->n_sclass == C_EXTERNAL) {
+
+            for (j = aux_size + 1; j < nb_syms - i; j++) {
+                struct syment *next_sym = (struct syment *)((char*)ext_sym + j * SYMESZ);
+
+                if (next_sym->n_sclass != C_NULL && next_sym->n_scnum == data_shndx) {
+                    sym->st_size = next_sym->n_value - ext_sym->n_value;
+                    break;
+                } else if (j == nb_syms - i - 1) {
+                    sec = &shdr[xcoff_data_shndx];
+                    sym->st_size = sec->s_size - ext_sym->n_value;
+                    break;
+                }
+            }
+        } else {
+            sym->st_size = 0;
+        }
+        sym->st_type = ext_sym->n_type;
+        sym->st_shndx = ext_sym->n_scnum;
+    }
+
+    /* find text relocations */
+
+    sec = &shdr[xcoff_text_shndx];
+    xcoff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc * RELSZ);
+    nb_relocs = sec->s_nreloc;
+
+    /* set xcoff relocation */
+
+    relocs = malloc(sizeof(struct xcoff_rel) * nb_relocs);
+    for (i = 0, ext_rel = xcoff_relocs, rel = relocs; i < nb_relocs;
+         i++, ext_rel = (struct reloc *)((char*)ext_rel + RELSZ), rel++) {
+        memset(rel, 0, sizeof(*rel));
+        rel->xcoff_reloc = ext_rel;
+        rel->xcoff_offset = ext_rel->r_vaddr;
+        rel->xcoff_size = ext_rel->r_rsize;
+        rel->xcoff_type = ext_rel->r_rtype;
+    }
+    /* find data relocations */
+
+    sec = &shdr[xcoff_data_shndx];
+    xcoff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc * RELSZ);
+    data_nb_relocs = sec->s_nreloc;
+
+    /* set xcoff relocation */
+
+    data_relocs = malloc(sizeof(struct xcoff_rel) * data_nb_relocs);
+    for (i = 0, ext_rel = xcoff_relocs, rel = data_relocs; i < data_nb_relocs;
+         i++, ext_rel = (struct reloc *)((char*)ext_rel + RELSZ), rel++) {
+        memset(rel, 0, sizeof(*rel));
+        rel->xcoff_reloc = ext_rel;
+        rel->xcoff_offset = ext_rel->r_vaddr;
+        rel->xcoff_size = ext_rel->r_rsize;
+        rel->xcoff_type = ext_rel->r_rtype;
+    }
+    return 0;
+}
+#endif
+
+void get_reloc_expr(char *name, int name_size, const char *sym_name)
+{
+    const char *p;
+#if defined(CONFIG_FORMAT_XCOFF)
+    if (strstart(sym_name, "_op_param", &p)) {
+        snprintf(name, name_size, "param%s", p);
+    } else if (strstart(sym_name, ".__op_gen_label", &p)) {
+        snprintf(name, name_size, "gen_labels[param%s]", p);
+    } else if (sym_name[0] == '.') {
+      snprintf(name, name_size, "(long)*(void**)(%s)", sym_name + 1);
+    } else {
+      snprintf(name, name_size, "(long)(&%s)", sym_name);
+    }
+#else
     if (strstart(sym_name, "__op_param", &p)) {
         snprintf(name, name_size, "param%s", p);
     } else if (strstart(sym_name, "__op_gen_label", &p)) {
@@ -1230,6 +1560,7 @@
 #endif
             snprintf(name, name_size, "(long)(&%s)", sym_name);
     }
+#endif
 }
 
 #ifdef HOST_IA64
@@ -1480,6 +1811,42 @@
     }
 #endif
 #elif defined(HOST_PPC)
+#ifdef CONFIG_FORMAT_XCOFF
+    {
+        uint8_t *p;
+	uint32_t inst;
+	signed short disp;
+	name ++;	/* remove first '.' */
+	/* -O2 doesn't remove stack management, we do */
+	disp = 0;
+	/* stwu r1,x(r1) */
+	inst = get32((uint32_t *)p_start);
+	if ((inst & 0xFFFF0000) == 0x94210000) {
+	    disp = -(short)(inst & 0x0000FFFF);
+	    start_offset += 4;
+	    p_start += 4;
+        }
+        p = (void*)(p_end - 4);
+        if (p == p_start)
+            error("empty code for %s", name);
+	/* blr */
+        while (get32((uint32_t *)p) != 0x4e800020) {
+            p -= 4;
+            if (p <= p_start)
+                error("blr expected at the end of %s [0x%p-0x%p]", name, p_start - start_offset, p_end);
+        }
+	inst = get32((uint32_t *)(p - 4));
+	if (disp !=0) {
+	    /* addi r1,r1,x */
+            if ((inst & 0xFFFF0000) != 0x38210000)
+		error("addi r1,r1,x expected at end of %s\n", name);
+            if (disp != (short)(inst & 0x0000FFFF))
+	        error("Bad stack management for %s", name);
+            p -= 4;
+        }
+        copy_size = p - p_start;
+    }
+#else
     {
         uint8_t *p;
         p = (void *)(p_end - 4);
@@ -1489,6 +1856,7 @@
             error("blr expected at the end of %s", name);
         copy_size = p - p_start;
     }
+#endif
 #elif defined(HOST_S390)
     {
         uint8_t *p;
@@ -1691,8 +2059,13 @@
             sym_name = get_rel_sym_name(rel);
             if(!sym_name)
                 continue;
+#if defined(CONFIG_FORMAT_XCOFF)
+            if (strstart(sym_name, "_op_param", &p) ||
+                strstart(sym_name, ".__op_gen_label", &p)) {
+#else
             if (strstart(sym_name, "__op_param", &p) ||
                 strstart(sym_name, "__op_gen_label", &p)) {
+#endif
                 n = strtoul(p, NULL, 10);
                 if (n > MAX_ARGS)
                     error("too many arguments in %s", name);
@@ -1737,6 +2110,19 @@
                 sym_name = get_rel_sym_name(rel);
                 if(!sym_name)
                     continue;
+#if defined(CONFIG_FORMAT_XCOFF)
+                if (*sym_name &&
+                    !strstart(sym_name, "_op_param", NULL) &&
+                    !strstart(sym_name, ".__op_jmp", NULL) &&
+                    !strstart(sym_name, ".__op_gen_label", NULL)) {
+		    if (sym_name[0] == '.')
+			sym_name++;
+                    if (rel->xcoff_type == R_RBR)
+                        fprintf(outfile, "    extern void %s();\n", sym_name);
+                    else if (rel->xcoff_type != R_TOC)
+                        fprintf(outfile, "    extern char %s;\n", sym_name);
+                }
+#else
                 if (*sym_name &&
                     !strstart(sym_name, "__op_param", NULL) &&
                     !strstart(sym_name, "__op_jmp", NULL) &&
@@ -1763,14 +2149,20 @@
 				fprintf(outfile, "    extern char %s;\n",
 					sym_name);
 #else
-                    fprintf(outfile, "extern char %s;\n", sym_name);
-#endif
+                    fprintf(outfile, "    extern char %s;\n", sym_name);
                 }
+#endif
+#endif
             }
         }
 
+#if defined(_AIX)
+        fprintf(outfile, "    memcpy(gen_code_ptr, (void*)((*(void **)%s) + %d), %d);\n",
+					name, (int)(start_offset - offset), copy_size);
+#else
         fprintf(outfile, "    memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n",
 					name, (int)(start_offset - offset), copy_size);
+#endif
 
         /* emit code offset information */
         {
@@ -1781,10 +2173,13 @@
 
             for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
                 sym_name = get_sym_name(sym);
+#if defined(CONFIG_FORMAT_XCOFF)
+                if (strstart(sym_name, ".__op_label", &p)) {
+#else
                 if (strstart(sym_name, "__op_label", &p)) {
+#endif
                     uint8_t *ptr;
                     unsigned long offset;
-
                     /* test if the variable refers to a label inside
                        the code we are generating */
 #ifdef CONFIG_FORMAT_COFF
@@ -1799,6 +2194,14 @@
                     if(!sym->n_sect)
                         continue;
                     ptr = sdata[sym->n_sect-1];
+#elif defined(CONFIG_FORMAT_XCOFF)
+                    if (sym->st_shndx == text_shndx) {
+                        ptr = sdata[xcoff_text_shndx];
+                    } else if (sym->st_shndx == data_shndx) {
+                        ptr = sdata[xcoff_data_shndx];
+                    } else {
+                        ptr = NULL;
+                    }
 #else
                     ptr = sdata[sym->st_shndx];
 #endif
@@ -1808,8 +2211,7 @@
 #ifdef CONFIG_FORMAT_MACH
                     offset -= section_hdr[sym->n_sect-1].addr;
 #endif
-                    val = *(host_ulong *)(ptr + offset);
-#ifdef ELF_USES_RELOCA
+#if defined(ELF_USES_RELOCA)
                     {
                         int reloc_shndx, nb_relocs1, j;
 
@@ -1828,6 +2230,10 @@
                             }
                         }
                     }
+#elif defined(CONFIG_FORMAT_XCOFF)
+                    val = (host_ulong)offset;
+#else
+                    val = *(host_ulong *)(ptr + offset);
 #endif
                     if (val >= start_offset && val <= start_offset + copy_size) {
                         n = strtol(p, NULL, 10);
@@ -2089,6 +2495,65 @@
                             error("unsupported powerpc relocation (%d)", type);
                     }
                 }
+#elif defined(CONFIG_FORMAT_XCOFF)
+                char relname[256];
+                int sign, len;
+                int reloc_offset;
+                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
+
+                    if (rel->xcoff_offset >= start_offset &&
+		        rel->xcoff_offset < start_offset + copy_size) {
+                        sym_name = get_rel_sym_name(rel);
+                        if (!sym_name)
+                            continue;
+
+                        reloc_offset = rel->xcoff_offset - start_offset;
+                        if (strstart(sym_name, ".__op_jmp", &p)) {
+                            int n;
+                            n = strtol(p, NULL, 10);
+                            /* .__op_jmp relocations are done at
+                               runtime to do translated block
+                               chaining: the offset of the instruction
+                               needs to be stored */
+                            fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, reloc_offset);
+                            continue;
+                        }
+                    get_reloc_expr(relname, sizeof(relname), sym_name);
+                len = (rel->xcoff_size & R_LEN) + 1;
+                sign = (rel->xcoff_size & R_SIGN) ? -1 : 1;
+                switch(rel->xcoff_type) {
+		case R_ABS:
+		    break;
+                case R_TOC:
+			if (strstart(sym_name, "_op_param", NULL)) {
+			    /* create "lis %0, param@h" with %0 from next opcode */
+	    		fprintf(outfile,
+"    *(uint16_t *)(gen_code_ptr + %d - 2) = 0x3c00 | "
+"(*(uint16_t *)(gen_code_ptr + %d + 2) & 0x03e0);\n",
+reloc_offset, reloc_offset);
+			    fprintf(outfile,
+"    *(uint16_t *)(gen_code_ptr + %d) = %s >> 16;\n",
+reloc_offset,  relname);
+			    /* update "ori %0,%0,param@l" */
+			    fprintf(outfile,
+"    *(uint16_t *)(gen_code_ptr + %d + 4) = %s & 0xffff;\n",
+reloc_offset, relname);
+			}
+                    break;
+                case R_RBR:
+                        fprintf(outfile,
+"    *(uint32_t *)(gen_code_ptr + %d) = "
+     "(*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | "
+     "((%s - (long)(gen_code_ptr + %d)) & 0x03fffffc);\n",
+     reloc_offset, reloc_offset, relname, reloc_offset);
+                    break;
+                default:
+                    error("unsupported XCOFF relocation type (%x)\n",
+                          rel->xcoff_type);
+                    break;
+                }
+            }
+            }
 #else
 #error unsupport object format
 #endif
@@ -2658,7 +3123,7 @@
             const char *name;
             name = get_sym_name(sym);
             if (strstart(name, OP_PREFIX, NULL)) {
-#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
+#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_XCOFF)
                 if (sym->st_shndx != text_shndx)
                     error("invalid section for opcode (0x%x)", sym->st_shndx);
 #endif
@@ -2824,7 +3289,7 @@
                 printf("%4d: %s pos=0x%08x len=%d\n",
                        i, name, sym->st_value, sym->st_size);
 #endif
-#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
+#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_XCOFF)
                 if (sym->st_shndx != text_shndx)
                     error("invalid section for opcode (0x%x)", sym->st_shndx);
 #endif
Index: qemu-0.9.1-aix/Makefile.target
===================================================================
--- qemu-0.9.1-aix.orig/Makefile.target	2008-04-10 13:17:42.-1748325248 +0200
+++ qemu-0.9.1-aix/Makefile.target	2008-04-10 13:17:44.1186875536 +0200
@@ -73,6 +73,7 @@
 PROGS=$(QEMU_PROG)
 
 # We require -O2 to avoid the stack setup prologue in EXIT_TB
+# (except for AIX...)
 OP_CFLAGS := -Wall -O2 -g -fno-strict-aliasing
 
 # cc-option
@@ -90,6 +91,10 @@
 OP_CFLAGS+=$(call cc-option, -fno-align-jumps, "")
 OP_CFLAGS+=$(call cc-option, -fno-align-functions, $(call cc-option, -malign-functions=0, ""))
 OP_CFLAGS+=$(call cc-option, -fno-section-anchors, "")
+ifdef CONFIG_AIX
+OP_CFLAGS+=$(call cc-option, -mlongcall, "")
+OP_CFLAGS+=$(call cc-option, -mno-sched-prolog, "")
+endif
 
 HELPER_CFLAGS=
 
@@ -153,7 +158,12 @@
 LDFLAGS+=$(OS_LDFLAGS) $(ARCH_LDFLAGS)
 OP_CFLAGS+=$(OS_CFLAGS) $(ARCH_CFLAGS)
 
-CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+CPPFLAGS+=-D_GNU_SOURCE
+ifdef CONFIG_AIX
+CPPFLAGS+= -D_LARGE_FILES
+else
+CPPFLAGS+= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+endif
 LIBS+=-lm
 ifdef CONFIG_WIN32
 LIBS+=-lwinmm -lws2_32 -liphlpapi
@@ -613,10 +623,12 @@
 ifndef CONFIG_DARWIN
 ifndef CONFIG_WIN32
 ifndef CONFIG_SOLARIS
+ifndef CONFIG_AIX
 LIBS+=-lutil
 endif
 endif
 endif
+endif
 ifdef TARGET_GPROF
 vl.o: CFLAGS+=-p
 LDFLAGS+=-p
Index: qemu-0.9.1-aix/osdep.c
===================================================================
--- qemu-0.9.1-aix.orig/osdep.c	2008-04-10 13:16:46.-1554046032 +0200
+++ qemu-0.9.1-aix/osdep.c	2008-04-10 13:17:44.-1697598352 +0200
@@ -199,7 +199,7 @@
     if (kqemu_allowed)
         return kqemu_vmalloc(size);
 #endif
-#ifdef _BSD
+#if defined(_BSD) || defined(_AIX)
     return valloc(size);
 #else
     return memalign(4096, size);
Index: qemu-0.9.1-aix/dyngen-exec.h
===================================================================
--- qemu-0.9.1-aix.orig/dyngen-exec.h	2008-04-10 13:16:46.1266244784 +0200
+++ qemu-0.9.1-aix/dyngen-exec.h	2008-04-10 13:17:44.-1762903424 +0200
@@ -237,12 +237,34 @@
 #else
 extern int __op_param1, __op_param2, __op_param3;
 #endif
+#if defined(_AIX)
+asm("\t.toc\n"
+    "__op_param1_toc:\n"
+    "\t.tc __op_param1[TC],__op_param1[RW]\n"
+    "__op_param2_toc:\n"
+    "\t.tc __op_param2[TC],__op_param2[RW]\n"
+    "__op_param3_toc:\n"
+    "\t.tc __op_param3[TC],__op_param3[RW]\n"
+    "\t.csect .text[PR]\n");
+
+#define PARAM1 ({ long _r; asm("lwz %0,"ASM_NAME(__op_param1_toc)"(2); ori %0,%0,0" : "=r" (_r) : ); _r; })
+#define PARAM2 ({ long _r; asm("lwz %0,"ASM_NAME(__op_param2_toc)"(2); ori %0,%0,0" : "=r" (_r) : ); _r; })
+#define PARAM3 ({ long _r; asm("lwz %0,"ASM_NAME(__op_param3_toc)"(2); ori %0,%0,0" : "=r" (_r) : ); _r; })
+#else
 #define PARAM1 ((long)(&__op_param1))
 #define PARAM2 ((long)(&__op_param2))
 #define PARAM3 ((long)(&__op_param3))
+#endif
 #endif /* !defined(__alpha__) */
 
+#if defined(_AIX)
+extern void __op_jmp0(void);
+extern void __op_jmp1(void);
+extern void __op_jmp2(void);
+extern void __op_jmp3(void);
+#else
 extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
+#endif
 
 #if defined(_WIN32) || defined(__APPLE__)
 #define ASM_NAME(x) "_" #x
@@ -258,7 +280,11 @@
 #define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
 #elif defined(__powerpc__)
 #define EXIT_TB() asm volatile ("blr")
+#if defined(_AIX)
+#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(.__op_gen_label) #n)
+#else
 #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
+#endif
 #elif defined(__s390__)
 #define EXIT_TB() asm volatile ("br %r14")
 #define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; .long " ASM_NAME(__op_gen_label) #n)
Index: qemu-0.9.1-aix/dyngen.h
===================================================================
--- qemu-0.9.1-aix.orig/dyngen.h	2008-04-10 13:16:46.-208811696 +0200
+++ qemu-0.9.1-aix/dyngen.h	2008-04-10 13:17:44.1057387392 +0200
@@ -19,14 +19,21 @@
  */
 
 int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
+#if defined(__sparc__) || defined(__arm__) || defined(_AIX)
   void __op_gen_label1(){}
   void __op_gen_label2(){}
   void __op_gen_label3(){}
 #else
   int __op_gen_label1, __op_gen_label2, __op_gen_label3;
 #endif
+#if defined(_AIX)
+void __op_jmp0(void) { }
+void __op_jmp1(void) { }
+void __op_jmp2(void) { }
+void __op_jmp3(void) { }
+#else
 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
+#endif
 
 #if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
 static inline void flush_icache_range(unsigned long start, unsigned long stop)
Index: qemu-0.9.1-aix/block-qcow2.c
===================================================================
--- qemu-0.9.1-aix.orig/block-qcow2.c	2008-04-10 13:16:46.-1683721176 +0200
+++ qemu-0.9.1-aix/block-qcow2.c	2008-04-10 13:17:44.-417269088 +0200
@@ -1386,6 +1386,8 @@
     uint32_t extra_data_size;
 
     offset = s->snapshots_offset;
+    if (s->nb_snapshots == 0)
+        goto out;
     s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot));
     if (!s->snapshots)
         goto fail;
@@ -1424,6 +1426,7 @@
         offset += name_size;
         sn->name[name_size] = '\0';
     }
+out:
     s->snapshots_size = offset - s->snapshots_offset;
     return 0;
  fail:
Index: qemu-0.9.1-aix/cpu-exec.c
===================================================================
--- qemu-0.9.1-aix.orig/cpu-exec.c	2008-04-10 13:17:42.-1050821632 +0200
+++ qemu-0.9.1-aix/cpu-exec.c	2008-04-10 13:17:44.-285395568 +0200
@@ -735,6 +735,17 @@
 		fp.ip = tc_ptr;
 		fp.gp = code_gen_buffer + 2 * (1 << 20);
 		(*(void (*)(void)) &fp)();
+#elif defined(_AIX)
+		asm volatile ("mtctr %0\n"
+			      "stwu 1,-512(1)\n"
+			      "bctrl\n"
+			      "addi 1,1,512\n"
+			      : : "r" (tc_ptr)
+			      : "r3", "r4", "r5", "r6", "r7", "r8",
+			        "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+				"r16", "r17", "r18", "r19", "r20", "r21", "r22",
+				"r23", "r24", "r25", "r26", "r27", "r28", "r29",
+				"r30", "r31", "lr", "ctr");
 #else
                 gen_func();
 #endif
Index: qemu-0.9.1-aix/target-ppc/op.c
===================================================================
--- qemu-0.9.1-aix.orig/target-ppc/op.c	2008-04-10 13:16:46.-338307840 +0200
+++ qemu-0.9.1-aix/target-ppc/op.c	2008-04-10 13:17:44.-1957158640 +0200
@@ -25,6 +25,7 @@
 #include "host-utils.h"
 #include "helper_regs.h"
 #include "op_helper.h"
+#undef hz
 
 #define REG 0
 #include "op_template.h"
Index: qemu-0.9.1-aix/target-ppc/translate.c
===================================================================
--- qemu-0.9.1-aix.orig/target-ppc/translate.c	2008-04-10 13:16:46.-402951912 +0200
+++ qemu-0.9.1-aix/target-ppc/translate.c	2008-04-10 13:17:44.865179176 +0200
@@ -21,7 +21,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <strings.h>
 #include <inttypes.h>
+#undef hz
 
 #include "cpu.h"
 #include "exec-all.h"
Index: qemu-0.9.1-aix/Makefile
===================================================================
--- qemu-0.9.1-aix.orig/Makefile	2008-04-10 13:17:42.-273201768 +0200
+++ qemu-0.9.1-aix/Makefile	2008-04-10 13:50:33.-1633089280 +0200
@@ -11,7 +11,12 @@
 LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS)
 
 CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP
-CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+CPPFLAGS += -D_GNU_SOURCE
+ifdef CONFIG_AIX
+CPPFLAGS += -DLARGE_FILES
+else
+CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+endif
 LIBS=
 ifdef CONFIG_STATIC
 LDFLAGS += -static
Index: qemu-0.9.1-aix/block-raw-posix.c
===================================================================
--- qemu-0.9.1-aix.orig/block-raw-posix.c	2008-04-10 13:24:07.000000000 +0200
+++ qemu-0.9.1-aix/block-raw-posix.c	2008-04-10 13:55:43.-1877807392 +0200
@@ -534,7 +534,9 @@
               0644);
     if (fd < 0)
         return -EIO;
-    ftruncate(fd, total_size * 512);
+    if (ftruncate(fd, total_size * 512) < 0)
+        return -errno;
+
     close(fd);
     return 0;
 }

