/* $Id: xpseudo_asm_gcc.h,v 1.1 2002/09/16 21:19:30 prabhu Exp $ */
/******************************************************************************
*
*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*       FOR A PARTICULAR PURPOSE.
*
*       (c) Copyright 2002 Xilinx Inc.
*       All rights reserved.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xpseudo_asm_gcc.h
*
* This header file contains macros for using inline assembler code. It is
* written specifically for the GNU compiler.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ch   06/18/02 First release
* </pre>
*
******************************************************************************/

#ifndef XPSEUDO_ASM_H  /* prevent circular inclusions */
#define XPSEUDO_ASM_H  /* by using protection macros */

/***************************** Include Files ********************************/

#include <ppc-asm.h>
#include "xreg405.h"
#define r2 2
#define r1 1

/************************** Constant Definitions ****************************/

/**************************** Type Definitions ******************************/

/***************** Macros (Inline Functions) Definitions ********************/

/* necessary for pre-processor */
#define stringify(s)    tostring(s)
#define tostring(s)     #s

/* pseudo assembler instructions */
#define mtgpr(rn, v)    __asm__ __volatile__(\
                          "mr " stringify(rn) ",%0\n"\
                          : : "r" (v)\
                        )

#define mfgpr(rn)       ({unsigned int rval; \
                          __asm__ __volatile__(\
                            "mr %0," stringify(rn) "\n"\
                            : "=r" (rval)\
                          );\
                          rval;\
                        })

#define mtspr(rn, v)    __asm__ __volatile__(\
                          "mtspr " stringify(rn) ",%0\n"\
                          : : "r" (v)\
                        )

#define mfspr(rn)       ({unsigned int rval; \
                          __asm__ __volatile__(\
                            "mfspr %0," stringify(rn) "\n"\
                            : "=r" (rval)\
                          );\
                          rval;\
                        })

#define mtdcr(rn, v)    __asm__ __volatile__(\
                          "mtdcr " stringify(rn) ",%0\n"\
                          : : "r" (v)\
                        )

#define mfdcr(rn)       ({unsigned int rval; \
                          __asm__ __volatile__(\
                            "mfdcr %0," stringify(rn) "\n"\
                            : "=r" (rval)\
                          );\
                          rval;\
                        })

#define mtmsr(v)        __asm__ __volatile__(\
                          "mtmsr %0\n"\
                          : : "r" (v)\
                        )

#define mfmsr()         ({unsigned int rval; \
                          __asm__ __volatile__(\
                            "mfmsr %0\n"\
                            : "=r" (rval)\
                          );\
                          rval;\
                        })

#define mtevpr(adr)     mtspr(XREG_SPR_EVPR, (adr))


#define iccci           __asm__ __volatile__("iccci 0,0\n")
#define isync           __asm__ __volatile__("isync\n")
#define icbi(adr)       __asm__ __volatile__("icbi  0,%0\n" : : "r" (adr))

#define dccci(adr)      __asm__ __volatile__("dccci 0,%0\n" : : "r" (adr))
#define dcbst(adr)      __asm__ __volatile__("dcbst 0,%0\n" : : "r" (adr))
#define dcbf(adr)       __asm__ __volatile__("dcbf  0,%0\n" : : "r" (adr))

#define dcread(adr)     ({register unsigned int rval; \
                          __asm__ __volatile__("\
                            dcread %0,0,%1\n"\
                            : "=r" (rval) : "r" (adr)\
                          );\
                          rval;\
                        }) 

#define sync            __asm__ __volatile__("sync\n")

/* memory operations */
#define eieio           __asm__ __volatile__("eieio\n")
#define lbz(adr)        ({unsigned char rval; \
                          __asm__ __volatile__(\
                            "lbz %0,0(%1)\n"\
                            : "=r" (rval) : "b" (adr)\
                          );\
                          rval;\
                        })

#define lhz(adr)        ({unsigned short rval; \
                          __asm__ __volatile__(\
                            "lhz %0,0(%1)\n"\
                            : "=r" (rval) : "b" (adr)\
                          );\
                          rval;\
                        })

#define lwz(adr)        ({unsigned int rval; \
                          __asm__ __volatile__(\
                            "lwz %0,0(%1)\n"\
                            : "=r" (rval) : "b" (adr)\
                          );\
                          rval;\
                        })

#define stb(adr, val)   __asm__ __volatile__(\
                          "stb %0,0(%1)\n"\
                          : : "r" (val), "b" (adr)\
                        )

#define sth(adr, val)   __asm__ __volatile__(\
                          "sth %0,0(%1)\n"\
                          : : "r" (val), "b" (adr)\
                        )

#define stw(adr, val)   __asm__ __volatile__(\
                          "stw %0,0(%1)\n"\
                          : : "r" (val), "b" (adr)\
                        )

#define lhbrx(adr)      ({unsigned short rval; \
                          __asm__ __volatile__(\
                            "lhbrx %0,0,%1\n"\
                            : "=r" (rval) : "r" (adr)\
                          );\
                          rval;\
                        })

#define lwbrx(adr)      ({unsigned int rval; \
                          __asm__ __volatile__(\
                            "lwbrx %0,0,%1\n"\
                            : "=r" (rval) : "r" (adr)\
                          );\
                          rval;\
                        })

#define sthbrx(adr, val)  __asm__ __volatile__(\
                            "sthbrx %0,0,%1\n"\
                            : : "r" (val), "r" (adr)\
                          )

#define stwbrx(adr, val)  __asm__ __volatile__(\
                            "stwbrx %0,0,%1\n"\
                            : : "r" (val), "r" (adr)\
                          )

/************************** Variable Definitions ****************************/

/************************** Function Prototypes *****************************/

#endif
