/*      $NetBSD: _regset.h,v 1.1 2006/04/07 14:21:18 cherry Exp $       */

/*-
* Copyright (c) 2002, 2003 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/

#ifndef _MACHINE_REGSET_H_
#define _MACHINE_REGSET_H_

/*
* Create register sets, based on the runtime specification. This allows
* us to better reuse code and to copy sets around more efficiently.
* Contexts are defined in terms of these sets. These include trapframe,
* sigframe, pcb, mcontext, reg and fpreg. Other candidates are unwind
* and coredump related contexts.
*
* Notes:
* o  Constant registers (r0, f0 and f1) are not accounted for,
* o  The stacked registers (r32-r127) are not accounted for,
* o  Predicates are not split across sets.
*/

/* A single FP register. */
union _ia64_fpreg {
       unsigned char   fpr_bits[16];
       long double     fpr_flt;
};

/*
* Special registers.
*/
struct _special {
       unsigned long           sp;
       unsigned long           unat;           /* NaT before spilling */
       unsigned long           rp;
       unsigned long           pr;
       unsigned long           pfs;
       unsigned long           bspstore;
       unsigned long           rnat;
       unsigned long           __spare;
       /* Userland context and syscalls */
       unsigned long           tp;
       unsigned long           rsc;
       unsigned long           fpsr;
       unsigned long           psr;
       /* ASYNC: Interrupt specific */
       unsigned long           gp;
       unsigned long           ndirty;
       unsigned long           cfm;
       unsigned long           iip;
       unsigned long           ifa;
       unsigned long           isr;
};

struct _high_fp {
       union _ia64_fpreg       fr32;
       union _ia64_fpreg       fr33;
       union _ia64_fpreg       fr34;
       union _ia64_fpreg       fr35;
       union _ia64_fpreg       fr36;
       union _ia64_fpreg       fr37;
       union _ia64_fpreg       fr38;
       union _ia64_fpreg       fr39;
       union _ia64_fpreg       fr40;
       union _ia64_fpreg       fr41;
       union _ia64_fpreg       fr42;
       union _ia64_fpreg       fr43;
       union _ia64_fpreg       fr44;
       union _ia64_fpreg       fr45;
       union _ia64_fpreg       fr46;
       union _ia64_fpreg       fr47;
       union _ia64_fpreg       fr48;
       union _ia64_fpreg       fr49;
       union _ia64_fpreg       fr50;
       union _ia64_fpreg       fr51;
       union _ia64_fpreg       fr52;
       union _ia64_fpreg       fr53;
       union _ia64_fpreg       fr54;
       union _ia64_fpreg       fr55;
       union _ia64_fpreg       fr56;
       union _ia64_fpreg       fr57;
       union _ia64_fpreg       fr58;
       union _ia64_fpreg       fr59;
       union _ia64_fpreg       fr60;
       union _ia64_fpreg       fr61;
       union _ia64_fpreg       fr62;
       union _ia64_fpreg       fr63;
       union _ia64_fpreg       fr64;
       union _ia64_fpreg       fr65;
       union _ia64_fpreg       fr66;
       union _ia64_fpreg       fr67;
       union _ia64_fpreg       fr68;
       union _ia64_fpreg       fr69;
       union _ia64_fpreg       fr70;
       union _ia64_fpreg       fr71;
       union _ia64_fpreg       fr72;
       union _ia64_fpreg       fr73;
       union _ia64_fpreg       fr74;
       union _ia64_fpreg       fr75;
       union _ia64_fpreg       fr76;
       union _ia64_fpreg       fr77;
       union _ia64_fpreg       fr78;
       union _ia64_fpreg       fr79;
       union _ia64_fpreg       fr80;
       union _ia64_fpreg       fr81;
       union _ia64_fpreg       fr82;
       union _ia64_fpreg       fr83;
       union _ia64_fpreg       fr84;
       union _ia64_fpreg       fr85;
       union _ia64_fpreg       fr86;
       union _ia64_fpreg       fr87;
       union _ia64_fpreg       fr88;
       union _ia64_fpreg       fr89;
       union _ia64_fpreg       fr90;
       union _ia64_fpreg       fr91;
       union _ia64_fpreg       fr92;
       union _ia64_fpreg       fr93;
       union _ia64_fpreg       fr94;
       union _ia64_fpreg       fr95;
       union _ia64_fpreg       fr96;
       union _ia64_fpreg       fr97;
       union _ia64_fpreg       fr98;
       union _ia64_fpreg       fr99;
       union _ia64_fpreg       fr100;
       union _ia64_fpreg       fr101;
       union _ia64_fpreg       fr102;
       union _ia64_fpreg       fr103;
       union _ia64_fpreg       fr104;
       union _ia64_fpreg       fr105;
       union _ia64_fpreg       fr106;
       union _ia64_fpreg       fr107;
       union _ia64_fpreg       fr108;
       union _ia64_fpreg       fr109;
       union _ia64_fpreg       fr110;
       union _ia64_fpreg       fr111;
       union _ia64_fpreg       fr112;
       union _ia64_fpreg       fr113;
       union _ia64_fpreg       fr114;
       union _ia64_fpreg       fr115;
       union _ia64_fpreg       fr116;
       union _ia64_fpreg       fr117;
       union _ia64_fpreg       fr118;
       union _ia64_fpreg       fr119;
       union _ia64_fpreg       fr120;
       union _ia64_fpreg       fr121;
       union _ia64_fpreg       fr122;
       union _ia64_fpreg       fr123;
       union _ia64_fpreg       fr124;
       union _ia64_fpreg       fr125;
       union _ia64_fpreg       fr126;
       union _ia64_fpreg       fr127;
};

