/*
   SPARC translation

   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
   Copyright (C) 2003 Fabrice Bellard

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
   TODO-list:

   NPC/PC static optimisations (use JUMP_TB when possible)
   FPU-Instructions
   Privileged instructions
   Coprocessor-Instructions
   Optimize synthetic instructions
   Optional alignment and privileged instruction check
*/

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "cpu.h"
#include "exec-all.h"
#include "disas.h"

#define DEBUG_DISAS

#define DYNAMIC_PC  1 /* dynamic pc value */
#define JUMP_PC     2 /* dynamic pc value which takes only two values
                         according to jump_pc[T2] */

typedef struct DisasContext {
    target_ulong pc;	/* current Program Counter: integer or DYNAMIC_PC */
    target_ulong npc;	/* next PC: integer or DYNAMIC_PC or JUMP_PC */
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
    int is_br;
    struct TranslationBlock *tb;
} DisasContext;

static uint16_t *gen_opc_ptr;
static uint32_t *gen_opparam_ptr;
extern FILE *logfile;
extern int loglevel;

enum {
#define DEF(s,n,copy_size) INDEX_op_ ## s,
#include "opc.h"
#undef DEF
    NB_OPS
};

#include "gen-op.h"

#define GET_FIELD(X, FROM, TO) \
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))

#define IS_IMM (insn & (1<<13))

static void disas_sparc_insn(DisasContext * dc);

static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
    {
     gen_op_movl_g0_T0,
     gen_op_movl_g1_T0,
     gen_op_movl_g2_T0,
     gen_op_movl_g3_T0,
     gen_op_movl_g4_T0,
     gen_op_movl_g5_T0,
     gen_op_movl_g6_T0,
     gen_op_movl_g7_T0,
     gen_op_movl_o0_T0,
     gen_op_movl_o1_T0,
     gen_op_movl_o2_T0,
     gen_op_movl_o3_T0,
     gen_op_movl_o4_T0,
     gen_op_movl_o5_T0,
     gen_op_movl_o6_T0,
     gen_op_movl_o7_T0,
     gen_op_movl_l0_T0,
     gen_op_movl_l1_T0,
     gen_op_movl_l2_T0,
     gen_op_movl_l3_T0,
     gen_op_movl_l4_T0,
     gen_op_movl_l5_T0,
     gen_op_movl_l6_T0,
     gen_op_movl_l7_T0,
     gen_op_movl_i0_T0,
     gen_op_movl_i1_T0,
     gen_op_movl_i2_T0,
     gen_op_movl_i3_T0,
     gen_op_movl_i4_T0,
     gen_op_movl_i5_T0,
     gen_op_movl_i6_T0,
     gen_op_movl_i7_T0,
     },
    {
     gen_op_movl_g0_T1,
     gen_op_movl_g1_T1,
     gen_op_movl_g2_T1,
     gen_op_movl_g3_T1,
     gen_op_movl_g4_T1,
     gen_op_movl_g5_T1,
     gen_op_movl_g6_T1,
     gen_op_movl_g7_T1,
     gen_op_movl_o0_T1,
     gen_op_movl_o1_T1,
     gen_op_movl_o2_T1,
     gen_op_movl_o3_T1,
     gen_op_movl_o4_T1,
     gen_op_movl_o5_T1,
     gen_op_movl_o6_T1,
     gen_op_movl_o7_T1,
     gen_op_movl_l0_T1,
     gen_op_movl_l1_T1,
     gen_op_movl_l2_T1,
     gen_op_movl_l3_T1,
     gen_op_movl_l4_T1,
     gen_op_movl_l5_T1,
     gen_op_movl_l6_T1,
     gen_op_movl_l7_T1,
     gen_op_movl_i0_T1,
     gen_op_movl_i1_T1,
     gen_op_movl_i2_T1,
     gen_op_movl_i3_T1,
     gen_op_movl_i4_T1,
     gen_op_movl_i5_T1,
     gen_op_movl_i6_T1,
     gen_op_movl_i7_T1,
     }
};

