home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / cctools / include / architecture / m98k / basic_regs.h next >
Encoding:
C/C++ Source or Header  |  1993-01-04  |  7.7 KB  |  316 lines

  1. /* Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved.
  2.  *
  3.  *    File:    architecture/m98k/basic_regs.h
  4.  *    Author:    Doug Mitchell, NeXT Computer, Inc.
  5.  *
  6.  *    Basic m98k registers.
  7.  *
  8.  * HISTORY
  9.  * 05-Nov-92  Doug Mitchell at NeXT
  10.  *    Created.
  11.  */
  12.  
  13. #ifndef _ARCH_M98K_BASIC_REGS_H_
  14. #define _ARCH_M98K_BASIC_REGS_H_
  15.  
  16. #import <architecture/m98k/reg_help.h>
  17. #import <architecture/nrw/macro_help.h>
  18.  
  19. /*
  20.  * Number of General Purpose registers.
  21.  */
  22. #define M98K_NGP_REGS    32
  23.  
  24. /*
  25.  * Common half-word used in Machine State Register and in 
  26.  * various exception frames. Defined as a macro because the compiler
  27.  * will align a struct to a word boundary when used inside another struct.
  28.  */
  29. #define MSR_BITS                               \
  30.     unsigned    ee:BIT_WIDTH(15),    /* external intr enable */ \
  31.             pr:BIT_WIDTH(14),    /* problem state    */ \
  32.             fp:BIT_WIDTH(13),    /* floating point avail    */ \
  33.             me:BIT_WIDTH(12),    /* machine check enable    */ \
  34.             fe0:BIT_WIDTH(11),    /* fp exception mode 0    */ \
  35.             se:BIT_WIDTH(10),    /* single step enable    */ \
  36.             be:BIT_WIDTH(9),    /* branch trace enable    */ \
  37.             fe1:BIT_WIDTH(8),    /* fp exception mode 0    */ \
  38.             rsvd1:BIT_WIDTH(7),    /* reserved        */ \
  39.             ip:BIT_WIDTH(6),    /* interrupt prefix    */ \
  40.             ir:BIT_WIDTH(5),    /* instruction relocate    */ \
  41.             dr:BIT_WIDTH(4),    /* data relocate    */ \
  42.             rsvd2:BITS_WIDTH(3,1),    /* reserved        */ \
  43.             psfr:BIT_WIDTH(0)    /* 64 bit mode        */
  44.  
  45. /*
  46.  * Machine state register.
  47.  * Read and written via get_msr() and set_msr() inlines, below.
  48.  */
  49. typedef struct {
  50.     unsigned    rsvd3:BITS_WIDTH(31,16);    // reserved
  51.             MSR_BITS;            // see above
  52. } msr_t;
  53.  
  54. /*
  55.  * Data Storage Interrupt Status Register (DSISR)
  56.  */
  57. typedef struct {
  58.     unsigned    dse:BIT_WIDTH(31);    // direct-store error
  59.     unsigned    tnf:BIT_WIDTH(30);    // translation not found
  60.     unsigned    :BITS_WIDTH(29,28);
  61.     unsigned    pe:BIT_WIDTH(27);    // protection error
  62.     unsigned    dsr:BIT_WIDTH(26);    // lwarx/stwcx to direct-store
  63.     unsigned    rw:BIT_WIDTH(25);    // 1 => store, 0 => load
  64.     unsigned    :BITS_WIDTH(24,23);
  65.     unsigned    dab:BIT_WIDTH(22);    // data address bkpt (601)
  66.     unsigned    ssf:BIT_WIDTH(21);    // seg table search failed
  67.     unsigned    :BITS_WIDTH(20,0);
  68. } dsisr_t;
  69.  
  70. /*
  71.  * Instruction Storage Interrupt Status Register (really SRR1)
  72.  */
  73. typedef struct {
  74.     unsigned    :BIT_WIDTH(31);
  75.     unsigned    tnf:BIT_WIDTH(30);    // translation not found
  76.     unsigned    :BIT_WIDTH(29);
  77.     unsigned    dse:BIT_WIDTH(28);    // direct-store fetch error
  78.     unsigned    pe:BIT_WIDTH(27);    // protection error
  79.     unsigned    :BITS_WIDTH(26,22);
  80.     unsigned    ssf:BIT_WIDTH(21);    // seg table search failed
  81.     unsigned    :BITS_WIDTH(20,16);
  82.     MSR_BITS;
  83. } isisr_t;
  84.  
  85. /*
  86.  * Alignment Interrupt Status Register (really DSISR)
  87.  * NOTE: bit numbers in field *names* are in IBM'ese (0 is MSB).
  88.  * FIXME: Yuck!!! Double Yuck!!!
  89.  */
  90. typedef struct {
  91.     unsigned    :BITS_WIDTH(31,20);
  92.     unsigned    ds3031:BITS_WIDTH(19,18);// bits 30:31 if DS form
  93.     unsigned    :BIT_WIDTH(17);
  94.     unsigned    x2930:BITS_WIDTH(16,15); // bits 29:30 if X form
  95.     unsigned    x25:BIT_WIDTH(14);     // bit 25 if X form or
  96.                          // bit 5 if D or DS form
  97.     unsigned    x2124:BITS_WIDTH(13,10); // bits 21:24 if X form or
  98.                          // bits 1:4 if D or DS form
  99.     unsigned    all615:BITS_WIDTH(9,0);     // bits 6:15 of instr
  100.     MSR_BITS;
  101. } aisr_t;
  102.  
  103. /*
  104.  * Program Interrupt Status Register (really SRR1)
  105.  */
  106. typedef struct {
  107.     unsigned    :BITS_WIDTH(31,21);
  108.     unsigned    fpee:BIT_WIDTH(20);    // floating pt enable exception
  109.     unsigned    ill:BIT_WIDTH(19);    // illegal instruction
  110.     unsigned    priv:BIT_WIDTH(18);    // privileged instruction
  111.     unsigned    trap:BIT_WIDTH(17);    // trap program interrupt
  112.     unsigned    subseq:BIT_WIDTH(16);    // 1 => SRR0 points to
  113.                         // subsequent instruction
  114.     MSR_BITS;
  115. } pisr_t;
  116.  
  117. /*
  118.  * Condition register. May not be useful in C, let's see...
  119.  */
  120. typedef struct {
  121.     unsigned    lt:BIT_WIDTH(31),    // negative
  122.             gt:BIT_WIDTH(30),    // positive
  123.             eq:BIT_WIDTH(29),    // equal to zero
  124.             so:BIT_WIDTH(28),    // summary overflow
  125.             fx:BIT_WIDTH(27),    // floating point exception
  126.             fex:BIT_WIDTH(26),    // fp enabled exception
  127.             vx:BIT_WIDTH(25),    // fp invalid operation
  128.                         //    exception
  129.             ox:BIT_WIDTH(24),    // fp overflow exception
  130.             rsvd:BITS_WIDTH(23,0);    // reserved
  131. } cr_t;
  132.  
  133. /*
  134.  * Program mode register.
  135.  * Read and written via get_prog_mode() and set_prog_mode() inlines, below.
  136.  *
  137.  * NOT SUPPORTED ON M98601
  138.  */
  139. typedef struct {
  140.     unsigned    rsvd1:BITS_WIDTH(31,12),
  141.             fe0:BIT_WIDTH(11),
  142.             rsvd2:BITS_WIDTH(10,9),
  143.             fe1:BIT_WIDTH(8),
  144.             rsvd3:BITS_WIDTH(7,1),
  145.             sf:BIT_WIDTH(0);    // 64 bit mode
  146. } prog_mode_t;
  147.  
  148. /*
  149.  * Abstract values representing fe0:fe1.
  150.  * See get_fp_exc_mode(), below.
  151.  */
  152. typedef enum {
  153.     FEM_IGNORE_EXCEP,    // ignore exceptions
  154.     FEM_IMPR_NONREC,    // imprecise nonrecoverable
  155.     FEM_IMPR_RECOV,        // imprecise recoverable
  156.     FEM_PRECISE,
  157. } fp_exc_mode_t;
  158.  
  159.  
  160. /*
  161.  * Special purpose registers.
  162.  */
  163.  
  164. /*
  165.  * Processor version register (special purpose register pvr).
  166.  */
  167. typedef struct {
  168.     unsigned    version:BITS_WIDTH(31,16),    
  169.             revision:BITS_WIDTH(15,0);
  170. } pvr_t;
  171.  
  172. /*
  173.  * Fixed point exception register (special purpose register xer)
  174.  */
  175. typedef struct {
  176.     unsigned    so:BIT_WIDTH(31),    // summary overflow
  177.             ov:BIT_WIDTH(30),    // overflow
  178.             ca:BIT_WIDTH(29),    // carry
  179.             rsvd1:BITS_WIDTH(28,16),// reserved
  180.             byte:BITS_WIDTH(15,8),    // byte to be compared
  181.             rsvd2:BIT_WIDTH(7),    // reserved
  182.             byte_count:BITS_WIDTH(6,0);    
  183. } xer_t;
  184.  
  185. /*
  186.  * Inlines and macros to manipulate the above registers.
  187.  */
  188.  
  189. /*
  190.  * Get/set machine state register.
  191.  */
  192. static __inline__ msr_t
  193. get_msr()
  194. {
  195.     msr_t    __msr_tmp;    
  196.     
  197.     __asm__ volatile ("mfmsr %0  /* mfmsr */"  \
  198.           : "=r" (__msr_tmp));
  199.     return __msr_tmp;
  200. }
  201.  
  202. static __inline__ void
  203. set_msr(msr_t msr)
  204. {
  205.     __asm__ volatile ("mtmsr %0 /* mtmsr */ "    \
  206.       : : "r" (msr));    
  207. }
  208.  
  209. /*
  210.  * Read/write program mode register.
  211.  *
  212.  * NOT SUPPORTED ON M98601
  213.  */
  214. static __inline__ prog_mode_t 
  215. get_prog_mode()
  216. {
  217.     prog_mode_t    __pm_tmp;    
  218.     __asm__ volatile ("mfpmr %0  /* mfpmr */"    \
  219.           : "=r" (__pm_tmp));
  220.     return __pm_tmp;        
  221. }
  222.  
  223. static __inline__ void 
  224. set_prog_mode(prog_mode_t prog_mode)
  225. {
  226.     __asm__ volatile ("mtpmr %0; /* mtpmr */ "    \
  227.       : : "r" (prog_mode));    
  228. }
  229.  
  230.  
  231. /* 
  232.  * Determine current fp_exc_mode_t given prog_mode.
  233.  */
  234. static __inline__ fp_exc_mode_t
  235. get_fp_exc_mode(prog_mode_t prog_mode)
  236. {
  237.     if(prog_mode.fe0) {
  238.         return prog_mode.fe1 ? FEM_PRECISE : FEM_IMPR_RECOV;
  239.     }
  240.     else {
  241.         return prog_mode.fe1 ? FEM_IMPR_NONREC : FEM_IGNORE_EXCEP;
  242.     }
  243. }
  244.  
  245. /*
  246.  * Software definitions for special purpose registers.
  247.  * The same register is used as per_cpu data pointer and
  248.  * vector base register. This requires that the vector
  249.  * table be the first item in the per_cpu table.
  250.  */
  251. #define SR_EXCEPTION_TMP_LR    sprg0
  252. #define SR_EXCEPTION_TMP_CR    sprg1
  253. #define SR_EXCEPTION_TMP_AT    sprg2
  254. #define SR_PER_CPU_DATA        sprg3
  255. #define SR_VBR            sprg3
  256.  
  257. /*
  258.  * Get/set special purpose registers.
  259.  *
  260.  * GET_SPR - get SPR by name.
  261.  *
  262.  * Example usage:
  263.  *
  264.  *   {
  265.  *    xer_t    some_xer;
  266.  *
  267.  *    some_xer = GET_SPR(xer_t, xer);
  268.  *    ...
  269.  *   }
  270.  *
  271.  * This is a strange one. We're creating a list of C expressions within
  272.  * a set of curlies; the last expression ("__spr_tmp;") is the return value
  273.  * of the statement created by the curlies.
  274.  *
  275.  * WARNING: The m88k version of this did not compile with -O2. Let's hope
  276.  * the 2.2.2 compiler fixes this.
  277.  */
  278.  
  279. #define GET_SPR(type, spr)                    \
  280. ({                                \
  281.     unsigned    __spr_tmp;                \
  282.     __asm__ volatile ("mfspr %0, "  STRINGIFY(spr)        \
  283.           : "=r" (__spr_tmp));                \
  284.     *(type *)&__spr_tmp;                    \
  285. })
  286.  
  287. /* 
  288.  * Example usage of SET_SPR:
  289.  *
  290.  *   {
  291.  *    xer_t some_xer;
  292.  *
  293.  *    ...set up some_xer...
  294.  *    SET_SPR(xer, some_xer);
  295.  *   }
  296.  */
  297. #define    SET_SPR(spr, val)                    \
  298. MACRO_BEGIN                            \
  299.     __typeof__ (val) __spr_tmp = (val);            \
  300.     __asm__ volatile ("mtspr "STRINGIFY(spr) ", %0"        \
  301.       : : "r" (__spr_tmp));                    \
  302. MACRO_END
  303.  
  304. /*
  305.  * Fully synchronize instruction stream.
  306.  */
  307. static __inline__ void
  308. m98k_sync()
  309. {
  310.     __asm__ volatile ("sync         /* sync */"    \
  311.         : : );
  312. }
  313.  
  314. #endif    _ARCH_M98K_BASIC_REGS_H_
  315.  
  316.