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.