~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/alpha/math-emu/math.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/alpha/math-emu/math.c (Version linux-6.11-rc3) and /arch/m68k/math-emu/math.c (Version linux-5.17.15)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 #include <linux/module.h>                         
  3 #include <linux/types.h>                          
  4 #include <linux/kernel.h>                         
  5 #include <linux/sched.h>                          
  6 #include <asm/ptrace.h>                           
  7 #include <asm/fpu.h>                              
  8                                                   
  9 #include <linux/uaccess.h>                        
 10                                                   
 11 #include "sfp-util.h"                             
 12 #include <math-emu/soft-fp.h>                     
 13 #include <math-emu/single.h>                      
 14 #include <math-emu/double.h>                      
 15                                                   
 16 #define OPC_PAL         0x00                      
 17 #define OPC_INTA        0x10                      
 18 #define OPC_INTL        0x11                      
 19 #define OPC_INTS        0x12                      
 20 #define OPC_INTM        0x13                      
 21 #define OPC_FLTC        0x14                      
 22 #define OPC_FLTV        0x15                      
 23 #define OPC_FLTI        0x16                      
 24 #define OPC_FLTL        0x17                      
 25 #define OPC_MISC        0x18                      
 26 #define OPC_JSR         0x1a                      
 27                                                   
 28 #define FOP_SRC_S       0                         
 29 #define FOP_SRC_T       2                         
 30 #define FOP_SRC_Q       3                         
 31                                                   
 32 #define FOP_FNC_ADDx    0                         
 33 #define FOP_FNC_CVTQL   0                         
 34 #define FOP_FNC_SUBx    1                         
 35 #define FOP_FNC_MULx    2                         
 36 #define FOP_FNC_DIVx    3                         
 37 #define FOP_FNC_CMPxUN  4                         
 38 #define FOP_FNC_CMPxEQ  5                         
 39 #define FOP_FNC_CMPxLT  6                         
 40 #define FOP_FNC_CMPxLE  7                         
 41 #define FOP_FNC_SQRTx   11                        
 42 #define FOP_FNC_CVTxS   12                        
 43 #define FOP_FNC_CVTxT   14                        
 44 #define FOP_FNC_CVTxQ   15                        
 45                                                   
 46 #define MISC_TRAPB      0x0000                    
 47 #define MISC_EXCB       0x0400                    
 48                                                   
 49 #ifdef MODULE                                     
 50                                                   
 51 MODULE_DESCRIPTION("FP Software completion mod    
 52 MODULE_LICENSE("GPL v2");                         
 53                                                   
 54 extern long (*alpha_fp_emul_imprecise)(struct     
 55 extern long (*alpha_fp_emul) (unsigned long pc    
 56                                                   
 57 static long (*save_emul_imprecise)(struct pt_r    
 58 static long (*save_emul) (unsigned long pc);      
 59                                                   
 60 long do_alpha_fp_emul_imprecise(struct pt_regs    
 61 long do_alpha_fp_emul(unsigned long);             
 62                                                   
 63 static int alpha_fp_emul_init_module(void)        
 64 {                                                 
 65         save_emul_imprecise = alpha_fp_emul_im    
 66         save_emul = alpha_fp_emul;                
 67         alpha_fp_emul_imprecise = do_alpha_fp_    
 68         alpha_fp_emul = do_alpha_fp_emul;         
 69         return 0;                                 
 70 }                                                 
 71 module_init(alpha_fp_emul_init_module);           
 72                                                   
 73 static void alpha_fp_emul_cleanup_module(void)    
 74 {                                                 
 75         alpha_fp_emul_imprecise = save_emul_im    
 76         alpha_fp_emul = save_emul;                
 77 }                                                 
 78 module_exit(alpha_fp_emul_cleanup_module);        
 79                                                   
 80 #undef  alpha_fp_emul_imprecise                   
 81 #define alpha_fp_emul_imprecise         do_alp    
 82 #undef  alpha_fp_emul                             
 83 #define alpha_fp_emul                   do_alp    
 84                                                   
 85 #endif /* MODULE */                               
 86                                                   
 87                                                   
 88 /*                                                
 89  * Emulate the floating point instruction at a    
 90  * instruction to be emulated is illegal (such    
 91  * the SI_CODE for a SIGFPE signal, else 0 if     
 92  *                                                
 93  * Notice that the kernel does not and cannot     
 94  * because it means that instead of saving/res    
 95  * stick the result of the operation into the     
 96  */                                               
 97 long                                              
 98 alpha_fp_emul (unsigned long pc)                  
 99 {                                                 
100         FP_DECL_EX;                               
101         FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_    
102         FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_    
103                                                   
104         unsigned long fa, fb, fc, func, mode,     
105         unsigned long res, va, vb, vc, swcr, f    
106         __u32 insn;                               
107         long si_code;                             
108                                                   
109         get_user(insn, (__u32 __user *)pc);       
110         fc     = (insn >>  0) & 0x1f;   /* des    
111         fb     = (insn >> 16) & 0x1f;             
112         fa     = (insn >> 21) & 0x1f;             
113         func   = (insn >>  5) & 0xf;              
114         src    = (insn >>  9) & 0x3;              
115         mode   = (insn >> 11) & 0x3;              
116                                                   
117         fpcr = rdfpcr();                          
118         swcr = swcr_update_status(current_thre    
119                                                   
120         if (mode == 3) {                          
121                 /* Dynamic -- get rounding mod    
122                 mode = (fpcr >> FPCR_DYN_SHIFT    
123         }                                         
124                                                   
125         switch (src) {                            
126         case FOP_SRC_S:                           
127                 va = alpha_read_fp_reg_s(fa);     
128                 vb = alpha_read_fp_reg_s(fb);     
129                                                   
130                 FP_UNPACK_SP(SA, &va);            
131                 FP_UNPACK_SP(SB, &vb);            
132                                                   
133                 switch (func) {                   
134                 case FOP_FNC_SUBx:                
135                         FP_SUB_S(SR, SA, SB);     
136                         goto pack_s;              
137                                                   
138                 case FOP_FNC_ADDx:                
139                         FP_ADD_S(SR, SA, SB);     
140                         goto pack_s;              
141                                                   
142                 case FOP_FNC_MULx:                
143                         FP_MUL_S(SR, SA, SB);     
144                         goto pack_s;              
145                                                   
146                 case FOP_FNC_DIVx:                
147                         FP_DIV_S(SR, SA, SB);     
148                         goto pack_s;              
149                                                   
150                 case FOP_FNC_SQRTx:               
151                         FP_SQRT_S(SR, SB);        
152                         goto pack_s;              
153                 }                                 
154                 goto bad_insn;                    
155                                                   
156         case FOP_SRC_T:                           
157                 va = alpha_read_fp_reg(fa);       
158                 vb = alpha_read_fp_reg(fb);       
159                                                   
160                 if ((func & ~3) == FOP_FNC_CMP    
161                         FP_UNPACK_RAW_DP(DA, &    
162                         FP_UNPACK_RAW_DP(DB, &    
163                         if (!DA_e && !_FP_FRAC    
164                                 FP_SET_EXCEPTI    
165                                 if (FP_DENORM_    
166                                         _FP_FR    
167                         }                         
168                         if (!DB_e && !_FP_FRAC    
169                                 FP_SET_EXCEPTI    
170                                 if (FP_DENORM_    
171                                         _FP_FR    
172                         }                         
173                         FP_CMP_D(res, DA, DB,     
174                         vc = 0x400000000000000    
175                         /* CMPTEQ, CMPTUN don'    
176                            while CMPTLT and CM    
177                         if (res == 3              
178                             && ((func & 3) >=     
179                                 || FP_ISSIGNAN    
180                                 || FP_ISSIGNAN    
181                                 FP_SET_EXCEPTI    
182                         }                         
183                         switch (func) {           
184                         case FOP_FNC_CMPxUN: i    
185                         case FOP_FNC_CMPxEQ: i    
186                         case FOP_FNC_CMPxLT: i    
187                         case FOP_FNC_CMPxLE: i    
188                         }                         
189                         goto done_d;              
190                 }                                 
191                                                   
192                 FP_UNPACK_DP(DA, &va);            
193                 FP_UNPACK_DP(DB, &vb);            
194                                                   
195                 switch (func) {                   
196                 case FOP_FNC_SUBx:                
197                         FP_SUB_D(DR, DA, DB);     
198                         goto pack_d;              
199                                                   
200                 case FOP_FNC_ADDx:                
201                         FP_ADD_D(DR, DA, DB);     
202                         goto pack_d;              
203                                                   
204                 case FOP_FNC_MULx:                
205                         FP_MUL_D(DR, DA, DB);     
206                         goto pack_d;              
207                                                   
208                 case FOP_FNC_DIVx:                
209                         FP_DIV_D(DR, DA, DB);     
210                         goto pack_d;              
211                                                   
212                 case FOP_FNC_SQRTx:               
213                         FP_SQRT_D(DR, DB);        
214                         goto pack_d;              
215                                                   
216                 case FOP_FNC_CVTxS:               
217                         /* It is irritating th    
218                            SRC == T_floating.     
219                            the bit used to tel    
220                         if (insn & 0x2000) {      
221                                 FP_CONV(S,D,1,    
222                                 goto pack_s;      
223                         } else {                  
224                                 vb = alpha_rea    
225                                 FP_UNPACK_SP(S    
226                                 DR_c = DB_c;      
227                                 DR_s = DB_s;      
228                                 DR_e = DB_e +     
229                                 DR_f = SB_f <<    
230                                 goto pack_d;      
231                         }                         
232                                                   
233                 case FOP_FNC_CVTxQ:               
234                         if (DB_c == FP_CLS_NAN    
235                             && (_FP_FRAC_HIGH_    
236                           /* AAHB Table B-2 sa    
237                                 vc = 0;           
238                         } else                    
239                                 FP_TO_INT_ROUN    
240                         goto done_d;              
241                 }                                 
242                 goto bad_insn;                    
243                                                   
244         case FOP_SRC_Q:                           
245                 vb = alpha_read_fp_reg(fb);       
246                                                   
247                 switch (func) {                   
248                 case FOP_FNC_CVTQL:               
249                         /* Notice: We can get     
250                            overflow.  Such ove    
251                            ops.  We return the    
252                            computed.  */          
253                         vc = ((vb & 0xc0000000    
254                               (vb & 0x3fffffff    
255                         FP_SET_EXCEPTION (FP_E    
256                         goto done_d;              
257                                                   
258                 case FOP_FNC_CVTxS:               
259                         FP_FROM_INT_S(SR, ((lo    
260                         goto pack_s;              
261                                                   
262                 case FOP_FNC_CVTxT:               
263                         FP_FROM_INT_D(DR, ((lo    
264                         goto pack_d;              
265                 }                                 
266                 goto bad_insn;                    
267         }                                         
268         goto bad_insn;                            
269                                                   
270 pack_s:                                           
271         FP_PACK_SP(&vc, SR);                      
272         if ((_fex & FP_EX_UNDERFLOW) && (swcr     
273                 vc = 0;                           
274         alpha_write_fp_reg_s(fc, vc);             
275         goto done;                                
276                                                   
277 pack_d:                                           
278         FP_PACK_DP(&vc, DR);                      
279         if ((_fex & FP_EX_UNDERFLOW) && (swcr     
280                 vc = 0;                           
281 done_d:                                           
282         alpha_write_fp_reg(fc, vc);               
283         goto done;                                
284                                                   
285         /*                                        
286          * Take the appropriate action for eac    
287          * floating-point result:                 
288          *                                        
289          *      - Set the appropriate bits in     
290          *      - If the specified exception i    
291          *        return.  The caller (entArit    
292          *        the appropriate signal to th    
293          *                                        
294          * In addition, properly track the exc    
295          * as described in the Alpha Architect    
296          */                                       
297 done:                                             
298         if (_fex) {                               
299                 /* Record exceptions in softwa    
300                 swcr |= (_fex << IEEE_STATUS_T    
301                 current_thread_info()->ieee_st    
302                   |= (_fex << IEEE_STATUS_TO_E    
303                                                   
304                 /* Update hardware control reg    
305                 fpcr &= (~FPCR_MASK | FPCR_DYN    
306                 fpcr |= ieee_swcr_to_fpcr(swcr    
307                 wrfpcr(fpcr);                     
308                                                   
309                 /* Do we generate a signal?  *    
310                 _fex = _fex & swcr & IEEE_TRAP    
311                 si_code = 0;                      
312                 if (_fex) {                       
313                         if (_fex & IEEE_TRAP_E    
314                         if (_fex & IEEE_TRAP_E    
315                         if (_fex & IEEE_TRAP_E    
316                         if (_fex & IEEE_TRAP_E    
317                         if (_fex & IEEE_TRAP_E    
318                         if (_fex & IEEE_TRAP_E    
319                 }                                 
320                                                   
321                 return si_code;                   
322         }                                         
323                                                   
324         /* We used to write the destination re    
325            requires that the result *always* b    
326            immediately after the operations ab    
327                                                   
328         return 0;                                 
329                                                   
330 bad_insn:                                         
331         printk(KERN_ERR "alpha_fp_emul: Invali    
332                insn, pc);                         
333         return -1;                                
334 }                                                 
335                                                   
336 long                                              
337 alpha_fp_emul_imprecise (struct pt_regs *regs,    
338 {                                                 
339         unsigned long trigger_pc = regs->pc -     
340         unsigned long insn, opcode, rc, si_cod    
341                                                   
342         /*                                        
343          * Turn off the bits corresponding to     
344          * target of instructions that set bit    
345          * summary register.  We have some sla    
346          * register that is the target of a tr    
347          * be written at most once in the trap    
348          *                                        
349          * Branches, jumps, TRAPBs, EXCBs and     
350          * bound the trap shadow, so we need n    
351          * up to the first occurrence of such     
352          */                                       
353         while (write_mask) {                      
354                 get_user(insn, (__u32 __user *    
355                 opcode = insn >> 26;              
356                 rc = insn & 0x1f;                 
357                                                   
358                 switch (opcode) {                 
359                       case OPC_PAL:               
360                       case OPC_JSR:               
361                       case 0x30 ... 0x3f:         
362                         goto egress;              
363                                                   
364                       case OPC_MISC:              
365                         switch (insn & 0xffff)    
366                               case MISC_TRAPB:    
367                               case MISC_EXCB:     
368                                 goto egress;      
369                                                   
370                               default:            
371                                 break;            
372                         }                         
373                         break;                    
374                                                   
375                       case OPC_INTA:              
376                       case OPC_INTL:              
377                       case OPC_INTS:              
378                       case OPC_INTM:              
379                         write_mask &= ~(1UL <<    
380                         break;                    
381                                                   
382                       case OPC_FLTC:              
383                       case OPC_FLTV:              
384                       case OPC_FLTI:              
385                       case OPC_FLTL:              
386                         write_mask &= ~(1UL <<    
387                         break;                    
388                 }                                 
389                 if (!write_mask) {                
390                         /* Re-execute insns in    
391                         regs->pc = trigger_pc     
392                         si_code = alpha_fp_emu    
393                         goto egress;              
394                 }                                 
395                 trigger_pc -= 4;                  
396         }                                         
397                                                   
398 egress:                                           
399         return si_code;                           
400 }                                                 
401                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php