/*
 * MIPS emulation micro-operations templates for floating point reg 
 * load & store for qemu.
 * 
 * Copyright (c) 2006 Marius Groeger
 *
 * 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
 */

#if defined(FREG)

#define OP_WLOAD_FREG(treg, tregname, FREG)              \
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
    {                                                    \
        treg = env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX];    \
        RETURN();                                        \
    }

#define OP_WSTORE_FREG(treg, tregname, FREG)             \
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
    {                                                    \
        env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX] = treg;    \
        RETURN();                                        \
    }

/* WT0 = FREG.w: op_load_fpr_WT0_fprFREG */
OP_WLOAD_FREG(WT0, WT0_fpr, FREG)
/* FREG.w = WT0: op_store_fpr_WT0_fprFREG */
OP_WSTORE_FREG(WT0, WT0_fpr, FREG)

OP_WLOAD_FREG(WT1, WT1_fpr, FREG)
OP_WSTORE_FREG(WT1, WT1_fpr, FREG)

OP_WLOAD_FREG(WT2, WT2_fpr, FREG)
OP_WSTORE_FREG(WT2, WT2_fpr, FREG)

#define OP_DLOAD_FREG(treg, tregname, FREG)              \
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
    {                                                    \
        if (env->hflags & MIPS_HFLAG_F64)                \
            treg = env->fpu->fpr[FREG].fd;               \
        else                                             \
            treg = (uint64_t)(env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
                   env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
        RETURN();                                        \
    }

#define OP_DSTORE_FREG(treg, tregname, FREG)             \
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
    {                                                    \
        if (env->hflags & MIPS_HFLAG_F64)                \
            env->fpu->fpr[FREG].fd = treg;               \
        else {                                           \
            env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
            env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg;      \
        }                                                \
        RETURN();                                        \
    }

OP_DLOAD_FREG(DT0, DT0_fpr, FREG)
OP_DSTORE_FREG(DT0, DT0_fpr, FREG)

OP_DLOAD_FREG(DT1, DT1_fpr, FREG)
OP_DSTORE_FREG(DT1, DT1_fpr, FREG)

OP_DLOAD_FREG(DT2, DT2_fpr, FREG)
OP_DSTORE_FREG(DT2, DT2_fpr, FREG)

#define OP_PSLOAD_FREG(treg, tregname, FREG)             \
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
    {                                                    \
        treg = env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX];   \
        RETURN();                                        \
    }

#define OP_PSSTORE_FREG(treg, tregname, FREG)            \
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
    {                                                    \
        env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg;   \
        RETURN();                                        \
    }

OP_PSLOAD_FREG(WTH0, WTH0_fpr, FREG)
OP_PSSTORE_FREG(WTH0, WTH0_fpr, FREG)

OP_PSLOAD_FREG(WTH1, WTH1_fpr, FREG)
OP_PSSTORE_FREG(WTH1, WTH1_fpr, FREG)

OP_PSLOAD_FREG(WTH2, WTH2_fpr, FREG)
OP_PSSTORE_FREG(WTH2, WTH2_fpr, FREG)

#endif

#if defined (FTN)

#define SET_RESET(treg, tregname)        \
    void glue(op_set, tregname)(void)    \
    {                                    \
        treg = PARAM1;                   \
        RETURN();                        \
    }                                    \
    void glue(op_reset, tregname)(void)  \
    {                                    \
        treg = 0;                        \
        RETURN();                        \
    }

SET_RESET(WT0, _WT0)
SET_RESET(WT1, _WT1)
SET_RESET(WT2, _WT2)
SET_RESET(DT0, _DT0)
SET_RESET(DT1, _DT1)
SET_RESET(DT2, _DT2)
SET_RESET(WTH0, _WTH0)
SET_RESET(WTH1, _WTH1)
SET_RESET(WTH2, _WTH2)

#undef SET_RESET
#endif
