This is basic_regs.h in view mode; [Download] [Up]
/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
*
* File: architecture/m98k/basic_regs.h
* Author: Doug Mitchell, NeXT Computer, Inc.
*
* Basic m98k registers.
*
* HISTORY
* 05-Nov-92 Doug Mitchell at NeXT
* Created.
*/
#ifndef _ARCH_M98K_BASIC_REGS_H_
#define _ARCH_M98K_BASIC_REGS_H_
#import <architecture/m98k/reg_help.h>
#import <architecture/nrw/macro_help.h>
/*
* Number of General Purpose registers.
*/
#define M98K_NGP_REGS 32
/*
* Common half-word used in Machine State Register and in
* various exception frames. Defined as a macro because the compiler
* will align a struct to a word boundary when used inside another struct.
*/
#define MSR_BITS \
unsigned ee:BIT_WIDTH(15), /* external intr enable */ \
pr:BIT_WIDTH(14), /* problem state */ \
fp:BIT_WIDTH(13), /* floating point avail */ \
me:BIT_WIDTH(12), /* machine check enable */ \
fe0:BIT_WIDTH(11), /* fp exception mode 0 */ \
se:BIT_WIDTH(10), /* single step enable */ \
be:BIT_WIDTH(9), /* branch trace enable */ \
fe1:BIT_WIDTH(8), /* fp exception mode 0 */ \
rsvd1:BIT_WIDTH(7), /* reserved */ \
ip:BIT_WIDTH(6), /* interrupt prefix */ \
ir:BIT_WIDTH(5), /* instruction relocate */ \
dr:BIT_WIDTH(4), /* data relocate */ \
rsvd2:BITS_WIDTH(3,1), /* reserved */ \
psfr:BIT_WIDTH(0) /* 64 bit mode */
/*
* Machine state register.
* Read and written via get_msr() and set_msr() inlines, below.
*/
typedef struct {
unsigned rsvd3:BITS_WIDTH(31,16); // reserved
MSR_BITS; // see above
} msr_t;
/*
* Data Storage Interrupt Status Register (DSISR)
*/
typedef struct {
unsigned dse:BIT_WIDTH(31); // direct-store error
unsigned tnf:BIT_WIDTH(30); // translation not found
unsigned :BITS_WIDTH(29,28);
unsigned pe:BIT_WIDTH(27); // protection error
unsigned dsr:BIT_WIDTH(26); // lwarx/stwcx to direct-store
unsigned rw:BIT_WIDTH(25); // 1 => store, 0 => load
unsigned :BITS_WIDTH(24,23);
unsigned dab:BIT_WIDTH(22); // data address bkpt (601)
unsigned ssf:BIT_WIDTH(21); // seg table search failed
unsigned :BITS_WIDTH(20,0);
} dsisr_t;
/*
* Instruction Storage Interrupt Status Register (really SRR1)
*/
typedef struct {
unsigned :BIT_WIDTH(31);
unsigned tnf:BIT_WIDTH(30); // translation not found
unsigned :BIT_WIDTH(29);
unsigned dse:BIT_WIDTH(28); // direct-store fetch error
unsigned pe:BIT_WIDTH(27); // protection error
unsigned :BITS_WIDTH(26,22);
unsigned ssf:BIT_WIDTH(21); // seg table search failed
unsigned :BITS_WIDTH(20,16);
MSR_BITS;
} isisr_t;
/*
* Alignment Interrupt Status Register (really DSISR)
* NOTE: bit numbers in field *names* are in IBM'ese (0 is MSB).
* FIXME: Yuck!!! Double Yuck!!!
*/
typedef struct {
unsigned :BITS_WIDTH(31,20);
unsigned ds3031:BITS_WIDTH(19,18);// bits 30:31 if DS form
unsigned :BIT_WIDTH(17);
unsigned x2930:BITS_WIDTH(16,15); // bits 29:30 if X form
unsigned x25:BIT_WIDTH(14); // bit 25 if X form or
// bit 5 if D or DS form
unsigned x2124:BITS_WIDTH(13,10); // bits 21:24 if X form or
// bits 1:4 if D or DS form
unsigned all615:BITS_WIDTH(9,0); // bits 6:15 of instr
MSR_BITS;
} aisr_t;
/*
* Program Interrupt Status Register (really SRR1)
*/
typedef struct {
unsigned :BITS_WIDTH(31,21);
unsigned fpee:BIT_WIDTH(20); // floating pt enable exception
unsigned ill:BIT_WIDTH(19); // illegal instruction
unsigned priv:BIT_WIDTH(18); // privileged instruction
unsigned trap:BIT_WIDTH(17); // trap program interrupt
unsigned subseq:BIT_WIDTH(16); // 1 => SRR0 points to
// subsequent instruction
MSR_BITS;
} pisr_t;
/*
* Condition register. May not be useful in C, let's see...
*/
typedef struct {
unsigned lt:BIT_WIDTH(31), // negative
gt:BIT_WIDTH(30), // positive
eq:BIT_WIDTH(29), // equal to zero
so:BIT_WIDTH(28), // summary overflow
fx:BIT_WIDTH(27), // floating point exception
fex:BIT_WIDTH(26), // fp enabled exception
vx:BIT_WIDTH(25), // fp invalid operation
// exception
ox:BIT_WIDTH(24), // fp overflow exception
rsvd:BITS_WIDTH(23,0); // reserved
} cr_t;
/*
* Program mode register.
* Read and written via get_prog_mode() and set_prog_mode() inlines, below.
*
* NOT SUPPORTED ON M98601
*/
typedef struct {
unsigned rsvd1:BITS_WIDTH(31,12),
fe0:BIT_WIDTH(11),
rsvd2:BITS_WIDTH(10,9),
fe1:BIT_WIDTH(8),
rsvd3:BITS_WIDTH(7,1),
sf:BIT_WIDTH(0); // 64 bit mode
} prog_mode_t;
/*
* Abstract values representing fe0:fe1.
* See get_fp_exc_mode(), below.
*/
typedef enum {
FEM_IGNORE_EXCEP, // ignore exceptions
FEM_IMPR_NONREC, // imprecise nonrecoverable
FEM_IMPR_RECOV, // imprecise recoverable
FEM_PRECISE,
} fp_exc_mode_t;
/*
* Special purpose registers.
*/
/*
* Processor version register (special purpose register pvr).
*/
typedef struct {
unsigned version:BITS_WIDTH(31,16),
revision:BITS_WIDTH(15,0);
} pvr_t;
/*
* Fixed point exception register (special purpose register xer)
*/
typedef struct {
unsigned so:BIT_WIDTH(31), // summary overflow
ov:BIT_WIDTH(30), // overflow
ca:BIT_WIDTH(29), // carry
rsvd1:BITS_WIDTH(28,16),// reserved
byte:BITS_WIDTH(15,8), // byte to be compared
rsvd2:BIT_WIDTH(7), // reserved
byte_count:BITS_WIDTH(6,0);
} xer_t;
/*
* Inlines and macros to manipulate the above registers.
*/
/*
* Get/set machine state register.
*/
static __inline__ msr_t
get_msr()
{
msr_t __msr_tmp;
__asm__ volatile ("mfmsr %0 /* mfmsr */" \
: "=r" (__msr_tmp));
return __msr_tmp;
}
static __inline__ void
set_msr(msr_t msr)
{
__asm__ volatile ("mtmsr %0 /* mtmsr */ " \
: : "r" (msr));
}
/*
* Read/write program mode register.
*
* NOT SUPPORTED ON M98601
*/
static __inline__ prog_mode_t
get_prog_mode()
{
prog_mode_t __pm_tmp;
__asm__ volatile ("mfpmr %0 /* mfpmr */" \
: "=r" (__pm_tmp));
return __pm_tmp;
}
static __inline__ void
set_prog_mode(prog_mode_t prog_mode)
{
__asm__ volatile ("mtpmr %0; /* mtpmr */ " \
: : "r" (prog_mode));
}
/*
* Determine current fp_exc_mode_t given prog_mode.
*/
static __inline__ fp_exc_mode_t
get_fp_exc_mode(prog_mode_t prog_mode)
{
if(prog_mode.fe0) {
return prog_mode.fe1 ? FEM_PRECISE : FEM_IMPR_RECOV;
}
else {
return prog_mode.fe1 ? FEM_IMPR_NONREC : FEM_IGNORE_EXCEP;
}
}
/*
* Software definitions for special purpose registers.
* The same register is used as per_cpu data pointer and
* vector base register. This requires that the vector
* table be the first item in the per_cpu table.
*/
#define SR_EXCEPTION_TMP_LR sprg0
#define SR_EXCEPTION_TMP_CR sprg1
#define SR_EXCEPTION_TMP_AT sprg2
#define SR_PER_CPU_DATA sprg3
#define SR_VBR sprg3
/*
* Get/set special purpose registers.
*
* GET_SPR - get SPR by name.
*
* Example usage:
*
* {
* xer_t some_xer;
*
* some_xer = GET_SPR(xer_t, xer);
* ...
* }
*
* This is a strange one. We're creating a list of C expressions within
* a set of curlies; the last expression ("__spr_tmp;") is the return value
* of the statement created by the curlies.
*
* WARNING: The m88k version of this did not compile with -O2. Let's hope
* the 2.2.2 compiler fixes this.
*/
#define GET_SPR(type, spr) \
({ \
unsigned __spr_tmp; \
__asm__ volatile ("mfspr %0, " STRINGIFY(spr) \
: "=r" (__spr_tmp)); \
*(type *)&__spr_tmp; \
})
/*
* Example usage of SET_SPR:
*
* {
* xer_t some_xer;
*
* ...set up some_xer...
* SET_SPR(xer, some_xer);
* }
*/
#define SET_SPR(spr, val) \
MACRO_BEGIN \
__typeof__ (val) __spr_tmp = (val); \
__asm__ volatile ("mtspr "STRINGIFY(spr) ", %0" \
: : "r" (__spr_tmp)); \
MACRO_END
/*
* Fully synchronize instruction stream.
*/
static __inline__ void
m98k_sync()
{
__asm__ volatile ("sync /* sync */" \
: : );
}
#endif _ARCH_M98K_BASIC_REGS_H_
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.