static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
    {
     gen_op_movl_T0_g0,
     gen_op_movl_T0_g1,
     gen_op_movl_T0_g2,
     gen_op_movl_T0_g3,
     gen_op_movl_T0_g4,
     gen_op_movl_T0_g5,
     gen_op_movl_T0_g6,
     gen_op_movl_T0_g7,
     gen_op_movl_T0_o0,
     gen_op_movl_T0_o1,
     gen_op_movl_T0_o2,
     gen_op_movl_T0_o3,
     gen_op_movl_T0_o4,
     gen_op_movl_T0_o5,
     gen_op_movl_T0_o6,
     gen_op_movl_T0_o7,
     gen_op_movl_T0_l0,
     gen_op_movl_T0_l1,
     gen_op_movl_T0_l2,
     gen_op_movl_T0_l3,
     gen_op_movl_T0_l4,
     gen_op_movl_T0_l5,
     gen_op_movl_T0_l6,
     gen_op_movl_T0_l7,
     gen_op_movl_T0_i0,
     gen_op_movl_T0_i1,
     gen_op_movl_T0_i2,
     gen_op_movl_T0_i3,
     gen_op_movl_T0_i4,
     gen_op_movl_T0_i5,
     gen_op_movl_T0_i6,
     gen_op_movl_T0_i7,
     },
    {
     gen_op_movl_T1_g0,
     gen_op_movl_T1_g1,
     gen_op_movl_T1_g2,
     gen_op_movl_T1_g3,
     gen_op_movl_T1_g4,
     gen_op_movl_T1_g5,
     gen_op_movl_T1_g6,
     gen_op_movl_T1_g7,
     gen_op_movl_T1_o0,
     gen_op_movl_T1_o1,
     gen_op_movl_T1_o2,
     gen_op_movl_T1_o3,
     gen_op_movl_T1_o4,
     gen_op_movl_T1_o5,
     gen_op_movl_T1_o6,
     gen_op_movl_T1_o7,
     gen_op_movl_T1_l0,
     gen_op_movl_T1_l1,
     gen_op_movl_T1_l2,
     gen_op_movl_T1_l3,
     gen_op_movl_T1_l4,
     gen_op_movl_T1_l5,
     gen_op_movl_T1_l6,
     gen_op_movl_T1_l7,
     gen_op_movl_T1_i0,
     gen_op_movl_T1_i1,
     gen_op_movl_T1_i2,
     gen_op_movl_T1_i3,
     gen_op_movl_T1_i4,
     gen_op_movl_T1_i5,
     gen_op_movl_T1_i6,
     gen_op_movl_T1_i7,
     },
    {
     gen_op_movl_T2_g0,
     gen_op_movl_T2_g1,
     gen_op_movl_T2_g2,
     gen_op_movl_T2_g3,
     gen_op_movl_T2_g4,
     gen_op_movl_T2_g5,
     gen_op_movl_T2_g6,
     gen_op_movl_T2_g7,
     gen_op_movl_T2_o0,
     gen_op_movl_T2_o1,
     gen_op_movl_T2_o2,
     gen_op_movl_T2_o3,
     gen_op_movl_T2_o4,
     gen_op_movl_T2_o5,
     gen_op_movl_T2_o6,
     gen_op_movl_T2_o7,
     gen_op_movl_T2_l0,
     gen_op_movl_T2_l1,
     gen_op_movl_T2_l2,
     gen_op_movl_T2_l3,
     gen_op_movl_T2_l4,
     gen_op_movl_T2_l5,
     gen_op_movl_T2_l6,
     gen_op_movl_T2_l7,
     gen_op_movl_T2_i0,
     gen_op_movl_T2_i1,
     gen_op_movl_T2_i2,
     gen_op_movl_T2_i3,
     gen_op_movl_T2_i4,
     gen_op_movl_T2_i5,
     gen_op_movl_T2_i6,
     gen_op_movl_T2_i7,
     }
};

