diff -urN qemu-0.10.0/cpu-all.h qemu-0.10.0.alpha/cpu-all.h
--- qemu-0.10.0/cpu-all.h    2009-03-04 14:54:45.000000000 -0800
+++ qemu-0.10.0.alpha/cpu-all.h    2009-10-25 23:13:53.000000000 -0700
@@ -22,7 +22,7 @@
 
 #include "qemu-common.h"
 
-#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__)
+#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__alpha__)
 #define WORDS_ALIGNED
 #endif
 
diff -urN qemu-0.10.0/tcg/alpha/tcg-target.c qemu-0.10.0.alpha/tcg/alpha/tcg-target.c
--- qemu-0.10.0/tcg/alpha/tcg-target.c    1969-12-31 16:00:00.000000000 -0800
+++ qemu-0.10.0.alpha/tcg/alpha/tcg-target.c    2009-11-26 05:13:41.000000000 -0800
@@ -0,0 +1,1477 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * code review modification:
+ * 1. $15 is deleted from reserved register set and add to tcg_target_reg_alloc_order[]
+ * 2. $25 is deleted from tcg_target_reg_alloc_order[]
+ * 3. callee-clobbered register set bug fixed
+ * 4. tcg_out_ld/st bug fixed
+ * 5. translation of INDEX_op_exit_tb bug fixed
+ * 6. translation of INDEX_op_goto_tb bug fixed
+ * 7. tcg_out_brcond() bug fixed
+ * 8. patch_reloc() rewritten
+ * 9. qemu_ld/st() bug fixed
+ * 10. mul() ???
+ * 11. be careful about register order, like tcg_out_mov()
+ * 12. remove INDEX_op_mov(i)_i32/i64 from tcg_out_op(), they are already implemented in tcg.c
+ * 13. icache flush not implemented ???
+*/
+
+#ifndef NDEBUG
+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+    "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+    "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
+    "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
+    "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
+};
+#endif
+
+/* 
+ * $26 ~ $31 are special, reserved, 
+ * and $25 is deliberately reserved for jcc operation
+ * and $0 is usually used for return function result, better allocate it later
+ * and $15 is used for cpu_env pointer, allocate it at last
+*/
+static const int tcg_target_reg_alloc_order[] = {
+    TCG_REG_1, TCG_REG_2, TCG_REG_3, TCG_REG_4, TCG_REG_5, TCG_REG_6,
+    TCG_REG_7, TCG_REG_8, TCG_REG_22, TCG_REG_23, TCG_REG_24,
+    TCG_REG_9, TCG_REG_10, TCG_REG_11, TCG_REG_12, TCG_REG_13, TCG_REG_14,
+    TCG_REG_16, TCG_REG_17, TCG_REG_18, TCG_REG_19, TCG_REG_20, TCG_REG_21,
+    TCG_REG_0, TCG_REG_15
+};
+
+/*
+ * according to alpha calling convention, these 6 registers are used for 
+ * function parameter passing. if function has more than 6 parameters, remained
+ * ones are stored on stack.
+*/
+static const int tcg_target_call_iarg_regs[6] = { 
+    TCG_REG_16, TCG_REG_17, TCG_REG_18, TCG_REG_19, TCG_REG_20, TCG_REG_21
+    };
+
+/*
+ * according to alpha calling convention, $0 is used for returning function result.
+*/
+static const int tcg_target_call_oarg_regs[1] = { TCG_REG_0 };
+
+/*
+ * save the address of TB's epilogue.
+*/
+static uint8_t *tb_ret_addr;
+
+/* 
+ * op-code and func-code for jump insn 
+*/
+#define CONTROL_CALL    0x01A
+#define CONTROL_RET        0x01A
+#define CONTROL_JMP        0x01A
+
+#define FUNC_JMP        0x00
+#define FUNC_CALL        0x01
+#define FUNC_RET        0x02
+
+#define CONTROL_BR        0x30
+#define CONTROL_BSR        0x34
+#define CONTROL_BEQ        0x39
+#define CONTROL_BNE        0x3D
+#define CONTROL_BLT        0x3A
+#define CONTROL_BLE        0x3B
+#define CONTROL_BGT        0x3F
+#define CONTROL_BGE        0x3E
+#define CONTROL_BLBC    0x38
+#define CONTROL_BLBS    0x3C
+
+#define ALPHA_ARITH        0x10
+
+#define ARITH_ADDL        0x00
+#define ARITH_SUBL        0x09
+#define ARITH_ADDQ        0x20
+#define ARITH_SUBQ        0x29
+#define ARITH_CMPEQ        0x2D
+#define ARITH_CMPLT        0x4D
+#define ARITH_CMPLE        0x6D
+#define ARITH_CMPULT    0x1D
+#define ARITH_CMPULE    0x3D
+
+#define ALPHA_MUL        0x13
+
+#define ARITH_MULL        0x00
+#define ARITH_MULQ        0x20
+
+#define ALPHA_LOGIC        0x11
+
+#define ARITH_AND        0x00
+#define ARITH_BIC        0x08
+#define ARITH_BIS        0x20
+#define ARITH_ORNOT        0x28
+#define ARITH_XOR        0x40
+#define ARITH_EQV        0x48
+
+#define ALPHA_SHIFT        0x12
+
+#define ARITH_SLL        0x39
+#define ARITH_SRL        0x34
+#define ARITH_SRA        0x3C
+
+#define ALPHA_SEXT        0x1C
+
+#define ARITH_SEXTB        0x00
+#define ARITH_SEXTW        0x01
+
+#define ALPHA_LDA        0x08
+#define ALPHA_LDAH        0x09
+#define ALPHA_LDBU        0x0A
+#define ALPHA_LDWU        0x0C
+#define ALPHA_LDL        0x28
+#define ALPHA_LDQ        0x29
+#define ALPHA_STB        0x0E
+#define ALPHA_STW        0x0D
+#define ALPHA_STL        0x2C
+#define ALPHA_STQ        0x2D
+
+/*
+ * return the # of regs used for parameter passing on procedure calling.
+ * note that alpha use $16~$21 to transfer the first 6 paramenters of a procedure.
+*/
+static inline int tcg_target_get_call_iarg_regs_count(int flags)
+{
+    return 6;
+}
+
+/*
+ * given constraint, return available register set. this function is called once
+ * for each op at qemu's initialization stage.
+*/
+static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+{
+    const char *ct_str = *pct_str;
+
+    switch(ct_str[0]) 
+    {
+    case 'r':
+        /* constaint 'r' means any register is okay */
+        ct->ct |= TCG_CT_REG;
+        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+        break;
+
+    case 'L':
+        /* 
+        * constranit 'L' is used for qemu_ld/st, which has 2 meanings:
+        * 1st, we the argument need to be allocated a register.
+        * 2nd, we should reserve some registers that belong to caller-clobbered 
+        * list for qemu_ld/st local usage, so these registers must not be 
+        * allocated to the argument that the 'L' constraint is describing.
+        *
+        * note that op qemu_ld/st has the TCG_OPF_CALL_CLOBBER flag, and 
+        * tcg will free all callee-clobbered registers before generate target
+        * insn for qemu_ld/st, so we can use these register directly without
+        * warrying about destroying their content.
+        */
+        ct->ct |= TCG_CT_REG;
+        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_0);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_16);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_17);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_18);
+        break;
+
+    default:
+        return -1;
+    }
+
+    ct_str++;
+    *pct_str = ct_str;
+    return 0;
+}
+
+/*
+ * whether op's input argument may use constant 
+*/
+static inline int tcg_target_const_match( \
+    tcg_target_long val, const TCGArgConstraint *arg_ct)
+{
+    int ct;
+    ct = arg_ct->ct;
+    if (ct & TCG_CT_CONST)
+        return 1;
+    else
+        return 0;
+}
+
+/*
+ * construct insn with following format. 
+ * (suitable for conditional branch insn)
+ *
+ * 31        26 25    21 20                            0
+ * ------------------------------------------------------
+ * |   OpCode  |   Ra   |              Disp             |
+ * ------------------------------------------------------
+*/
+static inline void tcg_out_inst2(TCGContext *s, int Opcode, int Ra, int Disp)
+{
+    uint32_t v;
+     
+    v = ( ( Opcode & 0x3f ) << 26  )
+       | ( ( Ra & 0x1f ) << 21 )
+       | ( Disp & 0x1fffff) ;
+
+    tcg_out32(s, v);     
+}
+
+/*
+ * construct insn with following format. 
+ * (used for ld/st or lda/ldah insn)
+ *
+ * 31        26 25    21 20    16 15                   0
+ * ------------------------------------------------------
+ * |   OpCode  |   Ra   |   Rb   |     Disp             |
+ * ------------------------------------------------------
+*/
+static inline void tcg_out_inst3_disp(TCGContext *s, int Opcode, int Ra, int Rb, int Disp)
+{
+    uint32_t v;
+     
+    v = ( ( Opcode & 0x3f ) << 26  )
+       | ( ( Ra & 0x1f ) << 21 )
+       | ( ( Rb & 0x1f ) << 16 )
+       | ( Disp & 0xffff) ;
+
+    tcg_out32(s, v);     
+}
+
+/*
+ * construct insn with following format. 
+ * (used for jmp insn)
+ *
+ * 31        26 25    21 20    16 15                   0
+ * ------------------------------------------------------
+ * |   OpCode  |   Ra   |   Rb   | Func |    Rsvd       |
+ * ------------------------------------------------------
+*/
+static inline void tcg_out_inst3_func(TCGContext *s, int Opcode, int Ra, int Rb, int Func, int Disp)
+{
+    uint32_t v;
+     
+    v = ( ( Opcode & 0x3f ) << 26  )
+       | ( ( Ra & 0x1f ) << 21 )
+       | ( ( Rb & 0x1f ) << 16 )
+       | ( ( Func & 0x3 ) << 14 )
+       | ( Disp & 0x3fff) ;
+
+    tcg_out32(s, v);     
+}
+
+/*
+ * construct insn with following format. 
+ * (used for operate insn)
+ *
+ *                                        1
+ * 31        26 25    21 20    16 15 13 2 11     5 4   0
+ * ------------------------------------------------------
+ * |   OpCode  |   Ra   |   Rb   | SBZ |0|  Func  | Rc  |
+ * ------------------------------------------------------
+*/
+static inline void tcg_out_inst4(TCGContext *s, int Opcode, int Ra, int Rb, int Func, int Rc)
+{
+    uint32_t v;
+
+    v = ( (Opcode & 0x3f) << 26  )
+       | ( ( Ra & 0x1f ) << 21 )
+       | ( ( Rb & 0x1f ) << 16 )
+       | ( ( Func & 0x7f ) << 5 )
+       | ( Rc & 0x1f ) ;
+
+    tcg_out32(s, v);     
+}
+
+/*
+ * construct insn with following format. 
+ * (used for operate insn with immediate)
+ *
+ *                                        1
+ * 31        26 25    21 20          13 2 11     5 4   0
+ * ------------------------------------------------------
+ * |   OpCode  |   Ra   |     LIT      |1|  Func  | Rc  |
+ * ------------------------------------------------------
+*/
+static inline void tcg_out_inst4i(TCGContext *s, int Opcode, int Ra, int Lit, int Func, int Rc)
+{
+    uint32_t v;
+
+    v = ( (Opcode & 0x3f) << 26  )
+       | ( ( Ra & 0x1f ) << 21 )
+       | ( ( Lit & 0xff ) << 13 )
+       | ( ( Func & 0x7f ) << 5 )
+       | ( 1 << 12 )
+       | ( Rc & 0x1f ) ;
+
+    tcg_out32(s, v);     
+}
+
+/*
+ * mov from a reg to another
+*/
+static inline void tcg_out_mov(TCGContext *s, int Rc, int Rb)
+{  
+    if ( Rb != Rc ) {
+        tcg_out_inst4(s, ALPHA_LOGIC, TCG_REG_31, Rb, ARITH_BIS, Rc);        // bis $31, Rb, Rc
+    }
+}
+
+/*
+ * mov a 64-bit immediate 'arg' to regsiter 'Ra', this function will
+ * generate fixed length (5 insns, 20 bytes) of target insn sequence.
+*/
+static inline void tcg_out_movi_fixl( \
+    TCGContext *s, TCGType type, int Ra, tcg_target_long arg)
+{
+    if( arg & ((tcg_target_ulong)0x800000000000) )
+        tcg_out_inst3_disp(s, ALPHA_LDAH, Ra, TCG_REG_31, (arg>>48)+1 );
+    else
+        tcg_out_inst3_disp(s, ALPHA_LDAH, Ra, TCG_REG_31, arg>>48 );        // ldah Ra, arg<63:48>($31)
+     
+    if( arg & ((tcg_target_ulong)0x80000000) )
{
+        tcg_out_inst3_disp(s, ALPHA_LDA, Ra, Ra, (arg>>32)+1 ); 
+    }
+    else
+        tcg_out_inst3_disp(s, ALPHA_LDA, Ra, Ra, arg>>32 );                    // lda Ra, arg<47:32>(Ra)
+     
+    tcg_out_inst4i(s, ALPHA_SHIFT, Ra, 32, ARITH_SLL, Ra);                    // sll Ra, 32, Ra
+     
+    if( arg & ((tcg_target_ulong)0x8000) )
+        tcg_out_inst3_disp(s, ALPHA_LDAH, Ra, Ra, (arg>>16)+1 ); 
+    else
+        tcg_out_inst3_disp(s, ALPHA_LDAH, Ra, Ra, arg>>16 );                // ldah Ra, arg<31:16>(Ra)
+     
+    tcg_out_inst3_disp(s, ALPHA_LDA, Ra, Ra, arg );                            // lda Ra, arg<15:0>(Ra)
+}
+
+/*
+ * mov 64-bit immediate 'arg' to regsiter 'Ra'. this function will
+ * generate variable length of target insn sequence.
+*/
+static inline void tcg_out_movi( \
+    TCGContext *s, TCGType type, int Ra, tcg_target_long arg)
+{
+    if (arg == 0) {
+        tcg_out_inst4(s, ALPHA_LOGIC, Ra, Ra, ARITH_XOR, Ra);                // xor Ra, Ra, Ra
+    }
+    else if( arg == (int16_t)arg ) {
+        tcg_out_inst3_disp(s, ALPHA_LDA, Ra, TCG_REG_31, arg );                // lda Ra, arg<15:0>($31)
+    }
+    else if( arg == (int32_t)arg ) {
+        if( arg & (1<<15) ) {
+            tcg_out_inst3_disp(s, ALPHA_LDAH, Ra, TCG_REG_31, (arg>>16)+1);
+        } else {
+            tcg_out_inst3_disp(s, ALPHA_LDAH, Ra, TCG_REG_31, arg>>16);        // ldah Ra, arg<31:16>($31)
+        }
+        tcg_out_inst3_disp(s, ALPHA_LDA, Ra, Ra, arg );                        // lda Ra, arg<15:0>(Ra)
+    } else {
+        /* use the most complex style of movement */
+        tcg_out_movi_fixl(s, type, Ra, arg);
+    }
+}
+
+/*
+ * load value in disp(Rb) to Ra.
+*/
+static inline void tcg_out_ld( \
+    TCGContext *s, TCGType type, int Ra, int Rb, tcg_target_long disp)
+{
+    int Opcode;
+    
+    if( type == TCG_TYPE_I32) {
+        Opcode = ALPHA_LDL;
+    } else {
+        Opcode = ALPHA_LDQ;
+    }
+     
+    if( disp != (int16_t)disp ) {
+        /* disp cannot be stored in insn directly */
+        tcg_out_movi(s, type, TMP_REG, disp);     
+        tcg_out_inst4(s, ALPHA_ARITH, Rb, TMP_REG, ARITH_ADDQ, TMP_REG);        // addq Rb, TMP_REG, TMP_REG
+        tcg_out_inst3_disp(s, Opcode, Ra, TMP_REG, 0);                        // ldx Ra, 0(TMP_REG)
+    }
+    else
+        tcg_out_inst3_disp(s, Opcode, Ra, Rb, disp);                        // ldx Ra, disp(Rb)
+}
+
+/*
+ * store value in Ra to disp(Rb).
+*/
+static inline void tcg_out_st( \
+    TCGContext *s, TCGType type, int Ra, int Rb, tcg_target_long disp)
+{
+    int Opcode;
+
+    if( type == TCG_TYPE_I32) {
+        Opcode = ALPHA_STL;
+    } else {
+        Opcode = ALPHA_STQ;
+    }
+
+    if( disp != (int16_t)disp ) {
+        /* disp cannot be stored in insn directly */
+        tcg_out_movi(s, type, TMP_REG, disp);
+        tcg_out_inst4(s, ALPHA_ARITH, Rb, TMP_REG, ARITH_ADDQ, TMP_REG);    // addq Rb, TMP_REG, TMP_REG
+        tcg_out_inst3_disp(s, Opcode, Ra, TMP_REG, 0);                        // stx Ra, 0(TMP_REG)
+    }
+    else
+        tcg_out_inst3_disp(s, Opcode, Ra, Rb, disp);                        // stx Ra, disp(Rb)
+}
+
+/*
+ * generate arithmatic instruction with immediate. Ra is used as both
+ * input and output, and val is used as another input.
+*/
+static inline void tgen_arithi( \
+    TCGContext *s, int Opcode, int Func, int Ra, tcg_target_long val)
+{
+    if (val == (uint8_t)val) {
+        tcg_out_inst4i(s, Opcode, Ra, val, Func, Ra);                        // arithi Ra, #b, Ra
+    } else {
+        tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, val);
+        tcg_out_inst4(s, Opcode, Ra, TMP_REG, Func, Ra);                    // arithi Ra, TMP_REG, Ra
+    }
+}
+
+/*
+ * generate addq instruction with immediate.
+*/
+static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+{
+    if (val != 0)
+        tgen_arithi(s, ALPHA_ARITH, ARITH_ADDQ, reg, val);
+}
+
+/*
+ * generate insn to push reg onto stack.
+*/
+static inline void tcg_out_push(TCGContext *s, int reg)
+{
+    tcg_out_inst4i(s, ALPHA_ARITH, TCG_REG_30, 8, ARITH_SUBQ, TCG_REG_30);
+    tcg_out_inst3_disp(s, ALPHA_STQ, reg, TCG_REG_30, 0);
+}
+
+/*
+ * generate insn to pop value from stack to reg.
+*/
+static inline void tcg_out_pop(TCGContext *s, int reg)
+{
+    tcg_out_inst3_disp(s, ALPHA_LDQ, reg, TCG_REG_30, 0);
+    tcg_out_inst4i(s, ALPHA_ARITH, TCG_REG_30, 8, ARITH_ADDQ, TCG_REG_30);
+}
+
+static const uint8_t tcg_cond_to_jcc[10] = {
+    [TCG_COND_EQ] = ARITH_CMPEQ,
+    [TCG_COND_NE] = ARITH_CMPEQ,
+    [TCG_COND_LT] = ARITH_CMPLT,
+    [TCG_COND_GE] = ARITH_CMPLT,
+    [TCG_COND_LE] = ARITH_CMPLE,
+    [TCG_COND_GT] = ARITH_CMPLE,
+    [TCG_COND_LTU] = ARITH_CMPULT,
+    [TCG_COND_GEU] = ARITH_CMPULT,
+    [TCG_COND_LEU] = ARITH_CMPULE,
+    [TCG_COND_GTU] = ARITH_CMPULE
+};
+
+/*
+ * called by tcg_out_reloc() when the label address is determined, 
+ * i.e., label->has_value is true. what should be done is to patch 
+ * the jmp insn that reference this label.
+ *
+ * code_ptr - position need to patch
+ * type - relocation type
+ * value - label address
+ * addend - not used
+*/
+static void patch_reloc(uint8_t *code_ptr, \
+    int type, tcg_target_long value, tcg_target_long addend)
+{
+    TCGContext s;
+     
+    if ( type != R_ALPHA_REFQUAD)
+        tcg_abort();
+     
+    s.code_ptr = code_ptr;
+    tcg_out_movi_fixl(&s, TCG_TYPE_I64, TMP_REG, value);
+    tcg_out_inst3_func(&s, CONTROL_JMP, TCG_REG_31, TMP_REG, FUNC_JMP, 0);
+}
+
+/*
+ * generate insns for BR or BRCOND 
+ * opc must be CONTROL_BR or CONTROL_BLBC or CONTROL_BLBS
+ * Ra fixed to TMP_REG
+*/
+static void tcg_out_jxx(TCGContext *s, int opc, int Ra, int label_index)
+{
+    tcg_target_long val;
+    TCGLabel *l = &s->labels[label_index];
+    
+    if ((Ra != TMP_REG) ||
+        (opc != CONTROL_BR && opc != CONTROL_BLBC && opc != CONTROL_BLBS) )
+        tcg_abort();
+
+    if (l->has_value) {
+        /* the label address has been resolved. */
+        val = (l->u.value - (tcg_target_long)s->code_ptr - 4) >> 2;
+        if ( val >= -0x100000 && val < 0x100000) {        
+            /* if distance can be put into 21-bit field */
+            tcg_out_inst2(s, opc, Ra, val);
+        } else {
+            /* distance can't be put into 21-bit field */
+            if ( opc != CONTROL_BR) {
+                tcg_out_inst2(s, opc^4, Ra, 6); 
+            }
+
+            tcg_out_movi_fixl(s, TCG_TYPE_I64, Ra, l->u.value);
+            tcg_out_inst3_func(s, CONTROL_JMP, TCG_REG_31, Ra, FUNC_JMP, 0);    // jmp $31, TMP_REG, 0 
+        }
+    } else { 
+        /* 
+         * if the label addr has not been determined, we first insert a short jmp,
+         * and then resv space (6 insns, 24 bytes) for long jmp 
+        */
+        if ( opc != CONTROL_BR) {
+            tcg_out_inst2(s, opc^4, Ra, 6); 
+        }
+
+        /* record relocation infor */
+        tcg_out_reloc(s, s->code_ptr, R_ALPHA_REFQUAD, label_index, 0);
+        s->code_ptr += 24;
+    }
+}
+
+/*
+ * generate insn for INDEX_op_brcond
+*/
+static void tcg_out_brcond( TCGContext *s, int cond, \
+    TCGArg arg1, TCGArg arg2, int const_arg2, int label_index)
+{
+    int Func, jcc_opc;
+
+    if ( cond < TCG_COND_EQ || cond > TCG_COND_GTU)
+        tcg_abort();
+
+    /* get function code according to condition */
+    Func = tcg_cond_to_jcc[cond];
+     
+    if ( const_arg2) {
+        tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, arg2);
+        tcg_out_inst4(s, ALPHA_ARITH, arg1, TMP_REG, Func, TMP_REG);    // CMPxx arg1, TMP_REG, TMP_REG
+    } else {
+        tcg_out_inst4(s, ALPHA_ARITH, arg1, arg2, Func, TMP_REG);        // CMPxx arg1, arg2, TMP_REG
+    }
+
+    //
+    // ---------------------------------
+    //  cond & 1  |  TMP_REG  |  take?
+    // ---------------------------------
+    //      0     |     0     |   not
+    //      0     |     1     |   yes
+    //      1     |     0     |   yes
+    //      1     |     1     |   not
+    // ---------------------------------
+    //
+    jcc_opc = (cond & 1) ? CONTROL_BLBC : CONTROL_BLBS;
+    tcg_out_jxx(s, jcc_opc, TMP_REG, label_index);     
+}
+
+
+#if defined(CONFIG_SOFTMMU)
+
+#include "../../softmmu_defs.h"
+
+static void *qemu_ld_helpers[4] = {
+    __ldb_mmu,
+    __ldw_mmu,
+    __ldl_mmu,
+    __ldq_mmu,
+};
+
+static void *qemu_st_helpers[4] = {
+    __stb_mmu,
+    __stw_mmu,
+    __stl_mmu,
+    __stq_mmu,
+};
+
+#endif
+
+/* 
+ * XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
+ * EAX. It will be useful once fixed registers globals are less common. 
+ *
+ * output host insn for op 'qemu_ldxx t0, t1, flags', which means fetching value from t1 to t0.
+ * flags gives the current CPU mode, kernel or user.
+ *
+ * opc argument determines the data width and extension type (zero or signed), and has the 
+ * following layout:
+ *                            2  1  0
+ * ------------------------------------
+ * |                        | E |  W  |
+ * ------------------------------------
+ *
+ * E = 0 means zero extention, 1 means signed extension
+ * W = 0 means byte, 1 means word, 2 means dword.
+ *
+ * Note that VM addr space may be 32-bit or 64-bit, below, we take 32-bit addr space as example
+ * when doing the comment.
+*/
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+{
+    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap;
+
+#if defined(CONFIG_SOFTMMU)
+    uint8_t *label1_ptr, *label2_ptr;
+#endif
+
+    data_reg = *args++;
+    addr_reg = *args++;
+    mem_index = *args;
+    s_bits = opc & 3;
+
+    r0 = TCG_REG_16;
+    r1 = TCG_REG_17;
+
+#if defined(CONFIG_SOFTMMU)
+
+    tcg_out_mov(s, r1, addr_reg); 
+    tcg_out_mov(s, r0, addr_reg); 
+ 
+#if TARGET_LONG_BITS == 32
+    /* if VM is of 32-bit arch, clear higher 32-bit of addr */
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SLL, r0);                                // sll r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SRL, r0);                                // srl r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r1, 32, ARITH_SLL, r1);                                // sll r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r1, 32, ARITH_SRL, r1);                                // srl r0, 32, r0
+#endif
+
+    tgen_arithi(s, ALPHA_LOGIC, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));    // and r0, #b, r0 
+
+    //
+    // after above insn, we got the page # stored in r0.  note that if VM addr space is 32 bits,
+    // then the higher 32 bits of r0 should be 0
+    //
+    //      32 31                         12 11                 1 0
+    // -------------------------------------------------------------
+    //  ...00 |             page#           |    ...0000...     |xx|
+    // -------------------------------------------------------------
+    //
+
+    // 
+    // the following 2 host insns are tricky. note that TLB has 256 entries,
+    // and entry is (1<<CPU_TLB_ENTRY_BITS) bytes aligned. to check
+    // whether an address is cached in TLB, we may (1) get the page# 
+    // from the address; (2) mask page# by 0xff, i.e., the simplest hash
+    // algorithm, to get TLB entry index; (3) shift the result CPU_TLB_ENTRY_BITS
+    // bits left to get the entry offset in TLB; (4) compare page# calculated
+    // in step (1) with the page# stored in TLB entry, if match, we can tell
+    // that the address is cached. take i386 as example, the CPU_TLB_ENTRY_BITS
+    // is 4, TARGET_PAGE_BITS is 12, so the original address has the folloing
+    // layout.
+    //
+    //      32 31                         12 11            4  3   0
+    // -------------------------------------------------------------
+    //  ...00 |             page#           |                |     |
+    // -------------------------------------------------------------
+    //
+
+    tgen_arithi(s, ALPHA_SHIFT, ARITH_SRL, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);    // srl r1, #b, r1
+
+    //
+    // after above insn, the addres has following layout:
+    //
+    //      32 31                          12  11          4  3   0
+    // -------------------------------------------------------------
+    //  ...00 |     0000...  |            page#              |     |
+    // -------------------------------------------------------------
+    //
+    
+    tgen_arithi(s, ALPHA_LOGIC, ARITH_AND, r1, (CPU_TLB_SIZE-1) << CPU_TLB_ENTRY_BITS);    // and r1, #b, r1
+
+    // after above insn, the addres has following layout:
+    //
+    //      32 31                        12  11            4  3    0
+    // --------------------------------------------------------------
+    //  ...00 |            00000           |   page# & 0xff  | 0000 |
+    // --------------------------------------------------------------
+    //                                       |<-  TLB entry offset  ->|
+    //
+
+    tcg_out_addi(s, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_read));            // addq r1, offset, r1
+    tcg_out_inst4(s, ALPHA_ARITH, r1, TCG_REG_15, ARITH_ADDQ, r1);                        // addq r1, $15, r1
+#if TARGET_LONG_BITS == 32
+    tcg_out_inst3_disp(s, ALPHA_LDL, TMP_REG, r1, 0);                                    // ldl TMP_REG, 0(r1)
+    tcg_out_inst4i(s, ALPHA_SHIFT, TMP_REG, 32, ARITH_SLL, TMP_REG);                    // sll TMP_REG, 32, TMP_REG
+    tcg_out_inst4i(s, ALPHA_SHIFT, TMP_REG, 32, ARITH_SRL, TMP_REG);                    // srl TMP_REG, 32, TMP_REG
+#else
+    tcg_out_inst3_disp(s, ALPHA_LDQ, TMP_REG, r1, 0);                                    // ldq TMP_REG, 0(r1)
+#endif
+         
+    //
+    // now, r0 contains the page# and TMP_REG contains the addr to tlb_entry.addr_read
+    // we below will compare them
+    //
+    tcg_out_inst4(s, ALPHA_ARITH, TMP_REG, r0, ARITH_CMPEQ, TMP_REG);                    // cmpeq TMP_REG, r0, TMP_REG
+
+    tcg_out_mov(s, r0, addr_reg); 
+#if TARGET_LONG_BITS == 32
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SLL, r0);                                // sll r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SRL, r0);                                // srl r0, 32, r0
+#endif
+
+    //
+    // if equal, we jump to label1. since label1 is not resolved yet, 
+    // we just record a relocation.
+    //
+    label1_ptr = s->code_ptr;
+    s->code_ptr += 4;
+
+    //
+    // here, unequal, TLB-miss.
+    //
+    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_17, mem_index);                            // pass argument 2
+    tcg_out_movi(s, TCG_TYPE_I64, \
+        TMP_REG, (tcg_target_long)qemu_ld_helpers[s_bits]);                                // get helper func entry
+    tcg_out_push(s, TCG_REG_26);
+tcg_out_mov(s, TCG_REG_27, TMP_REG);
+    tcg_out_inst3_func(s, CONTROL_CALL, TCG_REG_26, TMP_REG, FUNC_CALL, 0);                // call helper func
+    tcg_out_pop(s, TCG_REG_26);
+     
+    //
+    // after helper function call, the result of ld is saved in $0
+    //
+    switch(opc) {
+    case 0 | 4:
+        tcg_out_inst4(s, ALPHA_SEXT, TCG_REG_31, TCG_REG_0, ARITH_SEXTB, data_reg);        // sextb $31, $0, data_reg
+        break;
+    case 1 | 4:
+        tcg_out_inst4(s, ALPHA_SEXT, TCG_REG_31, TCG_REG_0, ARITH_SEXTW, data_reg);        // sextw $31, $0, data_reg
+        break;
+    case 2 | 4:
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 32, ARITH_SLL, TCG_REG_0);            // sll $0, 32, $0
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 32, ARITH_SRA, data_reg);                // sra $0, 32, data_reg
+        break;
+    case 0:
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 56, ARITH_SLL, TCG_REG_0);            // sll $0, 56, $0
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 56, ARITH_SRL, data_reg);                // srl $0, 56, data_reg
+        break;
+    case 1:
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 48, ARITH_SLL, TCG_REG_0);            // sll $0, 48, $0
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 48, ARITH_SRL, data_reg);                // srl $0, 48, data_reg
+        break;
+    case 2:
+    default:
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 32, ARITH_SLL, TCG_REG_0);            // sll $0, 32, $0
+        tcg_out_inst4i(s, ALPHA_SHIFT, TCG_REG_0, 32, ARITH_SRL, data_reg);                // srl $0, 32, data_reg
+        break;
+    case 3:
+        tcg_out_mov(s, data_reg, TCG_REG_0);
+        break;
+    }
+
+    //
+    // we have done, jmp to label2. label2 is not resolved yet, 
+    // we record a relocation.
+    //
+    label2_ptr = s->code_ptr;
+    s->code_ptr += 4;
+    
+    // patch jmp to label1
+    *(uint32_t *)label1_ptr = (uint32_t) \
+        ( ( CONTROL_BNE << 26 ) | ( TMP_REG << 21 ) \
+        | ( ((s->code_ptr-label1_ptr-4)>>2) & 0x1fffff) );                                // beq TMP_REG, disp 
+
+    //
+    // if we get here, a TLB entry is hit, r0 contains the guest addr and 
+    // r1 contains the ptr that point to tlb_entry.addr_read. what we should
+    // do is to load the tlb_entry.addend (64-bit on alpha) and add it to 
+    // r0 to get the host VA
+    //
+    tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, \
+        offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read));                // TMP_REG <- distance btw addent and addr_read
+    tcg_out_inst4(s, ALPHA_ARITH, r1, TMP_REG, ARITH_ADDQ, r1);                            // addq r1, TMP_REG, r1
+    tcg_out_inst3_disp(s, ALPHA_LDQ, TMP_REG, r1,  0);                                    // ldq TMP_REG, r1, 0
+    tcg_out_inst4(s, ALPHA_ARITH, r0, TMP_REG, ARITH_ADDQ, r0);                            // addq r0, TMP_REG, r0
+     
+#else
+    r0 = addr_reg;
+#endif // endif defined(CONFIG_SOFTMMU)
+
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    bswap = 1;
+#else
+    bswap = 0;
+#endif
+
+    if ( bswap) {
+        tcg_abort();
+    }
+
+    //
+    // when we get here, r0 contains the host VA that can be used to access guest PA
+    //
+    switch(opc) {
+    case 0:
+        tcg_out_inst3_disp(s, ALPHA_LDBU, data_reg, r0, 0);                                // ldbu data_reg, 0(r0)
+        break;
+    case 0 | 4:
+        tcg_out_inst3_disp(s, ALPHA_LDBU, data_reg, r0, 0);                                // ldbu data_reg, 0(r0)
+        tcg_out_inst4(s, ALPHA_SEXT, TCG_REG_31, data_reg, ARITH_SEXTB, data_reg);        // sextb $31, data_reg, data_reg
+        break;
+    case 1:
+        tcg_out_inst3_disp(s, ALPHA_LDWU, data_reg, r0, 0);                                // ldwu data_reg, 0(r0)
+        break;
+    case 1 | 4:
+        tcg_out_inst3_disp(s, ALPHA_LDWU, data_reg, r0, 0);                                // ldwu data_reg, 0(r0)
+        tcg_out_inst4(s, ALPHA_SEXT, TCG_REG_31, data_reg, ARITH_SEXTW, data_reg);        // sextw $31, data_reg, data_reg
+        break;
+    case 2:
+        tcg_out_inst3_disp(s, ALPHA_LDL, data_reg, r0, 0);                                // ldl data_reg, 0(r0)
+        tcg_out_inst4i(s, ALPHA_SHIFT, data_reg, 32, ARITH_SLL, data_reg);                // sll data_reg, 32, data_reg
+        tcg_out_inst4i(s, ALPHA_SHIFT, data_reg, 32, ARITH_SRL, data_reg);                // srl data_reg, 32, data_reg
+        break;
+    case 2 | 4:
+        tcg_out_inst3_disp(s, ALPHA_LDL, data_reg, r0, 0);                                // ldl data_reg, 0(r0)
+        break;
+    case 3:
+        tcg_out_inst3_disp(s, ALPHA_LDQ, data_reg, r0, 0);                                // ldq data_reg, 0(r0)
+        break;
+    default:
+        tcg_abort();
+    }
+
+#if defined(CONFIG_SOFTMMU)
+    /* label2: */
+    *(uint32_t *)label2_ptr = (uint32_t)( ( CONTROL_BR << 26 ) \
+               | ( TCG_REG_31  << 21 ) | 
+               ( ((s->code_ptr-label2_ptr-4)>>2) & 0x1fffff) );
+#endif
+}
+
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+{
+    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap;
+#if defined(CONFIG_SOFTMMU)
+    uint8_t *label1_ptr, *label2_ptr;
+#endif
+
+    data_reg = *args++;
+    addr_reg = *args++;
+    mem_index = *args;
+    s_bits = opc&3;
+
+    r0 = TCG_REG_16;
+    r1 = TCG_REG_17;
+
+#if defined(CONFIG_SOFTMMU)
+
+    tcg_out_mov(s, r1, addr_reg); 
+    tcg_out_mov(s, r0, addr_reg); 
+ 
+#if TARGET_LONG_BITS == 32
+    /* if VM is of 32-bit arch, clear higher 32-bit of addr */
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SLL, r0);                                // sll r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SRL, r0);                                // srl r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r1, 32, ARITH_SLL, r1);                                // sll r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r1, 32, ARITH_SRL, r1);                                // srl r0, 32, r0
+#endif
+
+    tgen_arithi(s, ALPHA_LOGIC, ARITH_AND, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));    // and r0, #b, r0
+
+    tgen_arithi(s, ALPHA_SHIFT, ARITH_SRL, r1, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);    // srl r1, #b, r1    
+    tgen_arithi(s, ALPHA_LOGIC, ARITH_AND, r1, (CPU_TLB_SIZE-1) << CPU_TLB_ENTRY_BITS);    // and r1, #b, r1
+
+    tcg_out_addi(s, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_write));        // addq r1, offset, r1
+    tcg_out_inst4(s, ALPHA_ARITH, r1, TCG_REG_15, ARITH_ADDQ, r1);                        // addq r1, $15, r1
+
+#if TARGET_LONG_BITS == 32
+    tcg_out_inst3_disp(s, ALPHA_LDL, TMP_REG, r1, 0);                                    // ldl TMP_REG, 0(r1)
+    tcg_out_inst4i(s, ALPHA_SHIFT, TMP_REG, 32, ARITH_SLL, TMP_REG);                    // sll TMP_REG, 32, TMP_REG
+    tcg_out_inst4i(s, ALPHA_SHIFT, TMP_REG, 32, ARITH_SRL, TMP_REG);                    // srl TMP_REG, 32, TMP_REG
+#else
+    tcg_out_inst3_disp(s, ALPHA_LDQ, TMP_REG, r1, 0);                                    // ldq TMP_REG, 0(r1)
+#endif
+
+    //
+    // now, r0 contains the page# and TMP_REG contains the addr to tlb_entry.addr_read
+    // we below will compare them
+    //    
+    tcg_out_inst4(s, ALPHA_ARITH, TMP_REG, r0, ARITH_CMPEQ, TMP_REG);                    // cmpeq TMP_REG, r0, TMP_REG
+
+    tcg_out_mov(s, r0, addr_reg); 
+#if TARGET_LONG_BITS == 32
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SLL, r0);                                // sll r0, 32, r0
+    tcg_out_inst4i(s, ALPHA_SHIFT, r0, 32, ARITH_SRL, r0);                                // srl r0, 32, r0
+#endif
+
+    //
+    // if equal, we jump to label1. since label1 is not resolved yet, 
+    // we just record a relocation.
+    //
+    label1_ptr = s->code_ptr;
+    s->code_ptr += 4;
+
+    // here, unequal, TLB-miss, ...
+    tcg_out_mov(s, TCG_REG_17, data_reg);                                                // pass argument 2
+    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_18, mem_index);                            // pass argument 3
+    tcg_out_movi(s, TCG_TYPE_I64, \
+        TMP_REG, (tcg_target_long)qemu_st_helpers[s_bits]);                                // get helper func entry
+    tcg_out_push(s, TCG_REG_26);
+tcg_out_mov(s, TCG_REG_27,TMP_REG);
+    tcg_out_inst3_func(s, CONTROL_CALL, TCG_REG_26, TMP_REG, FUNC_CALL, 0);                // call helper func
+    tcg_out_pop(s, TCG_REG_26);
+
+    //
+    // we have done, jmp to label2. label2 is not resolved yet, 
+    // we record a relocation.
+    //
+    label2_ptr = s->code_ptr;
+    s->code_ptr += 4;
+    
+    // patch jmp to label1
+    *(uint32_t *)label1_ptr = (uint32_t) \
+        ( ( CONTROL_BNE << 26) | ( TMP_REG  << 21 )
+        | ( ((s->code_ptr-label1_ptr-4)>>2) & 0x1fffff) );                                // bne TMP_REG, disp 
+
+    //
+    // if we get here, a TLB entry is hit, r0 contains the guest addr and 
+    // r1 contains the ptr that point to tlb_entry.addr_read. what we should
+    // do is to load the tlb_entry.addend (64-bit on alpha) and add it to 
+    // r0 to get the host VA
+    //
+    tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, \
+        offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write));                // TMP_REG <- distance btw addent and addr_write
+    tcg_out_inst4(s, ALPHA_ARITH, r1, TMP_REG, ARITH_ADDQ, r1);                            // addq r1, TMP_REG, r1
+    tcg_out_inst3_disp(s, ALPHA_LDQ, TMP_REG, r1,  0);                                    // ldq TMP_REG, r1, 0
+    tcg_out_inst4(s, ALPHA_ARITH, r0, TMP_REG, ARITH_ADDQ, r0);                            // addq r0, TMP_REG, r0
+
+#else
+    r0 = addr_reg;
+#endif
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    bswap = 1;
+#else
+    bswap = 0;
+#endif
+
+    if ( bswap) {
+        tcg_abort();
+    }
+
+    //
+    // when we get here, r0 contains the host VA that can be used to access guest PA
+    //
+    switch(opc) {
+    case 0:
+        tcg_out_inst3_disp(s, ALPHA_STB, data_reg, r0, 0);                                // stb data_reg, 0(r0)
+        break;
+    case 1:
+        tcg_out_inst3_disp(s, ALPHA_STW, data_reg, r0, 0);                                // stw data_reg, 0(r0)
+        break;
+    case 2:
+        tcg_out_inst3_disp(s, ALPHA_STL, data_reg, r0, 0);                                // stl data_reg, 0(r0)
+        break;
+    case 3:
+        tcg_out_inst3_disp(s, ALPHA_STQ, data_reg, r0, 0);                                // stq data_reg, 0(r0)
+        break;
+    default:
+        tcg_abort();
+    }
+
+#if defined(CONFIG_SOFTMMU)
+    /* label2: */
+    *(uint32_t *)label2_ptr = (uint32_t)( ( CONTROL_BR << 26 ) \
+        | ( TCG_REG_31  << 21 ) | ( ((s->code_ptr-label2_ptr-4)>>2) & 0x1fffff));
+#endif
+}
+
+static inline void tgen_ldxx( TCGContext *s, int Ra, int Rb, tcg_target_long disp, int flags)
+{
+    int opc_array[4] = { ALPHA_LDBU, ALPHA_LDWU, ALPHA_LDL, ALPHA_LDQ};
+    int opc = opc_array[flags & 3];
+
+    if( disp != (int16_t)disp ) {
+        /* disp cannot be stored in insn directly */
+        tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, disp);     
+        tcg_out_inst4(s, ALPHA_ARITH, Rb, TMP_REG, ARITH_ADDQ, TMP_REG);                    // addq r, TMP_REG, TMP_REG
+        tcg_out_inst3_disp(s, opc, Ra, TMP_REG, 0);                                    // ldx ret, 0(TMP_REG)
+    } else {
+        tcg_out_inst3_disp(s, opc, Ra, Rb, disp);                                        // ldx ret, disp(r)
+    }
+
+    switch ( flags & 7)    {
+    case 0:
+    case 1:
+    case 2|4:
+    case 3:
+        break;
+    case 0|4:
+        tcg_out_inst4(s, ALPHA_SEXT, TCG_REG_31, Ra, ARITH_SEXTB, Ra);                // sextb $31, ra, ra
+        break;
+    case 1|4:
+        tcg_out_inst4(s, ALPHA_SEXT, TCG_REG_31, Ra, ARITH_SEXTW, Ra);                // sextw $31, ra, ra
+        break;
+    case 2:
+        tcg_out_inst4i(s, ALPHA_SHIFT, Ra, 32, ARITH_SLL, Ra);                        // sll ret, 32, ret
+        tcg_out_inst4i(s, ALPHA_SHIFT, Ra, 32, ARITH_SRL, Ra);                        // srl ret, 32, ret
+        break;
+    default:
+        tcg_abort();
+    }
+}
+
+static inline void tgen_stxx( TCGContext *s, int Ra, int Rb, tcg_target_long disp, int flags)
+{
+    int opc_array[4] = { ALPHA_STB, ALPHA_STW, ALPHA_STL, ALPHA_STQ};
+    int opc = opc_array[flags & 3];
+
+    if( disp != (int16_t)disp ) {
+        /* disp cannot be stored in insn directly */
+        tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, disp);
+        tcg_out_inst4(s, ALPHA_ARITH, Rb, TMP_REG, ARITH_ADDQ, TMP_REG);            // addq Rb, TMP_REG, TMP_REG
+        tcg_out_inst3_disp(s, opc, Ra, TMP_REG, 0);                                // stx Ra, 0(TMP_REG)
+    } else {
+        tcg_out_inst3_disp(s, opc, Ra, Rb, disp);                                // stx Ra, disp(Rb)
+    }
+}
+
+static inline void tcg_out_op(TCGContext *s, \
+    int opc, const TCGArg *args, const int *const_args)
+{
+    int oc, c;
+    switch(opc) 
+    {
+    case INDEX_op_exit_tb:
+        /*
+         * exit_tb t0, where t0 is always constant and should be returned to engine 
+         * since we'll back to engine soon, $0 and $1 will never be used
+        */
+        tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_0, args[0]);
+        tcg_out_movi(s, TCG_TYPE_I64, TMP_REG, (tcg_target_long)tb_ret_addr);
+        tcg_out_inst3_func(s, CONTROL_JMP, TCG_REG_31, TMP_REG, FUNC_JMP, 0);            // jmp $31, TMP_REG, hint
+        break;
+
+    case INDEX_op_goto_tb:
+        /* goto_tb idx, where idx is constant 0 or 1, indicating the branch # */
+        if (s->tb_jmp_offset) {
+            /* we don't support direct jmp */
+            tcg_abort();
+        } else {
+            /* indirect jump method */
+        tcg_out_movi( s, TCG_TYPE_I64, TMP_REG, (tcg_target_long)(s->tb_next + args[0]));
+        tcg_out_ld( s, TCG_TYPE_I64, TMP_REG, TMP_REG, 0);
+        tcg_out_inst3_func(s, CONTROL_JMP, TCG_REG_31, TMP_REG, FUNC_JMP, 0);        // jmp $31, TMP_REG, hint
+        }
+        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+        break;
+
+    case INDEX_op_call:
+        /* call <ret> <params> ptr, where ptr has be stored in args[0] */
+        if (const_args[0]) {
+            tcg_abort();
+        } else {
+            tcg_out_push( s, TCG_REG_26);
+            tcg_out_mov( s, TCG_REG_27, args[0]);
+            tcg_out_inst3_func(s, CONTROL_CALL, TCG_REG_26, args[0], FUNC_CALL, 0);
+            tcg_out_pop( s, TCG_REG_26);
+        }
+        break;
+
+    case INDEX_op_jmp: 
+        /* jmp t0, where t0 gives the target address */
+        if (const_args[0]) {
+            tcg_abort();
+        } else {
+            tcg_out_inst3_func(s, CONTROL_JMP, TCG_REG_31, args[0], FUNC_JMP, 0);
+        }
+        break;
+
+    case INDEX_op_br: 
+        /* br idx, where idx gives the label index */
+        tcg_out_jxx(s, CONTROL_BR, TMP_REG, args[0]);
+        break;
+
+    case INDEX_op_mov_i32: 
+    case INDEX_op_mov_i64:
+        /* mov_i32/i64 t0, t1, implemented in tcg.c:tcg_reg_alloc_mov() */
+        tcg_abort();
+        break;
+
+    case INDEX_op_movi_i32: 
+    case INDEX_op_movi_i64: 
+        /* movi_i32/i64 t0, t1, implemented in tcg.c:tcg_reg_alloc_movi() */
+        tcg_abort();
+        break;
+         
+    case INDEX_op_ld8u_i32: 
+    case INDEX_op_ld8u_i64:
+        /* ld8u_i32/i64 t0, t1, offset */
+        tgen_ldxx( s, args[0], args[1], args[2], 0);
+        break;
+
+    case INDEX_op_ld8s_i32: 
+    case INDEX_op_ld8s_i64: 
+        /* ld8s_i32/i64 t0, t1, offset */
+        tgen_ldxx( s, args[0], args[1], args[2], 0|4);
+        break;
+
+    case INDEX_op_ld16u_i32:
+    case INDEX_op_ld16u_i64:
+        /* ld16u_i32/i64 t0, t1, offset */
+          tgen_ldxx( s, args[0], args[1], args[2], 1);
+        break;
+
+    case INDEX_op_ld16s_i32:
+    case INDEX_op_ld16s_i64: 
+        /* ld16s_i32/i64 t0, t1, offset */
+        tgen_ldxx( s, args[0], args[1], args[2], 1|4);
+        break;
+
+    case INDEX_op_ld32u_i64: 
+        /* ld32u_i64 t0, t1, offset */
+        tgen_ldxx( s, args[0], args[1], args[2], 2);
+        break;
+
+    case INDEX_op_ld_i32: 
+    case INDEX_op_ld32s_i64:
+        /* ld_i32 t0, t1, offset or ld32s_i64 t0, t1, offset */
+        tgen_ldxx( s, args[0], args[1], args[2], 2|4);
+        break;
+
+    case INDEX_op_ld_i64: 
+        /* ld_i32 t0, t1, offset */
+        tgen_ldxx( s, args[0], args[1], args[2], 3);
+        break;
+         
+    case INDEX_op_st8_i32:
+    case INDEX_op_st8_i64: 
+        /* st8_i32/i64 t0, t1, offset */
+        tgen_stxx( s, args[0], args[1], args[2], 0);
+        break;
+
+    case INDEX_op_st16_i32:
+    case INDEX_op_st16_i64: 
+        /* st16_i32/i64 t0, t1, offset */
+        tgen_stxx( s, args[0], args[1], args[2], 1);
+        break;
+
+    case INDEX_op_st_i32:
+    case INDEX_op_st32_i64: 
+        /* st_i32/st32_i64 t0, t1, offset */
+        tgen_stxx( s, args[0], args[1], args[2], 2);
+        break;
+
+    case INDEX_op_st_i64: 
+        /* st_i64 t0, t1, offset */
+        tgen_stxx( s, args[0], args[1], args[2], 3);
+        break;
+
+    case INDEX_op_add_i32: 
+        /* add_i32 t0, t1, t2 */
+        oc = ALPHA_ARITH;
+        c = ARITH_ADDL;
+        goto gen_arith;
+    case INDEX_op_add_i64: 
+        /* add_i64 t0, t1, t2 */
+        oc = ALPHA_ARITH;
+        c = ARITH_ADDQ;
+        goto gen_arith;
+    case INDEX_op_sub_i32: 
+        /* sub_i32 t0, t1, t2 */
+        oc = ALPHA_ARITH;
+        c = ARITH_SUBL;
+        goto gen_arith;
+    case INDEX_op_sub_i64: 
+        /* sub_i84 t0, t1, t2 */
+        oc = ALPHA_ARITH;
+        c = ARITH_SUBQ;
+        goto gen_arith;
+    case INDEX_op_mul_i32: 
+        /* mul_i32 t0, t1, t2 */
+        oc = ALPHA_MUL;
+        c = ARITH_MULL;
+        goto gen_arith;
+    case INDEX_op_mul_i64: 
+        /* mul_i64 t0, t1, t2 */
+        oc = ALPHA_MUL;
+        c = ARITH_MULQ;
+        goto gen_arith;
+    case INDEX_op_and_i32:
+    case INDEX_op_and_i64:
+        /* and_i32/i64 t0, t1, t2 */
+        oc = ALPHA_LOGIC;
+        c = ARITH_AND;
+        goto gen_arith;
+    case INDEX_op_or_i32:
+    case INDEX_op_or_i64: 
+        /* or_i32/i64 t0, t1, t2 */
+        oc = ALPHA_LOGIC;
+        c = ARITH_BIS;
+        goto gen_arith;
+    case INDEX_op_xor_i32:
+    case INDEX_op_xor_i64:
+        /* xor_i32/i64 t0, t1, t2 */
+        oc = ALPHA_LOGIC;
+        c = ARITH_XOR;
+        goto gen_arith;
+    case INDEX_op_shl_i32:
+    case INDEX_op_shl_i64:
+        /* shl_i32/i64 t0, t1, t2 */
+        oc = ALPHA_SHIFT;
+        c = ARITH_SLL;
+        goto gen_arith;
+    case INDEX_op_shr_i32:
+        tcg_out_inst4i(s, ALPHA_SHIFT, args[0], 32, ARITH_SLL, args[0]);
+        tcg_out_inst4i(s, ALPHA_SHIFT, args[0], 32, ARITH_SRL, args[0]);
+    case INDEX_op_shr_i64: 
+        /* shr_i32/i64 t0, t1, t2 */
+        oc = ALPHA_SHIFT;
+        c = ARITH_SRL;
+        goto gen_arith;
+    case INDEX_op_sar_i32:
    
+        tcg_out_inst4i(s, ALPHA_SHIFT, args[0], 32, ARITH_SLL, args[0]);
+        tcg_out_inst4i(s, ALPHA_SHIFT, args[0], 32, ARITH_SRA, args[0]);
+    case INDEX_op_sar_i64:
+        /* sar_i32/i64 t0, t1, t2 */
+        oc = ALPHA_SHIFT;
+        c = ARITH_SRA;
+    gen_arith:
+        if (const_args[2]) {
+            tgen_arithi(s, oc, c, args[0], args[2]);
+        } else {
+            tcg_out_inst4(s, oc, args[0], args[2], c, args[0]);
+        }
+        break;
+
+    case INDEX_op_brcond_i32:
+    case INDEX_op_brcond_i64:
+        /* brcond_i32/i64 t0, t1, cond, label */
+        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
+        break;
+
+    case INDEX_op_qemu_ld8u:
+        tcg_out_qemu_ld(s, args, 0);
+        break;
+    case INDEX_op_qemu_ld8s:
+        tcg_out_qemu_ld(s, args, 0 | 4);
+        break;
+    case INDEX_op_qemu_ld16u:
+        tcg_out_qemu_ld(s, args, 1);
+        break;
+    case INDEX_op_qemu_ld16s:
+        tcg_out_qemu_ld(s, args, 1 | 4);
+        break;
+    case INDEX_op_qemu_ld32u:
+        tcg_out_qemu_ld(s, args, 2);
+        break;
+    case INDEX_op_qemu_ld32s:
+        tcg_out_qemu_ld(s, args, 2 | 4);
+        break;
+    case INDEX_op_qemu_ld64:
+        tcg_out_qemu_ld(s, args, 3);
+        break;
+
+    case INDEX_op_qemu_st8:
+        tcg_out_qemu_st(s, args, 0);
+        break;
+    case INDEX_op_qemu_st16:
+        tcg_out_qemu_st(s, args, 1);
+        break;
+    case INDEX_op_qemu_st32:
+        tcg_out_qemu_st(s, args, 2);
+        break;
+    case INDEX_op_qemu_st64:
+        tcg_out_qemu_st(s, args, 3);
+        break;
+
+    case INDEX_op_div2_i32:
+    case INDEX_op_divu2_i32:
+    default:
+        tcg_abort();
+    }
+
+            tcg_out_inst4(s, ALPHA_LOGIC, 31, 31, ARITH_AND, 31);
+}
+
+static const TCGTargetOpDef alpha_op_defs[] = {
+    { INDEX_op_exit_tb, { } },
+    { INDEX_op_goto_tb, { } },
+    { INDEX_op_call, { "r" } },
+    { INDEX_op_jmp, { "r" } },
+    { INDEX_op_br, { } },
+
+    { INDEX_op_mov_i32, { "r", "r" } },
+    { INDEX_op_movi_i32, { "r" } },
+    { INDEX_op_ld8u_i32, { "r", "r" } },
+    { INDEX_op_ld8s_i32, { "r", "r" } },
+    { INDEX_op_ld16u_i32, { "r", "r" } },
+    { INDEX_op_ld16s_i32, { "r", "r" } },
+    { INDEX_op_ld_i32, { "r", "r" } },
+    { INDEX_op_st8_i32, { "r", "r" } },
+    { INDEX_op_st16_i32, { "r", "r" } },
+    { INDEX_op_st_i32, { "r", "r" } },
+
+    { INDEX_op_add_i32, { "r", "0", "ri" } },
+    { INDEX_op_mul_i32, { "r", "0", "ri" } },
+    //{ INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
+    //{ INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
+    { INDEX_op_sub_i32, { "r", "0", "ri" } },
+    { INDEX_op_and_i32, { "r", "0", "ri" } },
+    { INDEX_op_or_i32, { "r", "0", "ri" } },
+    { INDEX_op_xor_i32, { "r", "0", "ri" } },
+
+    { INDEX_op_shl_i32, { "r", "0", "ri" } },
+    { INDEX_op_shr_i32, { "r", "0", "ri" } },
+    { INDEX_op_sar_i32, { "r", "0", "ri" } },
+
+    { INDEX_op_brcond_i32, { "r", "ri" } },         
+
+    { INDEX_op_mov_i64, { "r", "r" } },     
+    { INDEX_op_movi_i64, { "r" } },
+    { INDEX_op_ld8u_i64, { "r", "r" } },
+    { INDEX_op_ld8s_i64, { "r", "r" } },
+    { INDEX_op_ld16u_i64, { "r", "r" } },
+    { INDEX_op_ld16s_i64, { "r", "r" } },
+    { INDEX_op_ld32u_i64, { "r", "r" } },
+    { INDEX_op_ld32s_i64, { "r", "r" } },
+    { INDEX_op_ld_i64, { "r", "r" } },
+    { INDEX_op_st8_i64, { "r", "r" } },     
+    { INDEX_op_st16_i64, { "r", "r" } },
+    { INDEX_op_st32_i64, { "r", "r" } },
+    { INDEX_op_st_i64, { "r", "r" } },
+
+    { INDEX_op_add_i64, { "r", "0", "ri" } },
+    { INDEX_op_mul_i64, { "r", "0", "ri" } },
+    //{ INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
+    //{ INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
+    { INDEX_op_sub_i64, { "r", "0", "ri" } },
+    { INDEX_op_and_i64, { "r", "0", "ri" } },
+    { INDEX_op_or_i64, { "r", "0", "ri" } },
+    { INDEX_op_xor_i64, { "r", "0", "ri" } },
+
+    { INDEX_op_shl_i64, { "r", "0", "ri" } },
+    { INDEX_op_shr_i64, { "r", "0", "ri" } },
+    { INDEX_op_sar_i64, { "r", "0", "ri" } },
+
+    { INDEX_op_brcond_i64, { "r", "ri" } },
+
+    { INDEX_op_qemu_ld8u, { "r", "L" } },
+    { INDEX_op_qemu_ld8s, { "r", "L" } },
+    { INDEX_op_qemu_ld16u, { "r", "L" } },
+    { INDEX_op_qemu_ld16s, { "r", "L" } },
+    { INDEX_op_qemu_ld32u, { "r", "L" } },
+    { INDEX_op_qemu_ld32s, { "r", "L" } },
+    { INDEX_op_qemu_ld64, { "r", "L" } },
+
+    { INDEX_op_qemu_st8, { "L", "L" } },
+    { INDEX_op_qemu_st16, { "L", "L" } },
+    { INDEX_op_qemu_st32, { "L", "L" } },
+    { INDEX_op_qemu_st64, { "L", "L", "L" } },
+
+    { -1 },
+};
+
+
+static int tcg_target_callee_save_regs[] = {
+    /* TCG_REG_15, */                                // used for the global env, so no need to save
+    TCG_REG_9,
+    TCG_REG_10,
+    TCG_REG_11,
+    TCG_REG_12,
+    TCG_REG_13,
+    TCG_REG_14
+};
+
+/*
+ * Generate global QEMU prologue and epilogue code 
+*/
+void tcg_target_qemu_prologue(TCGContext *s)
+{
+    int i, frame_size, push_size, stack_addend;
+    
+    /* TB prologue */
+/*printf("TB prologue @ %lx\n", s->code_ptr);*/
+     
+    /* save TCG_REG_26 */
+    tcg_out_push(s, TCG_REG_26);
+
+    /* save all callee saved registers */
+    for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+        tcg_out_push(s, tcg_target_callee_save_regs[i]);
+    }
+     
+    /* reserve some stack space */
+    push_size = 8 + (1 + ARRAY_SIZE(tcg_target_callee_save_regs)) * 8;
+    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
+    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & ~(TCG_TARGET_STACK_ALIGN - 1);
+    stack_addend = frame_size - push_size;
+    tcg_out_addi(s, TCG_REG_30, -stack_addend);
+
+    tcg_out_inst3_func(s, CONTROL_JMP, TCG_REG_31, TCG_REG_16, FUNC_JMP, 0);        /* jmp $16 */
+
+    /* TB epilogue */
+    tb_ret_addr = s->code_ptr;
+    tcg_out_addi(s, TCG_REG_30, stack_addend);
+    for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
+        tcg_out_pop(s, tcg_target_callee_save_regs[i]);
+    }
+
+    tcg_out_pop(s, TCG_REG_26);
+    tcg_out_inst3_func(s, CONTROL_RET, TCG_REG_31, TCG_REG_26, FUNC_RET, 0);        /* ret */
+}
+
+
+void tcg_target_init(TCGContext *s)
+{
+    /* fail safe */
+    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
+        tcg_abort();
+
+    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
+    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
+    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
+        (1 << TCG_REG_1  ) | (1 << TCG_REG_2 ) | (1 << TCG_REG_3  ) | (1 << TCG_REG_4 ) |
+        (1 << TCG_REG_5  ) | (1 << TCG_REG_6 ) | (1 << TCG_REG_7  ) | (1 << TCG_REG_8 ) | 
+        (1 << TCG_REG_22) | (1 << TCG_REG_23) | (1 << TCG_REG_24) | (1 << TCG_REG_25) | 
+              (1 << TCG_REG_16) | (1 << TCG_REG_17) | (1 << TCG_REG_18) | (1 << TCG_REG_19) | 
+              (1 << TCG_REG_20) | (1 << TCG_REG_21) | (1 << TCG_REG_0 ));
+    
+    tcg_regset_clear(s->reserved_regs);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_26);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_27);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_28);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_29);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_30);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_31);    // $15, $26~$31 not alloced by tcg.c
+    tcg_regset_set_reg(s->reserved_regs, TMP_REG);        // reserved register for used in this file
+
+    tcg_add_target_add_op_defs(alpha_op_defs);
+    printf("tcg_init called.\n");
+}
+
diff -urN qemu-0.10.0/tcg/alpha/tcg-target.h qemu-0.10.0.alpha/tcg/alpha/tcg-target.h
--- qemu-0.10.0/tcg/alpha/tcg-target.h    1969-12-31 16:00:00.000000000 -0800
+++ qemu-0.10.0.alpha/tcg/alpha/tcg-target.h    2009-10-23 23:09:46.000000000 -0700
@@ -0,0 +1,60 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#define TCG_TARGET_ALPHA 1
+
+#define TCG_TARGET_REG_BITS 64
+
+#define TCG_TARGET_NB_REGS 32
+
+enum {
+    TCG_REG_0 = 0, TCG_REG_1, TCG_REG_2, TCG_REG_3,
+     TCG_REG_4, TCG_REG_5, TCG_REG_6, TCG_REG_7,
+    TCG_REG_8, TCG_REG_9, TCG_REG_10, TCG_REG_11,
+    TCG_REG_12, TCG_REG_13, TCG_REG_14, TCG_REG_15,
+    TCG_REG_16, TCG_REG_17, TCG_REG_18, TCG_REG_19,
+    TCG_REG_20, TCG_REG_21, TCG_REG_22, TCG_REG_23,
+    TCG_REG_24, TCG_REG_25, TCG_REG_26, TCG_REG_27,
+    TCG_REG_28, TCG_REG_29, TCG_REG_30, TCG_REG_31
+};
+
+/* used for function call generation */
+#define TCG_REG_CALL_STACK TCG_REG_30 
+#define TCG_TARGET_STACK_ALIGN 16
+#define TCG_TARGET_CALL_STACK_OFFSET 0
+
+/* Note: must be synced with dyngen-exec.h */
+#define TCG_AREG0 TCG_REG_15
+#define TCG_AREG1 TCG_REG_9
+#define TCG_AREG2 TCG_REG_10
+#define TCG_AREG3 TCG_REG_11
+#define TCG_AREG4 TCG_REG_12
+#define TCG_AREG5 TCG_REG_13
+#define TCG_AREG6 TCG_REG_14
+
+#define TMP_REG TCG_REG_25
+
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+    asm("call_pal 0x86");
+}
