|
|
1.1 ! root 1: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved. ! 2: * ! 3: * File: architecture/m88k/fp_regs.h ! 4: * Author: Mike DeMoney, NeXT Computer, Inc. ! 5: * ! 6: * This include file defines Motorola 88K architecturally defined ! 7: * floating point control and status registers. ! 8: * ! 9: * HISTORY ! 10: * 23-Jan-91 Mike DeMoney ([email protected]) ! 11: * Created. ! 12: */ ! 13: ! 14: #ifndef _ARCH_M88K_FP_REGS_H_ ! 15: #define _ARCH_M88K_FP_REGS_H_ ! 16: ! 17: #import <architecture/m88k/reg_help.h> ! 18: ! 19: /* ! 20: * m88k_xrf_t -- data types that MAY be in extended register file ! 21: * Actual data types supported is implementation dependent ! 22: */ ! 23: typedef union { ! 24: float f; // 32 bit IEEE single ! 25: double d; // 64 bit IEEE double ! 26: /* ! 27: * NOTE: currently compiler implements long double type ! 28: * simply as double. In the future, it may implement ! 29: * this as 80 bit IEEE double extended or 128 bit IEEE quad ! 30: * as appropriate for the 88K implementation. ! 31: */ ! 32: long double e; // 80 or 128 bit IEEE format ! 33: /* Insure compiler aligns struct appropriately */ ! 34: unsigned x[4] __attribute__(( aligned(16) )); ! 35: } m88k_xrf_t; ! 36: ! 37: /* ! 38: * FPSR -- Floating Point Status Register ! 39: */ ! 40: typedef struct { ! 41: unsigned :BITS_WIDTH(31,17); ! 42: unsigned xmod:BIT_WIDTH(16); // extended registers modified ! 43: unsigned :BITS_WIDTH(15,5); ! 44: unsigned afinv:BIT_WIDTH(4); // accumulated invalid flag ! 45: unsigned afdvz:BIT_WIDTH(3); // accumulated div by zero flag ! 46: unsigned afunf:BIT_WIDTH(2); // accumulated underflow flag ! 47: unsigned afovf:BIT_WIDTH(1); // accumulated overflow flag ! 48: unsigned afinx:BIT_WIDTH(0); // accumulated inexact flag ! 49: } m88k_fpsr_t; ! 50: ! 51: /* ! 52: * FPCR -- Floating Point Control Register ! 53: * 88K architecturally specified form. ! 54: * Does not expose implementation-dependent functions ! 55: */ ! 56: typedef enum { ! 57: M88K_RM_NEAREST = 0, // round toward nearest ! 58: M88K_RM_ZERO = 1, // round toward zero ! 59: M88K_RM_NEGINF = 2, // round toward negative infinity ! 60: M88K_RM_POSINF =3 // round toward positive infinity ! 61: } m88k_fpcr_rm_t; ! 62: ! 63: typedef struct { ! 64: unsigned :BITS_WIDTH(31,16); ! 65: m88k_fpcr_rm_t rm:BITS_WIDTH(15,14); // rounding mode ! 66: unsigned :BITS_WIDTH(13,5); ! 67: unsigned efinv:BIT_WIDTH(4); // invalid exception enable ! 68: unsigned efdvz:BIT_WIDTH(3); // div by zero exception enable ! 69: unsigned efunf:BIT_WIDTH(2); // underflow exception enable ! 70: unsigned efovf:BIT_WIDTH(1); // overflow exception enable ! 71: unsigned efinx:BIT_WIDTH(0); // inexact exception enable ! 72: } m88k_fpcr_t; ! 73: ! 74: /* ! 75: * FPCR -- Floating Point Control Register ! 76: * 88110 implementation -- includes "TCFP" features. ! 77: */ ! 78: typedef struct { ! 79: unsigned :BITS_WIDTH(31,22); ! 80: unsigned tcfp:BIT_WIDTH(21); // def results for INF/NaN ! 81: unsigned :BITS_WIDTH(20,19); ! 82: unsigned tcfpunf:BIT_WIDTH(18); // underflow -> zero ! 83: unsigned tcfpovf:BIT_WIDTH(17); // overflow -> inf ! 84: unsigned :BIT_WIDTH(16); ! 85: m88k_fpcr_rm_t rm:BITS_WIDTH(15,14); // rounding mode ! 86: unsigned :BITS_WIDTH(13,5); ! 87: unsigned efinv:BIT_WIDTH(4); // invalid exception enable ! 88: unsigned efdvz:BIT_WIDTH(3); // div by zero exception enable ! 89: unsigned efunf:BIT_WIDTH(2); // underflow exception enable ! 90: unsigned efovf:BIT_WIDTH(1); // overflow exception enable ! 91: unsigned efinx:BIT_WIDTH(0); // inexact exception enable ! 92: } m88110_fpcr_t; ! 93: ! 94: #ifndef __STRICT_ANSI__ ! 95: /* ! 96: * read and write fpsr and fpcr registers ! 97: * ! 98: * FIXME: When the compiler is fixed, convert to style of inlines shown ! 99: * in m88110_sfu0.h which do not use either CONTENTS() macro or ! 100: * *(foo_t *)& casts (and therefore, don't force the compiler to generate ! 101: * a memory reference. ! 102: */ ! 103: static __inline__ m88k_fpsr_t m88k_get_fpsr() ! 104: { ! 105: unsigned cr_tmp; ! 106: ! 107: __asm__ volatile ("fldcr %0,fcr62 ; get_fpsr()" : "=r" (cr_tmp)); ! 108: return *(m88k_fpsr_t *)&cr_tmp; ! 109: } ! 110: ! 111: static __inline__ void m88k_set_fpsr(m88k_fpsr_t fpsr_val) ! 112: { ! 113: /* ! 114: * Must force xmod to 1, since OS uses this to determine ! 115: * if XRF must be context switched. Not setting to 1 ! 116: * will NOT corrupt other threads registers, but will ! 117: * result in loss of this threads register values. ! 118: */ ! 119: fpsr_val.xmod = 1; ! 120: __asm__ volatile ("fstcr %0,fcr62 ; set_fpsr()" ! 121: : : "r" (CONTENTS(fpsr_val))); ! 122: } ! 123: ! 124: static __inline__ m88k_fpcr_t m88k_get_fpcr() ! 125: { ! 126: unsigned cr_tmp; ! 127: ! 128: __asm__ volatile ("fldcr %0,fcr63 ; get_fpcr()" : "=r" (cr_tmp)); ! 129: return *(m88k_fpcr_t *)&cr_tmp; ! 130: } ! 131: ! 132: static __inline__ void m88k_set_fpcr(m88k_fpcr_t fpcr_val) ! 133: { ! 134: __asm__ volatile ("fstcr %0,fcr63 ; set_fpcr()" ! 135: : : "r" (CONTENTS(fpcr_val))); ! 136: } ! 137: #endif __STRICT_ANSI__ ! 138: ! 139: #endif _ARCH_M88K_FP_REGS_H_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.