static GenOpFunc1 *gen_op_movl_TN_im[3] = {
    gen_op_movl_T0_im,
    gen_op_movl_T1_im,
    gen_op_movl_T2_im
};

static inline void gen_movl_imm_TN(int reg, int imm)
{
    gen_op_movl_TN_im[reg] (imm);
}

static inline void gen_movl_imm_T1(int val)
{
    gen_movl_imm_TN(1, val);
}

static inline void gen_movl_imm_T0(int val)
{
    gen_movl_imm_TN(0, val);
}

static inline void gen_movl_reg_TN(int reg, int t)
{
    if (reg)
	gen_op_movl_reg_TN[t][reg] ();
    else
	gen_movl_imm_TN(t, 0);
}

static inline void gen_movl_reg_T0(int reg)
{
    gen_movl_reg_TN(reg, 0);
}

static inline void gen_movl_reg_T1(int reg)
{
    gen_movl_reg_TN(reg, 1);
}

static inline void gen_movl_reg_T2(int reg)
{
    gen_movl_reg_TN(reg, 2);
}

static inline void gen_movl_TN_reg(int reg, int t)
{
    if (reg)
	gen_op_movl_TN_reg[t][reg] ();
}

static inline void gen_movl_T0_reg(int reg)
{
    gen_movl_TN_reg(reg, 0);
}

static inline void gen_movl_T1_reg(int reg)
{
    gen_movl_TN_reg(reg, 1);
}

/* call this function before using T2 as it may have been set for a jump */
static inline void flush_T2(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
        gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
        dc->npc = DYNAMIC_PC;
    }
}

static inline void save_npc(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
        gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
        gen_op_movl_npc_im(dc->npc);
    }
}

static inline void save_state(DisasContext * dc)
{
    gen_op_jmp_im((uint32_t)dc->pc);
    save_npc(dc);
}

static void gen_cond(int cond)
{
	switch (cond) {
        case 0x0:
            gen_op_movl_T2_0();
            break;
	case 0x1:
	    gen_op_eval_be();
	    break;
	case 0x2:
	    gen_op_eval_ble();
	    break;
	case 0x3:
	    gen_op_eval_bl();
	    break;
	case 0x4:
	    gen_op_eval_bleu();
	    break;
	case 0x5:
	    gen_op_eval_bcs();
	    break;
	case 0x6:
	    gen_op_eval_bneg();
	    break;
	case 0x7:
	    gen_op_eval_bvs();
	    break;
        case 0x8:
            gen_op_movl_T2_1();
            break;
	case 0x9:
	    gen_op_eval_bne();
	    break;
	case 0xa:
	    gen_op_eval_bg();
	    break;
	case 0xb:
	    gen_op_eval_bge();
	    break;
	case 0xc:
	    gen_op_eval_bgu();
	    break;
	case 0xd:
	    gen_op_eval_bcc();
	    break;
	case 0xe:
	    gen_op_eval_bpos();
	    break;
        default:
	case 0xf:
	    gen_op_eval_bvc();
	    break;
	}
}


static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
    target += (uint32_t) dc->pc;
    if (cond == 0x0) {
	/* unconditional not taken */
	if (a) {
	    dc->pc = dc->npc + 4;
	    dc->npc = dc->pc + 4;
	} else {
	    dc->pc = dc->npc;
	    dc->npc = dc->pc + 4;
	}
    } else if (cond == 0x8) {
	/* unconditional taken */
	if (a) {
	    dc->pc = target;
	    dc->npc = dc->pc + 4;
	} else {
	    dc->pc = dc->npc;
	    dc->npc = target;
	}
    } else {
        flush_T2(dc);
        gen_cond(cond);
	if (a) {
	    gen_op_branch_a((long)dc->tb, target, dc->npc);
            dc->is_br = 1;
	} else {
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
	}
    }
}

