1 /* 2 * linux/include/linux/math_emu.h 3 * 4 * (C) 1991 Linus Torvalds 5 */ 6 #ifndef _LINUX_MATH_EMU_H 7 #define _LINUX_MATH_EMU_H 8 9 /*#define math_abort(x,y) \ 10 (((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))*/ 11 12 /* 13 * Gcc forces this stupid alignment problem: I want to use only two longs 14 * for the temporary real 64-bit mantissa, but then gcc aligns out the 15 * structure to 12 bytes which breaks things in math_emulate.c. Shit. I 16 * want some kind of "no-alignt" pragma or something. 17 */ 18 19 typedef struct { 20 long a,b; 21 short exponent; 22 } temp_real; 23 24 typedef struct { 25 short m0,m1,m2,m3; 26 short exponent; 27 } temp_real_unaligned; 28 29 #define real_to_real(a,b) \ 30 ((*(long long *) (b) = *(long long *) (a)),((b)->exponent = (a)->exponent)) 31 32 typedef struct { 33 long a,b; 34 } long_real; 35 36 typedef long short_real; 37 38 typedef struct { 39 long a,b; 40 short sign; 41 } temp_int; 42 43 struct swd { 44 int ie:1; 45 int de:1; 46 int ze:1; 47 int oe:1; 48 int ue:1; 49 int pe:1; 50 int sf:1; 51 int ir:1; 52 int c0:1; 53 int c1:1; 54 int c2:1; 55 int top:3; 56 int c3:1; 57 int b:1; 58 }; 59 struct i387_struct { 60 long cwd; 61 long swd; 62 long twd; 63 long fip; 64 long fcs; 65 long foo; 66 long fos; 67 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ 68 }; 69 70 #define I387 (*(struct i387_struct *)&(((struct pcb *)curproc->p_addr)->pcb_savefpu)) 71 #define SWD (*(struct swd *) &I387.swd) 72 #define ROUNDING ((I387.cwd >> 10) & 3) 73 #define PRECISION ((I387.cwd >> 8) & 3) 74 75 #define BITS24 0 76 #define BITS53 2 77 #define BITS64 3 78 79 #define ROUND_NEAREST 0 80 #define ROUND_DOWN 1 81 #define ROUND_UP 2 82 #define ROUND_0 3 83 84 #define CONSTZ (temp_real_unaligned) {0x0000,0x0000,0x0000,0x0000,0x0000} 85 #define CONST1 (temp_real_unaligned) {0x0000,0x0000,0x0000,0x8000,0x3FFF} 86 #define CONSTPI (temp_real_unaligned) {0xC235,0x2168,0xDAA2,0xC90F,0x4000} 87 #define CONSTLN2 (temp_real_unaligned) {0x79AC,0xD1CF,0x17F7,0xB172,0x3FFE} 88 #define CONSTLG2 (temp_real_unaligned) {0xF799,0xFBCF,0x9A84,0x9A20,0x3FFD} 89 #define CONSTL2E (temp_real_unaligned) {0xF0BC,0x5C17,0x3B29,0xB8AA,0x3FFF} 90 #define CONSTL2T (temp_real_unaligned) {0x8AFE,0xCD1B,0x784B,0xD49A,0x4000} 91 92 #define set_IE() (I387.swd |= 1) 93 #define set_DE() (I387.swd |= 2) 94 #define set_ZE() (I387.swd |= 4) 95 #define set_OE() (I387.swd |= 8) 96 #define set_UE() (I387.swd |= 16) 97 #define set_PE() (I387.swd |= 32) 98 99 #define set_C0() (I387.swd |= 0x0100) 100 #define set_C1() (I387.swd |= 0x0200) 101 #define set_C2() (I387.swd |= 0x0400) 102 #define set_C3() (I387.swd |= 0x4000) 103 104 /* ea.c */ 105 106 char * ea(struct trapframe *, unsigned short); 107 108 /* convert.c */ 109 110 void frndint(const temp_real * __a, temp_real * __b); 111 void Fscale(const temp_real *, const temp_real *, temp_real *); 112 void short_to_temp(const short_real * __a, temp_real * __b); 113 void long_to_temp(const long_real * __a, temp_real * __b); 114 void temp_to_short(const temp_real * __a, short_real * __b); 115 void temp_to_long(const temp_real * __a, long_real * __b); 116 void real_to_int(const temp_real * __a, temp_int * __b); 117 void int_to_real(const temp_int * __a, temp_real * __b); 118 119 /* get_put.c */ 120 121 void get_short_real(temp_real *, struct trapframe *, unsigned short); 122 void get_long_real(temp_real *, struct trapframe *, unsigned short); 123 void get_temp_real(temp_real *, struct trapframe *, unsigned short); 124 void get_short_int(temp_real *, struct trapframe *, unsigned short); 125 void get_long_int(temp_real *, struct trapframe *, unsigned short); 126 void get_longlong_int(temp_real *, struct trapframe *, unsigned short); 127 void get_BCD(temp_real *, struct trapframe *, unsigned short); 128 void put_short_real(const temp_real *, struct trapframe *, unsigned short); 129 void put_long_real(const temp_real *, struct trapframe *, unsigned short); 130 void put_temp_real(const temp_real *, struct trapframe *, unsigned short); 131 void put_short_int(const temp_real *, struct trapframe *, unsigned short); 132 void put_long_int(const temp_real *, struct trapframe *, unsigned short); 133 void put_longlong_int(const temp_real *, struct trapframe *, unsigned short); 134 void put_BCD(const temp_real *, struct trapframe *, unsigned short); 135 136 /* add.c */ 137 138 void fadd(const temp_real *, const temp_real *, temp_real *); 139 140 /* mul.c */ 141 142 void fmul(const temp_real *, const temp_real *, temp_real *); 143 144 /* div.c */ 145 146 void fdiv(const temp_real *, const temp_real *, temp_real *); 147 148 /* compare.c */ 149 150 void fcom(const temp_real *, const temp_real *); 151 void fucom(const temp_real *, const temp_real *); 152 void ftst(const temp_real *); 153 154 #endif 155