/*
* Preserved registers.
*/
struct _callee_saved {
       unsigned long           unat;           /* NaT after spilling. */
       unsigned long           gr4;
       unsigned long           gr5;
       unsigned long           gr6;
       unsigned long           gr7;
       unsigned long           br1;
       unsigned long           br2;
       unsigned long           br3;
       unsigned long           br4;
       unsigned long           br5;
       unsigned long           lc;
       unsigned long           __spare;
};

struct _callee_saved_fp {
       union _ia64_fpreg       fr2;
       union _ia64_fpreg       fr3;
       union _ia64_fpreg       fr4;
       union _ia64_fpreg       fr5;
       union _ia64_fpreg       fr16;
       union _ia64_fpreg       fr17;
       union _ia64_fpreg       fr18;
       union _ia64_fpreg       fr19;
       union _ia64_fpreg       fr20;
       union _ia64_fpreg       fr21;
       union _ia64_fpreg       fr22;
       union _ia64_fpreg       fr23;
       union _ia64_fpreg       fr24;
       union _ia64_fpreg       fr25;
       union _ia64_fpreg       fr26;
       union _ia64_fpreg       fr27;
       union _ia64_fpreg       fr28;
       union _ia64_fpreg       fr29;
       union _ia64_fpreg       fr30;
       union _ia64_fpreg       fr31;
};

/*
* Scratch registers.
*/
struct _caller_saved {
       unsigned long           unat;           /* NaT after spilling. */
       unsigned long           gr2;
       unsigned long           gr3;
       unsigned long           gr8;
       unsigned long           gr9;
       unsigned long           gr10;
       unsigned long           gr11;
       unsigned long           gr14;
       unsigned long           gr15;
       unsigned long           gr16;
       unsigned long           gr17;
       unsigned long           gr18;
       unsigned long           gr19;
       unsigned long           gr20;
       unsigned long           gr21;
       unsigned long           gr22;
       unsigned long           gr23;
       unsigned long           gr24;
       unsigned long           gr25;
       unsigned long           gr26;
       unsigned long           gr27;
       unsigned long           gr28;
       unsigned long           gr29;
       unsigned long           gr30;
       unsigned long           gr31;
       unsigned long           br6;
       unsigned long           br7;
       unsigned long           ccv;
       unsigned long           csd;
       unsigned long           ssd;
};

struct _caller_saved_fp {
       union _ia64_fpreg       fr6;
       union _ia64_fpreg       fr7;
       union _ia64_fpreg       fr8;
       union _ia64_fpreg       fr9;
       union _ia64_fpreg       fr10;
       union _ia64_fpreg       fr11;
       union _ia64_fpreg       fr12;
       union _ia64_fpreg       fr13;
       union _ia64_fpreg       fr14;
       union _ia64_fpreg       fr15;
};

#ifdef _KERNEL
void    restore_callee_saved(const struct _callee_saved *);
void    restore_callee_saved_fp(const struct _callee_saved_fp *);
void    restore_high_fp(const struct _high_fp *);
void    save_callee_saved(struct _callee_saved *);
void    save_callee_saved_fp(struct _callee_saved_fp *);
void    save_high_fp(struct _high_fp *);
#endif

#endif  /* _MACHINE_REGSET_H_ */