#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)

static int sign_extend(int x, int len)
{
    len = 32 - len;
    return (x << len) >> len;
}

static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;

    insn = ldl_code((uint8_t *)dc->pc);
    opc = GET_FIELD(insn, 0, 1);

    rd = GET_FIELD(insn, 2, 6);
    switch (opc) {
    case 0:			/* branches/sethi */
	{
	    unsigned int xop = GET_FIELD(insn, 7, 9);
	    int target;
	    target = GET_FIELD(insn, 10, 31);
	    switch (xop) {
	    case 0x0:
	    case 0x1:		/* UNIMPL */
                goto illegal_insn;
	    case 0x2:		/* BN+x */
		{
		    target <<= 2;
		    target = sign_extend(target, 22);
		    do_branch(dc, target, insn);
		    goto jmp_insn;
		}
	    case 0x3:		/* FBN+x */
		break;
	    case 0x4:		/* SETHI */
		gen_movl_imm_T0(target << 10);
		gen_movl_T0_reg(rd);
		break;
	    case 0x5:		/*CBN+x */
		break;
	    }
	    break;
	}
    case 1:
	/*CALL*/ {
	    unsigned int target = GET_FIELDs(insn, 2, 31) << 2;

	    gen_op_movl_T0_im((long) (dc->pc));
	    gen_movl_T0_reg(15);
	    target = dc->pc + target;
	    dc->pc = dc->npc;
	    dc->npc = target;
	}
	goto jmp_insn;
    case 2:			/* FPU & Logical Operations */
	{
	    unsigned int xop = GET_FIELD(insn, 7, 12);
	    if (xop == 0x3a) {	/* generate trap */
                int cond;
                rs1 = GET_FIELD(insn, 13, 17);
                gen_movl_reg_T0(rs1);
		if (IS_IMM) {
                    gen_movl_imm_T1(GET_FIELD(insn, 25, 31));
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
                }
                gen_op_add_T1_T0();
                save_state(dc);
                cond = GET_FIELD(insn, 3, 6);
                if (cond == 0x8) {
                    gen_op_trap_T0();
                    dc->is_br = 1;
                    goto jmp_insn;
                } else {
                    gen_op_trapcc_T0();
                }
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
                    gen_op_rdy();
                    gen_movl_T0_reg(rd);
                    break;
                default:
                    goto illegal_insn;
                }
	    } else if (xop == 0x34 || xop == 0x35) {	/* FPU Operations */
                goto illegal_insn;
	    } else {
                rs1 = GET_FIELD(insn, 13, 17);
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {	/* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
                    gen_movl_imm_T1(rs2);
                } else {		/* register */
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
                }
                if (xop < 0x20) {
                    switch (xop & ~0x10) {
                    case 0x0:
                        if (xop & 0x10)
                            gen_op_add_T1_T0_cc();
                        else
                            gen_op_add_T1_T0();
                        break;
                    case 0x1:
                        gen_op_and_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x2:
                        gen_op_or_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x3:
                        gen_op_xor_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x4:
                        if (xop & 0x10)
                            gen_op_sub_T1_T0_cc();
                        else
                            gen_op_sub_T1_T0();
                        break;
                    case 0x5:
                        gen_op_andn_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x6:
                        gen_op_orn_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x7:
                        gen_op_xnor_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x8:
                        gen_op_addx_T1_T0();
                        if (xop & 0x10)
                            gen_op_set_flags();
                        break;
                    case 0xa:
                        gen_op_umul_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0xb:
                        gen_op_smul_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0xc:
                        gen_op_subx_T1_T0();
                        if (xop & 0x10)
                            gen_op_set_flags();
                        break;
                    case 0xe:
                        gen_op_udiv_T1_T0();
                        if (xop & 0x10)
                            gen_op_div_cc();
                        break;
                    case 0xf:
                        gen_op_sdiv_T1_T0();
                        if (xop & 0x10)
                            gen_op_div_cc();
                        break;
                    default:
                        goto illegal_insn;
                    }
                    gen_movl_T0_reg(rd);
                } else {
                    switch (xop) {
                    case 0x24: /* mulscc */
                        gen_op_mulscc_T1_T0();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x25:	/* SLL */
                        gen_op_sll();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x26:
                        gen_op_srl();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x27:
                        gen_op_sra();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x30:
                        {
                            gen_op_xor_T1_T0();
                            switch(rd) {
                            case 0:
                                gen_op_wry();
                                break;
                            default:
                                goto illegal_insn;
                            }
                        }
                        break;
                    case 0x38:	/* jmpl */
                        {
                            gen_op_add_T1_T0();
                            gen_op_movl_npc_T0();
                            if (rd != 0) {
                                gen_op_movl_T0_im((long) (dc->pc));
                                gen_movl_T0_reg(rd);
                            }
                            dc->pc = dc->npc;
                            dc->npc = DYNAMIC_PC;
                        }
                        goto jmp_insn;
                    case 0x3b: /* flush */
                        gen_op_add_T1_T0();
                        gen_op_flush_T0();
                        break;
                    case 0x3c:	/* save */
                        save_state(dc);
                        gen_op_add_T1_T0();
                        gen_op_save();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x3d:	/* restore */
                        save_state(dc);
                        gen_op_add_T1_T0();
                        gen_op_restore();
                        gen_movl_T0_reg(rd);
                        break;
                    default:
                        goto illegal_insn;
                    }
                }
            }
	    break;
	}
    case 3:			/* load/store instructions */
	{
	    unsigned int xop = GET_FIELD(insn, 7, 12);
	    rs1 = GET_FIELD(insn, 13, 17);
	    gen_movl_reg_T0(rs1);
	    if (IS_IMM) {	/* immediate */
		rs2 = GET_FIELDs(insn, 19, 31);
		gen_movl_imm_T1(rs2);
	    } else {		/* register */
		rs2 = GET_FIELD(insn, 27, 31);
		gen_movl_reg_T1(rs2);
	    }
	    gen_op_add_T1_T0();
	    if (xop < 4 || xop > 7) {
		switch (xop) {
		case 0x0:	/* load word */
		    gen_op_ld();
		    break;
		case 0x1:	/* load unsigned byte */
		    gen_op_ldub();
		    break;
		case 0x2:	/* load unsigned halfword */
		    gen_op_lduh();
		    break;
		case 0x3:	/* load double word */
		    gen_op_ldd();
		    gen_movl_T0_reg(rd + 1);
		    break;
		case 0x9:	/* load signed byte */
		    gen_op_ldsb();
		    break;
		case 0xa:	/* load signed halfword */
		    gen_op_ldsh();
		    break;
		case 0xd:	/* ldstub -- XXX: should be atomically */
		    gen_op_ldstub();
		    break;
		case 0x0f:	/* swap register with memory. Also atomically */
		    gen_op_swap();
		    break;
		}
		gen_movl_T1_reg(rd);
	    } else if (xop < 8) {
		gen_movl_reg_T1(rd);
		switch (xop) {
		case 0x4:
		    gen_op_st();
		    break;
		case 0x5:
		    gen_op_stb();
		    break;
		case 0x6:
		    gen_op_sth();
		    break;
		case 0x7:
                    flush_T2(dc);
		    gen_movl_reg_T2(rd + 1);
		    gen_op_std();
		    break;
		}
	    }
	}
    }
    /* default case for non jump instructions */
    if (dc->npc == DYNAMIC_PC) {
	dc->pc = DYNAMIC_PC;
	gen_op_next_insn();
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
        gen_op_branch2((long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
        dc->is_br = 1;
    } else {
	dc->pc = dc->npc;
	dc->npc = dc->npc + 4;
    }
  jmp_insn:;
    return;
 illegal_insn:
    save_state(dc);
    gen_op_exception(TT_ILL_INSN);
    dc->is_br = 1;
}

static inline int gen_intermediate_code_internal(TranslationBlock * tb,
						 int spc)
{
    target_ulong pc_start, last_pc;
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;

    memset(dc, 0, sizeof(DisasContext));
    if (spc) {
	printf("SearchPC not yet supported\n");
	exit(0);
    }
    dc->tb = tb;
    pc_start = tb->pc;
    dc->pc = pc_start;
    dc->npc = (target_ulong) tb->cs_base;

    gen_opc_ptr = gen_opc_buf;
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
    gen_opparam_ptr = gen_opparam_buf;

    do {
	last_pc = dc->pc;
	disas_sparc_insn(dc);
	if (dc->is_br)
	    break;
	/* if the next PC is different, we abort now */
	if (dc->pc != (last_pc + 4))
	    break;
    } while ((gen_opc_ptr < gen_opc_end) &&
	     (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
    if (!dc->is_br) {
        if (dc->pc != DYNAMIC_PC && 
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
            gen_op_branch((long)tb, dc->pc, dc->npc);
        } else {
            if (dc->pc != DYNAMIC_PC)
                gen_op_jmp_im(dc->pc);
            save_npc(dc);
            gen_op_movl_T0_0();
            gen_op_exit_tb();
        }
    }
    *gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
    if (loglevel & CPU_LOG_TB_IN_ASM) {
	fprintf(logfile, "--------------\n");
	fprintf(logfile, "IN: %s\n", lookup_symbol((uint8_t *)pc_start));
	disas(logfile, (uint8_t *)pc_start, last_pc + 4 - pc_start, 0, 0);
	fprintf(logfile, "\n");
        if (loglevel & CPU_LOG_TB_OP) {
            fprintf(logfile, "OP:\n");
            dump_ops(gen_opc_buf, gen_opparam_buf);
            fprintf(logfile, "\n");
        }
    }
#endif

    return 0;
}

int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
{
    return gen_intermediate_code_internal(tb, 0);
}

int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
{
    return gen_intermediate_code_internal(tb, 1);
}

CPUSPARCState *cpu_sparc_init(void)
{
    CPUSPARCState *env;

    cpu_exec_init();

    if (!(env = malloc(sizeof(CPUSPARCState))))
	return (NULL);
    memset(env, 0, sizeof(*env));
    env->cwp = 0;
    env->wim = 1;
    env->regwptr = env->regbase + (env->cwp * 16);
    env->user_mode_only = 1;
    cpu_single_env = env;
    return (env);
}

#define GET_FLAG(a,b) ((env->psr & a)?b:'-')

void cpu_sparc_dump_state(CPUSPARCState * env, FILE * f, int flags)
{
    int i, x;

    fprintf(f, "pc: 0x%08x  npc: 0x%08x\n", (int) env->pc, (int) env->npc);
    fprintf(f, "General Registers:\n");
    for (i = 0; i < 4; i++)
	fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
    fprintf(f, "\n");
    for (; i < 8; i++)
	fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
    fprintf(f, "\nCurrent Register Window:\n");
    for (x = 0; x < 3; x++) {
	for (i = 0; i < 4; i++)
	    fprintf(f, "%%%c%d: 0x%08x\t",
		    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
		    env->regwptr[i + x * 8]);
	fprintf(f, "\n");
	for (; i < 8; i++)
	    fprintf(f, "%%%c%d: 0x%08x\t",
		    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
		    env->regwptr[i + x * 8]);
	fprintf(f, "\n");
    }
    fprintf(f, "psr: 0x%08x -> %c%c%c%c wim: 0x%08x\n", env->psr | env->cwp,
	    GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
	    GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
            env->wim);
}

target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
{
    return addr;
}

void helper_flush(target_ulong addr)
{
    addr &= ~7;
    tb_invalidate_page_range(addr, addr + 8);
}
