Merge master.kernel.org:/home/rmk/linux-2.6-arm

+337 -484
+1
Documentation/dontdiff
··· 104 104 logo_*_clut224.c 105 105 logo_*_mono.c 106 106 lxdialog 107 + mach-types 107 108 mach-types.h 108 109 make_times_h 109 110 map
+1 -1
arch/arm/mach-ixp4xx/coyote-setup.c
··· 61 61 .mapbase = IXP4XX_UART2_BASE_PHYS, 62 62 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, 63 63 .irq = IRQ_IXP4XX_UART2, 64 - .flags = UPF_BOOT_AUTOCONF, 64 + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 65 65 .iotype = UPIO_MEM, 66 66 .regshift = 2, 67 67 .uartclk = IXP4XX_UART_XTAL,
+1 -1
arch/arm/mach-ixp4xx/gtwx5715-setup.c
··· 83 83 .mapbase = IXP4XX_UART2_BASE_PHYS, 84 84 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, 85 85 .irq = IRQ_IXP4XX_UART2, 86 - .flags = UPF_BOOT_AUTOCONF, 86 + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 87 87 .iotype = UPIO_MEM, 88 88 .regshift = 2, 89 89 .uartclk = IXP4XX_UART_XTAL,
+2 -2
arch/arm/mach-ixp4xx/ixdp425-setup.c
··· 82 82 .mapbase = IXP4XX_UART1_BASE_PHYS, 83 83 .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, 84 84 .irq = IRQ_IXP4XX_UART1, 85 - .flags = UPF_BOOT_AUTOCONF, 85 + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 86 86 .iotype = UPIO_MEM, 87 87 .regshift = 2, 88 88 .uartclk = IXP4XX_UART_XTAL, ··· 91 91 .mapbase = IXP4XX_UART2_BASE_PHYS, 92 92 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, 93 93 .irq = IRQ_IXP4XX_UART1, 94 - .flags = UPF_BOOT_AUTOCONF, 94 + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, 95 95 .iotype = UPIO_MEM, 96 96 .regshift = 2, 97 97 .uartclk = IXP4XX_UART_XTAL,
+15 -1
arch/arm/mach-s3c2410/mach-bast.c
··· 30 30 * 28-Jun-2005 BJD Moved pm functionality out to common code 31 31 * 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s 32 32 * 25-Jul-2005 BJD Removed ASIX static mappings 33 + * 27-Jul-2005 BJD Ensure maximum frequency of i2c bus 33 34 */ 34 35 35 36 #include <linux/kernel.h> ··· 61 60 #include <asm/arch/regs-mem.h> 62 61 #include <asm/arch/regs-lcd.h> 63 62 #include <asm/arch/nand.h> 63 + #include <asm/arch/iic.h> 64 64 65 65 #include <linux/mtd/mtd.h> 66 66 #include <linux/mtd/nand.h> ··· 306 304 } 307 305 308 306 static struct s3c2410_platform_nand bast_nand_info = { 309 - .tacls = 80, 307 + .tacls = 40, 310 308 .twrph0 = 80, 311 309 .twrph1 = 80, 312 310 .nr_sets = ARRAY_SIZE(bast_nand_sets), ··· 387 385 }, 388 386 }; 389 387 388 + /* we have devices on the bus which cannot work much over the 389 + * standard 100KHz i2c bus frequency 390 + */ 391 + 392 + static struct s3c2410_platform_i2c bast_i2c_info = { 393 + .flags = 0, 394 + .slave_addr = 0x10, 395 + .bus_freq = 100*1000, 396 + .max_freq = 130*1000, 397 + }; 398 + 390 399 /* Standard BAST devices */ 391 400 392 401 static struct platform_device *bast_devices[] __initdata = { ··· 444 431 s3c24xx_uclk.parent = &s3c24xx_clkout1; 445 432 446 433 s3c_device_nand.dev.platform_data = &bast_nand_info; 434 + s3c_device_i2c.dev.platform_data = &bast_i2c_info; 447 435 448 436 s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); 449 437 s3c24xx_init_clocks(0);
-136
arch/arm/mm/proc-xscale.S
··· 370 370 bhi 1b 371 371 mov pc, lr 372 372 373 - /* ================================ CACHE LOCKING============================ 374 - * 375 - * The XScale MicroArchitecture implements support for locking entries into 376 - * the data and instruction cache. The following functions implement the core 377 - * low level instructions needed to accomplish the locking. The developer's 378 - * manual states that the code that performs the locking must be in non-cached 379 - * memory. To accomplish this, the code in xscale-cache-lock.c copies the 380 - * following functions from the cache into a non-cached memory region that 381 - * is allocated through consistent_alloc(). 382 - * 383 - */ 384 - .align 5 385 - /* 386 - * xscale_icache_lock 387 - * 388 - * r0: starting address to lock 389 - * r1: end address to lock 390 - */ 391 - ENTRY(xscale_icache_lock) 392 - 393 - iLockLoop: 394 - bic r0, r0, #CACHELINESIZE - 1 395 - mcr p15, 0, r0, c9, c1, 0 @ lock into cache 396 - cmp r0, r1 @ are we done? 397 - add r0, r0, #CACHELINESIZE @ advance to next cache line 398 - bls iLockLoop 399 - mov pc, lr 400 - 401 - /* 402 - * xscale_icache_unlock 403 - */ 404 - ENTRY(xscale_icache_unlock) 405 - mcr p15, 0, r0, c9, c1, 1 @ Unlock icache 406 - mov pc, lr 407 - 408 - /* 409 - * xscale_dcache_lock 410 - * 411 - * r0: starting address to lock 412 - * r1: end address to lock 413 - */ 414 - ENTRY(xscale_dcache_lock) 415 - mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer 416 - mov r2, #1 417 - mcr p15, 0, r2, c9, c2, 0 @ Put dcache in lock mode 418 - cpwait ip @ Wait for completion 419 - 420 - mrs r2, cpsr 421 - orr r3, r2, #PSR_F_BIT | PSR_I_BIT 422 - dLockLoop: 423 - msr cpsr_c, r3 424 - mcr p15, 0, r0, c7, c10, 1 @ Write back line if it is dirty 425 - mcr p15, 0, r0, c7, c6, 1 @ Flush/invalidate line 426 - msr cpsr_c, r2 427 - ldr ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from 428 - @ location [r0]. Post-increment 429 - @ r3 to next cache line 430 - cmp r0, r1 @ Are we done? 431 - bls dLockLoop 432 - 433 - mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer 434 - mov r2, #0 435 - mcr p15, 0, r2, c9, c2, 0 @ Get out of lock mode 436 - cpwait_ret lr, ip 437 - 438 - /* 439 - * xscale_dcache_unlock 440 - */ 441 - ENTRY(xscale_dcache_unlock) 442 - mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer 443 - mcr p15, 0, ip, c9, c2, 1 @ Unlock cache 444 - mov pc, lr 445 - 446 - /* 447 - * Needed to determine the length of the code that needs to be copied. 448 - */ 449 - .align 5 450 - ENTRY(xscale_cache_dummy) 451 - mov pc, lr 452 - 453 - /* ================================ TLB LOCKING============================== 454 - * 455 - * The XScale MicroArchitecture implements support for locking entries into 456 - * the Instruction and Data TLBs. The following functions provide the 457 - * low level support for supporting these under Linux. xscale-lock.c 458 - * implements some higher level management code. Most of the following 459 - * is taken straight out of the Developer's Manual. 460 - */ 461 - 462 - /* 463 - * Lock I-TLB entry 464 - * 465 - * r0: Virtual address to translate and lock 466 - */ 467 - .align 5 468 - ENTRY(xscale_itlb_lock) 469 - mrs r2, cpsr 470 - orr r3, r2, #PSR_F_BIT | PSR_I_BIT 471 - msr cpsr_c, r3 @ Disable interrupts 472 - mcr p15, 0, r0, c8, c5, 1 @ Invalidate I-TLB entry 473 - mcr p15, 0, r0, c10, c4, 0 @ Translate and lock 474 - msr cpsr_c, r2 @ Restore interrupts 475 - cpwait_ret lr, ip 476 - 477 - /* 478 - * Lock D-TLB entry 479 - * 480 - * r0: Virtual address to translate and lock 481 - */ 482 - .align 5 483 - ENTRY(xscale_dtlb_lock) 484 - mrs r2, cpsr 485 - orr r3, r2, #PSR_F_BIT | PSR_I_BIT 486 - msr cpsr_c, r3 @ Disable interrupts 487 - mcr p15, 0, r0, c8, c6, 1 @ Invalidate D-TLB entry 488 - mcr p15, 0, r0, c10, c8, 0 @ Translate and lock 489 - msr cpsr_c, r2 @ Restore interrupts 490 - cpwait_ret lr, ip 491 - 492 - /* 493 - * Unlock all I-TLB entries 494 - */ 495 - .align 5 496 - ENTRY(xscale_itlb_unlock) 497 - mcr p15, 0, ip, c10, c4, 1 @ Unlock I-TLB 498 - mcr p15, 0, ip, c8, c5, 0 @ Invalidate I-TLB 499 - cpwait_ret lr, ip 500 - 501 - /* 502 - * Unlock all D-TLB entries 503 - */ 504 - ENTRY(xscale_dtlb_unlock) 505 - mcr p15, 0, ip, c10, c8, 1 @ Unlock D-TBL 506 - mcr p15, 0, ip, c8, c6, 0 @ Invalidate D-TLB 507 - cpwait_ret lr, ip 508 - 509 373 /* =============================== PageTable ============================== */ 510 374 511 375 #define PTE_CACHE_WRITE_ALLOCATE 0
+12 -12
arch/arm/nwfpe/double_cpdo.c
··· 40 40 float64 float64_pow(float64 rFn, float64 rFm); 41 41 float64 float64_pol(float64 rFn, float64 rFm); 42 42 43 - static float64 float64_rsf(float64 rFn, float64 rFm) 43 + static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm) 44 44 { 45 - return float64_sub(rFm, rFn); 45 + return float64_sub(roundData, rFm, rFn); 46 46 } 47 47 48 - static float64 float64_rdv(float64 rFn, float64 rFm) 48 + static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm) 49 49 { 50 - return float64_div(rFm, rFn); 50 + return float64_div(roundData, rFm, rFn); 51 51 } 52 52 53 - static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = { 53 + static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = { 54 54 [ADF_CODE >> 20] = float64_add, 55 55 [MUF_CODE >> 20] = float64_mul, 56 56 [SUF_CODE >> 20] = float64_sub, ··· 65 65 [FRD_CODE >> 20] = float64_rdv, 66 66 }; 67 67 68 - static float64 float64_mvf(float64 rFm) 68 + static float64 float64_mvf(struct roundingData *roundData,float64 rFm) 69 69 { 70 70 return rFm; 71 71 } 72 72 73 - static float64 float64_mnf(float64 rFm) 73 + static float64 float64_mnf(struct roundingData *roundData,float64 rFm) 74 74 { 75 75 union float64_components u; 76 76 ··· 84 84 return u.f64; 85 85 } 86 86 87 - static float64 float64_abs(float64 rFm) 87 + static float64 float64_abs(struct roundingData *roundData,float64 rFm) 88 88 { 89 89 union float64_components u; 90 90 ··· 98 98 return u.f64; 99 99 } 100 100 101 - static float64 (*const monadic_double[16])(float64 rFm) = { 101 + static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = { 102 102 [MVF_CODE >> 20] = float64_mvf, 103 103 [MNF_CODE >> 20] = float64_mnf, 104 104 [ABS_CODE >> 20] = float64_abs, ··· 108 108 [NRM_CODE >> 20] = float64_mvf, 109 109 }; 110 110 111 - unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd) 111 + unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) 112 112 { 113 113 FPA11 *fpa11 = GET_FPA11(); 114 114 float64 rFm; ··· 151 151 } 152 152 153 153 if (dyadic_double[opc_mask_shift]) { 154 - rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm); 154 + rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm); 155 155 } else { 156 156 return 0; 157 157 } 158 158 } else { 159 159 if (monadic_double[opc_mask_shift]) { 160 - rFd->fDouble = monadic_double[opc_mask_shift](rFm); 160 + rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm); 161 161 } else { 162 162 return 0; 163 163 }
+12 -12
arch/arm/nwfpe/extended_cpdo.c
··· 35 35 floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm); 36 36 floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm); 37 37 38 - static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm) 38 + static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm) 39 39 { 40 - return floatx80_sub(rFm, rFn); 40 + return floatx80_sub(roundData, rFm, rFn); 41 41 } 42 42 43 - static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm) 43 + static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm) 44 44 { 45 - return floatx80_div(rFm, rFn); 45 + return floatx80_div(roundData, rFm, rFn); 46 46 } 47 47 48 - static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = { 48 + static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = { 49 49 [ADF_CODE >> 20] = floatx80_add, 50 50 [MUF_CODE >> 20] = floatx80_mul, 51 51 [SUF_CODE >> 20] = floatx80_sub, ··· 60 60 [FRD_CODE >> 20] = floatx80_rdv, 61 61 }; 62 62 63 - static floatx80 floatx80_mvf(floatx80 rFm) 63 + static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm) 64 64 { 65 65 return rFm; 66 66 } 67 67 68 - static floatx80 floatx80_mnf(floatx80 rFm) 68 + static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm) 69 69 { 70 70 rFm.high ^= 0x8000; 71 71 return rFm; 72 72 } 73 73 74 - static floatx80 floatx80_abs(floatx80 rFm) 74 + static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm) 75 75 { 76 76 rFm.high &= 0x7fff; 77 77 return rFm; 78 78 } 79 79 80 - static floatx80 (*const monadic_extended[16])(floatx80 rFm) = { 80 + static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = { 81 81 [MVF_CODE >> 20] = floatx80_mvf, 82 82 [MNF_CODE >> 20] = floatx80_mnf, 83 83 [ABS_CODE >> 20] = floatx80_abs, ··· 87 87 [NRM_CODE >> 20] = floatx80_mvf, 88 88 }; 89 89 90 - unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd) 90 + unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) 91 91 { 92 92 FPA11 *fpa11 = GET_FPA11(); 93 93 floatx80 rFm; ··· 138 138 } 139 139 140 140 if (dyadic_extended[opc_mask_shift]) { 141 - rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm); 141 + rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm); 142 142 } else { 143 143 return 0; 144 144 } 145 145 } else { 146 146 if (monadic_extended[opc_mask_shift]) { 147 - rFd->fExtended = monadic_extended[opc_mask_shift](rFm); 147 + rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm); 148 148 } else { 149 149 return 0; 150 150 }
+11 -19
arch/arm/nwfpe/fpa11.c
··· 51 51 fpa11->fpsr = FP_EMULATOR | BIT_AC; 52 52 } 53 53 54 - void SetRoundingMode(const unsigned int opcode) 54 + int8 SetRoundingMode(const unsigned int opcode) 55 55 { 56 56 switch (opcode & MASK_ROUNDING_MODE) { 57 57 default: 58 58 case ROUND_TO_NEAREST: 59 - float_rounding_mode = float_round_nearest_even; 60 - break; 59 + return float_round_nearest_even; 61 60 62 61 case ROUND_TO_PLUS_INFINITY: 63 - float_rounding_mode = float_round_up; 64 - break; 62 + return float_round_up; 65 63 66 64 case ROUND_TO_MINUS_INFINITY: 67 - float_rounding_mode = float_round_down; 68 - break; 65 + return float_round_down; 69 66 70 67 case ROUND_TO_ZERO: 71 - float_rounding_mode = float_round_to_zero; 72 - break; 68 + return float_round_to_zero; 73 69 } 74 70 } 75 71 76 - void SetRoundingPrecision(const unsigned int opcode) 72 + int8 SetRoundingPrecision(const unsigned int opcode) 77 73 { 78 74 #ifdef CONFIG_FPE_NWFPE_XP 79 75 switch (opcode & MASK_ROUNDING_PRECISION) { 80 76 case ROUND_SINGLE: 81 - floatx80_rounding_precision = 32; 82 - break; 77 + return 32; 83 78 84 79 case ROUND_DOUBLE: 85 - floatx80_rounding_precision = 64; 86 - break; 80 + return 64; 87 81 88 82 case ROUND_EXTENDED: 89 - floatx80_rounding_precision = 80; 90 - break; 83 + return 80; 91 84 92 85 default: 93 - floatx80_rounding_precision = 80; 86 + return 80; 94 87 } 95 88 #endif 89 + return 80; 96 90 } 97 91 98 92 void nwfpe_init_fpa(union fp_state *fp) ··· 97 103 #endif 98 104 memset(fpa11, 0, sizeof(FPA11)); 99 105 resetFPA11(); 100 - SetRoundingMode(ROUND_TO_NEAREST); 101 - SetRoundingPrecision(ROUND_EXTENDED); 102 106 fpa11->initflag = 1; 103 107 } 104 108
+9 -2
arch/arm/nwfpe/fpa11.h
··· 37 37 /* includes */ 38 38 #include "fpsr.h" /* FP control and status register definitions */ 39 39 #include "milieu.h" 40 + 41 + struct roundingData { 42 + int8 mode; 43 + int8 precision; 44 + signed char exception; 45 + }; 46 + 40 47 #include "softfloat.h" 41 48 42 49 #define typeNone 0x00 ··· 91 84 initialised. */ 92 85 } FPA11; 93 86 94 - extern void SetRoundingMode(const unsigned int); 95 - extern void SetRoundingPrecision(const unsigned int); 87 + extern int8 SetRoundingMode(const unsigned int); 88 + extern int8 SetRoundingPrecision(const unsigned int); 96 89 extern void nwfpe_init_fpa(union fp_state *fp); 97 90 98 91 #endif
+17 -11
arch/arm/nwfpe/fpa11_cpdo.c
··· 24 24 #include "fpa11.h" 25 25 #include "fpopcode.h" 26 26 27 - unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd); 28 - unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd); 29 - unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd); 27 + unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); 28 + unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); 29 + unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); 30 30 31 31 unsigned int EmulateCPDO(const unsigned int opcode) 32 32 { 33 33 FPA11 *fpa11 = GET_FPA11(); 34 34 FPREG *rFd; 35 35 unsigned int nType, nDest, nRc; 36 + struct roundingData roundData; 36 37 37 38 /* Get the destination size. If not valid let Linux perform 38 39 an invalid instruction trap. */ ··· 41 40 if (typeNone == nDest) 42 41 return 0; 43 42 44 - SetRoundingMode(opcode); 43 + roundData.mode = SetRoundingMode(opcode); 44 + roundData.precision = SetRoundingPrecision(opcode); 45 + roundData.exception = 0; 45 46 46 47 /* Compare the size of the operands in Fn and Fm. 47 48 Choose the largest size and perform operations in that size, ··· 66 63 67 64 switch (nType) { 68 65 case typeSingle: 69 - nRc = SingleCPDO(opcode, rFd); 66 + nRc = SingleCPDO(&roundData, opcode, rFd); 70 67 break; 71 68 case typeDouble: 72 - nRc = DoubleCPDO(opcode, rFd); 69 + nRc = DoubleCPDO(&roundData, opcode, rFd); 73 70 break; 74 71 #ifdef CONFIG_FPE_NWFPE_XP 75 72 case typeExtended: 76 - nRc = ExtendedCPDO(opcode, rFd); 73 + nRc = ExtendedCPDO(&roundData, opcode, rFd); 77 74 break; 78 75 #endif 79 76 default: ··· 96 93 case typeSingle: 97 94 { 98 95 if (typeDouble == nType) 99 - rFd->fSingle = float64_to_float32(rFd->fDouble); 96 + rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble); 100 97 else 101 - rFd->fSingle = floatx80_to_float32(rFd->fExtended); 98 + rFd->fSingle = floatx80_to_float32(&roundData, rFd->fExtended); 102 99 } 103 100 break; 104 101 ··· 107 104 if (typeSingle == nType) 108 105 rFd->fDouble = float32_to_float64(rFd->fSingle); 109 106 else 110 - rFd->fDouble = floatx80_to_float64(rFd->fExtended); 107 + rFd->fDouble = floatx80_to_float64(&roundData, rFd->fExtended); 111 108 } 112 109 break; 113 110 ··· 124 121 #else 125 122 if (nDest != nType) { 126 123 if (nDest == typeSingle) 127 - rFd->fSingle = float64_to_float32(rFd->fDouble); 124 + rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble); 128 125 else 129 126 rFd->fDouble = float32_to_float64(rFd->fSingle); 130 127 } 131 128 #endif 132 129 } 130 + 131 + if (roundData.exception) 132 + float_raise(roundData.exception); 133 133 134 134 return nRc; 135 135 }
+14 -8
arch/arm/nwfpe/fpa11_cpdt.c
··· 96 96 } 97 97 } 98 98 99 - static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem) 99 + static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem) 100 100 { 101 101 FPA11 *fpa11 = GET_FPA11(); 102 102 union { ··· 106 106 107 107 switch (fpa11->fType[Fn]) { 108 108 case typeDouble: 109 - val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble); 109 + val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble); 110 110 break; 111 111 112 112 #ifdef CONFIG_FPE_NWFPE_XP 113 113 case typeExtended: 114 - val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); 114 + val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended); 115 115 break; 116 116 #endif 117 117 ··· 122 122 put_user(val.i[0], pMem); 123 123 } 124 124 125 - static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem) 125 + static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem) 126 126 { 127 127 FPA11 *fpa11 = GET_FPA11(); 128 128 union { ··· 137 137 138 138 #ifdef CONFIG_FPE_NWFPE_XP 139 139 case typeExtended: 140 - val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); 140 + val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended); 141 141 break; 142 142 #endif 143 143 ··· 259 259 { 260 260 unsigned int __user *pBase, *pAddress, *pFinal; 261 261 unsigned int nRc = 1, write_back = WRITE_BACK(opcode); 262 + struct roundingData roundData; 262 263 263 - SetRoundingMode(ROUND_TO_NEAREST); 264 + roundData.mode = SetRoundingMode(opcode); 265 + roundData.precision = SetRoundingPrecision(opcode); 266 + roundData.exception = 0; 264 267 265 268 pBase = (unsigned int __user *) readRegister(getRn(opcode)); 266 269 if (REG_PC == getRn(opcode)) { ··· 284 281 285 282 switch (opcode & MASK_TRANSFER_LENGTH) { 286 283 case TRANSFER_SINGLE: 287 - storeSingle(getFd(opcode), pAddress); 284 + storeSingle(&roundData, getFd(opcode), pAddress); 288 285 break; 289 286 case TRANSFER_DOUBLE: 290 - storeDouble(getFd(opcode), pAddress); 287 + storeDouble(&roundData, getFd(opcode), pAddress); 291 288 break; 292 289 #ifdef CONFIG_FPE_NWFPE_XP 293 290 case TRANSFER_EXTENDED: ··· 297 294 default: 298 295 nRc = 0; 299 296 } 297 + 298 + if (roundData.exception) 299 + float_raise(roundData.exception); 300 300 301 301 if (write_back) 302 302 writeRegister(getRn(opcode), (unsigned long) pFinal);
+19 -9
arch/arm/nwfpe/fpa11_cprt.c
··· 33 33 extern flag float64_is_nan(float64); 34 34 extern flag float32_is_nan(float32); 35 35 36 - void SetRoundingMode(const unsigned int opcode); 37 - 38 36 unsigned int PerformFLT(const unsigned int opcode); 39 37 unsigned int PerformFIX(const unsigned int opcode); 40 38 ··· 75 77 unsigned int PerformFLT(const unsigned int opcode) 76 78 { 77 79 FPA11 *fpa11 = GET_FPA11(); 78 - SetRoundingMode(opcode); 79 - SetRoundingPrecision(opcode); 80 + struct roundingData roundData; 81 + 82 + roundData.mode = SetRoundingMode(opcode); 83 + roundData.precision = SetRoundingPrecision(opcode); 84 + roundData.exception = 0; 80 85 81 86 switch (opcode & MASK_ROUNDING_PRECISION) { 82 87 case ROUND_SINGLE: 83 88 { 84 89 fpa11->fType[getFn(opcode)] = typeSingle; 85 - fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode))); 90 + fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode))); 86 91 } 87 92 break; 88 93 ··· 109 108 return 0; 110 109 } 111 110 111 + if (roundData.exception) 112 + float_raise(roundData.exception); 113 + 112 114 return 1; 113 115 } 114 116 ··· 119 115 { 120 116 FPA11 *fpa11 = GET_FPA11(); 121 117 unsigned int Fn = getFm(opcode); 118 + struct roundingData roundData; 122 119 123 - SetRoundingMode(opcode); 120 + roundData.mode = SetRoundingMode(opcode); 121 + roundData.precision = SetRoundingPrecision(opcode); 122 + roundData.exception = 0; 124 123 125 124 switch (fpa11->fType[Fn]) { 126 125 case typeSingle: 127 126 { 128 - writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle)); 127 + writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle)); 129 128 } 130 129 break; 131 130 132 131 case typeDouble: 133 132 { 134 - writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble)); 133 + writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble)); 135 134 } 136 135 break; 137 136 138 137 #ifdef CONFIG_FPE_NWFPE_XP 139 138 case typeExtended: 140 139 { 141 - writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); 140 + writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended)); 142 141 } 143 142 break; 144 143 #endif ··· 149 142 default: 150 143 return 0; 151 144 } 145 + 146 + if (roundData.exception) 147 + float_raise(roundData.exception); 152 148 153 149 return 1; 154 150 }
+6 -9
arch/arm/nwfpe/fpmodule.c
··· 116 116 code to access data in user space in some other source files at the 117 117 moment (grep for get_user / put_user calls). --philb] 118 118 119 - float_exception_flags is a global variable in SoftFloat. 120 - 121 119 This function is called by the SoftFloat routines to raise a floating 122 120 point exception. We check the trap enable byte in the FPSR, and raise 123 121 a SIGFPE exception if necessary. If not the relevant bits in the ··· 127 129 register unsigned int fpsr, cumulativeTraps; 128 130 129 131 #ifdef CONFIG_DEBUG_USER 130 - printk(KERN_DEBUG 131 - "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", 132 - current->comm, current->pid, flags, 133 - __builtin_return_address(0), GET_USERREG()->ARM_pc); 132 + /* Ignore inexact errors as there are far too many of them to log */ 133 + if (flags & ~BIT_IXC) 134 + printk(KERN_DEBUG 135 + "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", 136 + current->comm, current->pid, flags, 137 + __builtin_return_address(0), GET_USERREG()->ARM_pc); 134 138 #endif 135 - 136 - /* Keep SoftFloat exception flags up to date. */ 137 - float_exception_flags |= flags; 138 139 139 140 /* Read fpsr and initialize the cumulativeTraps. */ 140 141 fpsr = readFPSR();
+12 -12
arch/arm/nwfpe/single_cpdo.c
··· 36 36 float32 float32_pow(float32 rFn, float32 rFm); 37 37 float32 float32_pol(float32 rFn, float32 rFm); 38 38 39 - static float32 float32_rsf(float32 rFn, float32 rFm) 39 + static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm) 40 40 { 41 - return float32_sub(rFm, rFn); 41 + return float32_sub(roundData, rFm, rFn); 42 42 } 43 43 44 - static float32 float32_rdv(float32 rFn, float32 rFm) 44 + static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm) 45 45 { 46 - return float32_div(rFm, rFn); 46 + return float32_div(roundData, rFm, rFn); 47 47 } 48 48 49 - static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { 49 + static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = { 50 50 [ADF_CODE >> 20] = float32_add, 51 51 [MUF_CODE >> 20] = float32_mul, 52 52 [SUF_CODE >> 20] = float32_sub, ··· 60 60 [FRD_CODE >> 20] = float32_rdv, 61 61 }; 62 62 63 - static float32 float32_mvf(float32 rFm) 63 + static float32 float32_mvf(struct roundingData *roundData, float32 rFm) 64 64 { 65 65 return rFm; 66 66 } 67 67 68 - static float32 float32_mnf(float32 rFm) 68 + static float32 float32_mnf(struct roundingData *roundData, float32 rFm) 69 69 { 70 70 return rFm ^ 0x80000000; 71 71 } 72 72 73 - static float32 float32_abs(float32 rFm) 73 + static float32 float32_abs(struct roundingData *roundData, float32 rFm) 74 74 { 75 75 return rFm & 0x7fffffff; 76 76 } 77 77 78 - static float32 (*const monadic_single[16])(float32 rFm) = { 78 + static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = { 79 79 [MVF_CODE >> 20] = float32_mvf, 80 80 [MNF_CODE >> 20] = float32_mnf, 81 81 [ABS_CODE >> 20] = float32_abs, ··· 85 85 [NRM_CODE >> 20] = float32_mvf, 86 86 }; 87 87 88 - unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) 88 + unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) 89 89 { 90 90 FPA11 *fpa11 = GET_FPA11(); 91 91 float32 rFm; ··· 108 108 if (fpa11->fType[Fn] == typeSingle && 109 109 dyadic_single[opc_mask_shift]) { 110 110 rFn = fpa11->fpreg[Fn].fSingle; 111 - rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm); 111 + rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm); 112 112 } else { 113 113 return 0; 114 114 } 115 115 } else { 116 116 if (monadic_single[opc_mask_shift]) { 117 - rFd->fSingle = monadic_single[opc_mask_shift](rFm); 117 + rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm); 118 118 } else { 119 119 return 0; 120 120 }
+163 -171
arch/arm/nwfpe/softfloat.c
··· 36 36 37 37 /* 38 38 ------------------------------------------------------------------------------- 39 - Floating-point rounding mode, extended double-precision rounding precision, 40 - and exception flags. 41 - ------------------------------------------------------------------------------- 42 - */ 43 - int8 float_rounding_mode = float_round_nearest_even; 44 - int8 floatx80_rounding_precision = 80; 45 - int8 float_exception_flags; 46 - 47 - /* 48 - ------------------------------------------------------------------------------- 49 39 Primitive arithmetic functions, including multi-word arithmetic, and 50 40 division and square root approximations. (Can be specialized to target if 51 41 desired.) ··· 67 77 positive or negative integer is returned. 68 78 ------------------------------------------------------------------------------- 69 79 */ 70 - static int32 roundAndPackInt32( flag zSign, bits64 absZ ) 80 + static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ ) 71 81 { 72 82 int8 roundingMode; 73 83 flag roundNearestEven; 74 84 int8 roundIncrement, roundBits; 75 85 int32 z; 76 86 77 - roundingMode = float_rounding_mode; 87 + roundingMode = roundData->mode; 78 88 roundNearestEven = ( roundingMode == float_round_nearest_even ); 79 89 roundIncrement = 0x40; 80 90 if ( ! roundNearestEven ) { ··· 97 107 z = absZ; 98 108 if ( zSign ) z = - z; 99 109 if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { 100 - float_exception_flags |= float_flag_invalid; 110 + roundData->exception |= float_flag_invalid; 101 111 return zSign ? 0x80000000 : 0x7FFFFFFF; 102 112 } 103 - if ( roundBits ) float_exception_flags |= float_flag_inexact; 113 + if ( roundBits ) roundData->exception |= float_flag_inexact; 104 114 return z; 105 115 106 116 } ··· 214 224 Binary Floating-point Arithmetic. 215 225 ------------------------------------------------------------------------------- 216 226 */ 217 - static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) 227 + static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig ) 218 228 { 219 229 int8 roundingMode; 220 230 flag roundNearestEven; 221 231 int8 roundIncrement, roundBits; 222 232 flag isTiny; 223 233 224 - roundingMode = float_rounding_mode; 234 + roundingMode = roundData->mode; 225 235 roundNearestEven = ( roundingMode == float_round_nearest_even ); 226 236 roundIncrement = 0x40; 227 237 if ( ! roundNearestEven ) { ··· 244 254 || ( ( zExp == 0xFD ) 245 255 && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) 246 256 ) { 247 - float_raise( float_flag_overflow | float_flag_inexact ); 257 + roundData->exception |= float_flag_overflow | float_flag_inexact; 248 258 return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); 249 259 } 250 260 if ( zExp < 0 ) { ··· 255 265 shift32RightJamming( zSig, - zExp, &zSig ); 256 266 zExp = 0; 257 267 roundBits = zSig & 0x7F; 258 - if ( isTiny && roundBits ) float_raise( float_flag_underflow ); 268 + if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow; 259 269 } 260 270 } 261 - if ( roundBits ) float_exception_flags |= float_flag_inexact; 271 + if ( roundBits ) roundData->exception |= float_flag_inexact; 262 272 zSig = ( zSig + roundIncrement )>>7; 263 273 zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); 264 274 if ( zSig == 0 ) zExp = 0; ··· 277 287 ------------------------------------------------------------------------------- 278 288 */ 279 289 static float32 280 - normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) 290 + normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig ) 281 291 { 282 292 int8 shiftCount; 283 293 284 294 shiftCount = countLeadingZeros32( zSig ) - 1; 285 - return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount ); 295 + return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount ); 286 296 287 297 } 288 298 ··· 385 395 Binary Floating-point Arithmetic. 386 396 ------------------------------------------------------------------------------- 387 397 */ 388 - static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) 398 + static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig ) 389 399 { 390 400 int8 roundingMode; 391 401 flag roundNearestEven; 392 402 int16 roundIncrement, roundBits; 393 403 flag isTiny; 394 404 395 - roundingMode = float_rounding_mode; 405 + roundingMode = roundData->mode; 396 406 roundNearestEven = ( roundingMode == float_round_nearest_even ); 397 407 roundIncrement = 0x200; 398 408 if ( ! roundNearestEven ) { ··· 417 427 ) { 418 428 //register int lr = __builtin_return_address(0); 419 429 //printk("roundAndPackFloat64 called from 0x%08x\n",lr); 420 - float_raise( float_flag_overflow | float_flag_inexact ); 430 + roundData->exception |= float_flag_overflow | float_flag_inexact; 421 431 return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 ); 422 432 } 423 433 if ( zExp < 0 ) { ··· 428 438 shift64RightJamming( zSig, - zExp, &zSig ); 429 439 zExp = 0; 430 440 roundBits = zSig & 0x3FF; 431 - if ( isTiny && roundBits ) float_raise( float_flag_underflow ); 441 + if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow; 432 442 } 433 443 } 434 - if ( roundBits ) float_exception_flags |= float_flag_inexact; 444 + if ( roundBits ) roundData->exception |= float_flag_inexact; 435 445 zSig = ( zSig + roundIncrement )>>10; 436 446 zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); 437 447 if ( zSig == 0 ) zExp = 0; ··· 450 460 ------------------------------------------------------------------------------- 451 461 */ 452 462 static float64 453 - normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) 463 + normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig ) 454 464 { 455 465 int8 shiftCount; 456 466 457 467 shiftCount = countLeadingZeros64( zSig ) - 1; 458 - return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount ); 468 + return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount ); 459 469 460 470 } 461 471 ··· 562 572 */ 563 573 static floatx80 564 574 roundAndPackFloatx80( 565 - int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 575 + struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 566 576 ) 567 577 { 568 - int8 roundingMode; 578 + int8 roundingMode, roundingPrecision; 569 579 flag roundNearestEven, increment, isTiny; 570 580 int64 roundIncrement, roundMask, roundBits; 571 581 572 - roundingMode = float_rounding_mode; 582 + roundingMode = roundData->mode; 583 + roundingPrecision = roundData->precision; 573 584 roundNearestEven = ( roundingMode == float_round_nearest_even ); 574 585 if ( roundingPrecision == 80 ) goto precision80; 575 586 if ( roundingPrecision == 64 ) { ··· 614 623 shift64RightJamming( zSig0, 1 - zExp, &zSig0 ); 615 624 zExp = 0; 616 625 roundBits = zSig0 & roundMask; 617 - if ( isTiny && roundBits ) float_raise( float_flag_underflow ); 618 - if ( roundBits ) float_exception_flags |= float_flag_inexact; 626 + if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow; 627 + if ( roundBits ) roundData->exception |= float_flag_inexact; 619 628 zSig0 += roundIncrement; 620 629 if ( (sbits64) zSig0 < 0 ) zExp = 1; 621 630 roundIncrement = roundMask + 1; ··· 626 635 return packFloatx80( zSign, zExp, zSig0 ); 627 636 } 628 637 } 629 - if ( roundBits ) float_exception_flags |= float_flag_inexact; 638 + if ( roundBits ) roundData->exception |= float_flag_inexact; 630 639 zSig0 += roundIncrement; 631 640 if ( zSig0 < roundIncrement ) { 632 641 ++zExp; ··· 663 672 ) { 664 673 roundMask = 0; 665 674 overflow: 666 - float_raise( float_flag_overflow | float_flag_inexact ); 675 + roundData->exception |= float_flag_overflow | float_flag_inexact; 667 676 if ( ( roundingMode == float_round_to_zero ) 668 677 || ( zSign && ( roundingMode == float_round_up ) ) 669 678 || ( ! zSign && ( roundingMode == float_round_down ) ) ··· 680 689 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) ); 681 690 shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 ); 682 691 zExp = 0; 683 - if ( isTiny && zSig1 ) float_raise( float_flag_underflow ); 684 - if ( zSig1 ) float_exception_flags |= float_flag_inexact; 692 + if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow; 693 + if ( zSig1 ) roundData->exception |= float_flag_inexact; 685 694 if ( roundNearestEven ) { 686 695 increment = ( (sbits64) zSig1 < 0 ); 687 696 } ··· 701 710 return packFloatx80( zSign, zExp, zSig0 ); 702 711 } 703 712 } 704 - if ( zSig1 ) float_exception_flags |= float_flag_inexact; 713 + if ( zSig1 ) roundData->exception |= float_flag_inexact; 705 714 if ( increment ) { 706 715 ++zSig0; 707 716 if ( zSig0 == 0 ) { ··· 731 740 */ 732 741 static floatx80 733 742 normalizeRoundAndPackFloatx80( 734 - int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 743 + struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 735 744 ) 736 745 { 737 746 int8 shiftCount; ··· 745 754 shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); 746 755 zExp -= shiftCount; 747 756 return 748 - roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 ); 757 + roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 ); 749 758 750 759 } 751 760 ··· 758 767 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. 759 768 ------------------------------------------------------------------------------- 760 769 */ 761 - float32 int32_to_float32( int32 a ) 770 + float32 int32_to_float32(struct roundingData *roundData, int32 a) 762 771 { 763 772 flag zSign; 764 773 765 774 if ( a == 0 ) return 0; 766 775 if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); 767 776 zSign = ( a < 0 ); 768 - return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a ); 777 + return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a ); 769 778 770 779 } 771 780 ··· 831 840 largest integer with the same sign as `a' is returned. 832 841 ------------------------------------------------------------------------------- 833 842 */ 834 - int32 float32_to_int32( float32 a ) 843 + int32 float32_to_int32( struct roundingData *roundData, float32 a ) 835 844 { 836 845 flag aSign; 837 846 int16 aExp, shiftCount; ··· 847 856 zSig = aSig; 848 857 zSig <<= 32; 849 858 if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig ); 850 - return roundAndPackInt32( aSign, zSig ); 859 + return roundAndPackInt32( roundData, aSign, zSig ); 851 860 852 861 } 853 862 ··· 880 889 return 0x80000000; 881 890 } 882 891 else if ( aExp <= 0x7E ) { 883 - if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; 892 + if ( aExp | aSig ) float_raise( float_flag_inexact ); 884 893 return 0; 885 894 } 886 895 aSig = ( aSig | 0x00800000 )<<8; 887 896 z = aSig>>( - shiftCount ); 888 897 if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { 889 - float_exception_flags |= float_flag_inexact; 898 + float_raise( float_flag_inexact ); 890 899 } 891 900 return aSign ? - z : z; 892 901 ··· 964 973 Floating-point Arithmetic. 965 974 ------------------------------------------------------------------------------- 966 975 */ 967 - float32 float32_round_to_int( float32 a ) 976 + float32 float32_round_to_int( struct roundingData *roundData, float32 a ) 968 977 { 969 978 flag aSign; 970 979 int16 aExp; ··· 979 988 } 980 989 return a; 981 990 } 991 + roundingMode = roundData->mode; 982 992 if ( aExp <= 0x7E ) { 983 993 if ( (bits32) ( a<<1 ) == 0 ) return a; 984 - float_exception_flags |= float_flag_inexact; 994 + roundData->exception |= float_flag_inexact; 985 995 aSign = extractFloat32Sign( a ); 986 - switch ( float_rounding_mode ) { 996 + switch ( roundingMode ) { 987 997 case float_round_nearest_even: 988 998 if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { 989 999 return packFloat32( aSign, 0x7F, 0 ); ··· 1001 1009 lastBitMask <<= 0x96 - aExp; 1002 1010 roundBitsMask = lastBitMask - 1; 1003 1011 z = a; 1004 - roundingMode = float_rounding_mode; 1005 1012 if ( roundingMode == float_round_nearest_even ) { 1006 1013 z += lastBitMask>>1; 1007 1014 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; ··· 1011 1020 } 1012 1021 } 1013 1022 z &= ~ roundBitsMask; 1014 - if ( z != a ) float_exception_flags |= float_flag_inexact; 1023 + if ( z != a ) roundData->exception |= float_flag_inexact; 1015 1024 return z; 1016 1025 1017 1026 } ··· 1025 1034 Floating-point Arithmetic. 1026 1035 ------------------------------------------------------------------------------- 1027 1036 */ 1028 - static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) 1037 + static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign ) 1029 1038 { 1030 1039 int16 aExp, bExp, zExp; 1031 1040 bits32 aSig, bSig, zSig; ··· 1084 1093 ++zExp; 1085 1094 } 1086 1095 roundAndPack: 1087 - return roundAndPackFloat32( zSign, zExp, zSig ); 1096 + return roundAndPackFloat32( roundData, zSign, zExp, zSig ); 1088 1097 1089 1098 } 1090 1099 ··· 1097 1106 Standard for Binary Floating-point Arithmetic. 1098 1107 ------------------------------------------------------------------------------- 1099 1108 */ 1100 - static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) 1109 + static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign ) 1101 1110 { 1102 1111 int16 aExp, bExp, zExp; 1103 1112 bits32 aSig, bSig, zSig; ··· 1114 1123 if ( expDiff < 0 ) goto bExpBigger; 1115 1124 if ( aExp == 0xFF ) { 1116 1125 if ( aSig | bSig ) return propagateFloat32NaN( a, b ); 1117 - float_raise( float_flag_invalid ); 1126 + roundData->exception |= float_flag_invalid; 1118 1127 return float32_default_nan; 1119 1128 } 1120 1129 if ( aExp == 0 ) { ··· 1123 1132 } 1124 1133 if ( bSig < aSig ) goto aBigger; 1125 1134 if ( aSig < bSig ) goto bBigger; 1126 - return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); 1135 + return packFloat32( roundData->mode == float_round_down, 0, 0 ); 1127 1136 bExpBigger: 1128 1137 if ( bExp == 0xFF ) { 1129 1138 if ( bSig ) return propagateFloat32NaN( a, b ); ··· 1160 1169 zExp = aExp; 1161 1170 normalizeRoundAndPack: 1162 1171 --zExp; 1163 - return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); 1172 + return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig ); 1164 1173 1165 1174 } 1166 1175 ··· 1171 1180 Binary Floating-point Arithmetic. 1172 1181 ------------------------------------------------------------------------------- 1173 1182 */ 1174 - float32 float32_add( float32 a, float32 b ) 1183 + float32 float32_add( struct roundingData *roundData, float32 a, float32 b ) 1175 1184 { 1176 1185 flag aSign, bSign; 1177 1186 1178 1187 aSign = extractFloat32Sign( a ); 1179 1188 bSign = extractFloat32Sign( b ); 1180 1189 if ( aSign == bSign ) { 1181 - return addFloat32Sigs( a, b, aSign ); 1190 + return addFloat32Sigs( roundData, a, b, aSign ); 1182 1191 } 1183 1192 else { 1184 - return subFloat32Sigs( a, b, aSign ); 1193 + return subFloat32Sigs( roundData, a, b, aSign ); 1185 1194 } 1186 1195 1187 1196 } ··· 1193 1202 for Binary Floating-point Arithmetic. 1194 1203 ------------------------------------------------------------------------------- 1195 1204 */ 1196 - float32 float32_sub( float32 a, float32 b ) 1205 + float32 float32_sub( struct roundingData *roundData, float32 a, float32 b ) 1197 1206 { 1198 1207 flag aSign, bSign; 1199 1208 1200 1209 aSign = extractFloat32Sign( a ); 1201 1210 bSign = extractFloat32Sign( b ); 1202 1211 if ( aSign == bSign ) { 1203 - return subFloat32Sigs( a, b, aSign ); 1212 + return subFloat32Sigs( roundData, a, b, aSign ); 1204 1213 } 1205 1214 else { 1206 - return addFloat32Sigs( a, b, aSign ); 1215 + return addFloat32Sigs( roundData, a, b, aSign ); 1207 1216 } 1208 1217 1209 1218 } ··· 1215 1224 for Binary Floating-point Arithmetic. 1216 1225 ------------------------------------------------------------------------------- 1217 1226 */ 1218 - float32 float32_mul( float32 a, float32 b ) 1227 + float32 float32_mul( struct roundingData *roundData, float32 a, float32 b ) 1219 1228 { 1220 1229 flag aSign, bSign, zSign; 1221 1230 int16 aExp, bExp, zExp; ··· 1235 1244 return propagateFloat32NaN( a, b ); 1236 1245 } 1237 1246 if ( ( bExp | bSig ) == 0 ) { 1238 - float_raise( float_flag_invalid ); 1247 + roundData->exception |= float_flag_invalid; 1239 1248 return float32_default_nan; 1240 1249 } 1241 1250 return packFloat32( zSign, 0xFF, 0 ); ··· 1243 1252 if ( bExp == 0xFF ) { 1244 1253 if ( bSig ) return propagateFloat32NaN( a, b ); 1245 1254 if ( ( aExp | aSig ) == 0 ) { 1246 - float_raise( float_flag_invalid ); 1255 + roundData->exception |= float_flag_invalid; 1247 1256 return float32_default_nan; 1248 1257 } 1249 1258 return packFloat32( zSign, 0xFF, 0 ); ··· 1265 1274 zSig <<= 1; 1266 1275 --zExp; 1267 1276 } 1268 - return roundAndPackFloat32( zSign, zExp, zSig ); 1277 + return roundAndPackFloat32( roundData, zSign, zExp, zSig ); 1269 1278 1270 1279 } 1271 1280 ··· 1276 1285 IEC/IEEE Standard for Binary Floating-point Arithmetic. 1277 1286 ------------------------------------------------------------------------------- 1278 1287 */ 1279 - float32 float32_div( float32 a, float32 b ) 1288 + float32 float32_div( struct roundingData *roundData, float32 a, float32 b ) 1280 1289 { 1281 1290 flag aSign, bSign, zSign; 1282 1291 int16 aExp, bExp, zExp; ··· 1293 1302 if ( aSig ) return propagateFloat32NaN( a, b ); 1294 1303 if ( bExp == 0xFF ) { 1295 1304 if ( bSig ) return propagateFloat32NaN( a, b ); 1296 - float_raise( float_flag_invalid ); 1305 + roundData->exception |= float_flag_invalid; 1297 1306 return float32_default_nan; 1298 1307 } 1299 1308 return packFloat32( zSign, 0xFF, 0 ); ··· 1305 1314 if ( bExp == 0 ) { 1306 1315 if ( bSig == 0 ) { 1307 1316 if ( ( aExp | aSig ) == 0 ) { 1308 - float_raise( float_flag_invalid ); 1317 + roundData->exception |= float_flag_invalid; 1309 1318 return float32_default_nan; 1310 1319 } 1311 - float_raise( float_flag_divbyzero ); 1320 + roundData->exception |= float_flag_divbyzero; 1312 1321 return packFloat32( zSign, 0xFF, 0 ); 1313 1322 } 1314 1323 normalizeFloat32Subnormal( bSig, &bExp, &bSig ); ··· 1332 1341 if ( ( zSig & 0x3F ) == 0 ) { 1333 1342 zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 ); 1334 1343 } 1335 - return roundAndPackFloat32( zSign, zExp, zSig ); 1344 + return roundAndPackFloat32( roundData, zSign, zExp, zSig ); 1336 1345 1337 1346 } 1338 1347 ··· 1343 1352 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. 1344 1353 ------------------------------------------------------------------------------- 1345 1354 */ 1346 - float32 float32_rem( float32 a, float32 b ) 1355 + float32 float32_rem( struct roundingData *roundData, float32 a, float32 b ) 1347 1356 { 1348 1357 flag aSign, bSign, zSign; 1349 1358 int16 aExp, bExp, expDiff; ··· 1363 1372 if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { 1364 1373 return propagateFloat32NaN( a, b ); 1365 1374 } 1366 - float_raise( float_flag_invalid ); 1375 + roundData->exception |= float_flag_invalid; 1367 1376 return float32_default_nan; 1368 1377 } 1369 1378 if ( bExp == 0xFF ) { ··· 1372 1381 } 1373 1382 if ( bExp == 0 ) { 1374 1383 if ( bSig == 0 ) { 1375 - float_raise( float_flag_invalid ); 1384 + roundData->exception |= float_flag_invalid; 1376 1385 return float32_default_nan; 1377 1386 } 1378 1387 normalizeFloat32Subnormal( bSig, &bExp, &bSig ); ··· 1435 1444 } 1436 1445 zSign = ( (sbits32) aSig < 0 ); 1437 1446 if ( zSign ) aSig = - aSig; 1438 - return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); 1447 + return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig ); 1439 1448 1440 1449 } 1441 1450 ··· 1446 1455 Floating-point Arithmetic. 1447 1456 ------------------------------------------------------------------------------- 1448 1457 */ 1449 - float32 float32_sqrt( float32 a ) 1458 + float32 float32_sqrt( struct roundingData *roundData, float32 a ) 1450 1459 { 1451 1460 flag aSign; 1452 1461 int16 aExp, zExp; ··· 1459 1468 if ( aExp == 0xFF ) { 1460 1469 if ( aSig ) return propagateFloat32NaN( a, 0 ); 1461 1470 if ( ! aSign ) return a; 1462 - float_raise( float_flag_invalid ); 1471 + roundData->exception |= float_flag_invalid; 1463 1472 return float32_default_nan; 1464 1473 } 1465 1474 if ( aSign ) { 1466 1475 if ( ( aExp | aSig ) == 0 ) return a; 1467 - float_raise( float_flag_invalid ); 1476 + roundData->exception |= float_flag_invalid; 1468 1477 return float32_default_nan; 1469 1478 } 1470 1479 if ( aExp == 0 ) { ··· 1490 1499 } 1491 1500 } 1492 1501 shift32RightJamming( zSig, 1, &zSig ); 1493 - return roundAndPackFloat32( 0, zExp, zSig ); 1502 + return roundAndPackFloat32( roundData, 0, zExp, zSig ); 1494 1503 1495 1504 } 1496 1505 ··· 1652 1661 largest integer with the same sign as `a' is returned. 1653 1662 ------------------------------------------------------------------------------- 1654 1663 */ 1655 - int32 float64_to_int32( float64 a ) 1664 + int32 float64_to_int32( struct roundingData *roundData, float64 a ) 1656 1665 { 1657 1666 flag aSign; 1658 1667 int16 aExp, shiftCount; ··· 1665 1674 if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); 1666 1675 shiftCount = 0x42C - aExp; 1667 1676 if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); 1668 - return roundAndPackInt32( aSign, aSig ); 1677 + return roundAndPackInt32( roundData, aSign, aSig ); 1669 1678 1670 1679 } 1671 1680 ··· 1696 1705 goto invalid; 1697 1706 } 1698 1707 else if ( 52 < shiftCount ) { 1699 - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; 1708 + if ( aExp || aSig ) float_raise( float_flag_inexact ); 1700 1709 return 0; 1701 1710 } 1702 1711 aSig |= LIT64( 0x0010000000000000 ); ··· 1706 1715 if ( aSign ) z = - z; 1707 1716 if ( ( z < 0 ) ^ aSign ) { 1708 1717 invalid: 1709 - float_exception_flags |= float_flag_invalid; 1718 + float_raise( float_flag_invalid ); 1710 1719 return aSign ? 0x80000000 : 0x7FFFFFFF; 1711 1720 } 1712 1721 if ( ( aSig<<shiftCount ) != savedASig ) { 1713 - float_exception_flags |= float_flag_inexact; 1722 + float_raise( float_flag_inexact ); 1714 1723 } 1715 1724 return z; 1716 1725 ··· 1727 1736 largest positive integer is returned. 1728 1737 ------------------------------------------------------------------------------- 1729 1738 */ 1730 - int32 float64_to_uint32( float64 a ) 1739 + int32 float64_to_uint32( struct roundingData *roundData, float64 a ) 1731 1740 { 1732 1741 flag aSign; 1733 1742 int16 aExp, shiftCount; ··· 1740 1749 if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); 1741 1750 shiftCount = 0x42C - aExp; 1742 1751 if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); 1743 - return roundAndPackInt32( aSign, aSig ); 1752 + return roundAndPackInt32( roundData, aSign, aSig ); 1744 1753 } 1745 1754 1746 1755 /* ··· 1769 1778 goto invalid; 1770 1779 } 1771 1780 else if ( 52 < shiftCount ) { 1772 - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; 1781 + if ( aExp || aSig ) float_raise( float_flag_inexact ); 1773 1782 return 0; 1774 1783 } 1775 1784 aSig |= LIT64( 0x0010000000000000 ); ··· 1779 1788 if ( aSign ) z = - z; 1780 1789 if ( ( z < 0 ) ^ aSign ) { 1781 1790 invalid: 1782 - float_exception_flags |= float_flag_invalid; 1791 + float_raise( float_flag_invalid ); 1783 1792 return aSign ? 0x80000000 : 0x7FFFFFFF; 1784 1793 } 1785 1794 if ( ( aSig<<shiftCount ) != savedASig ) { 1786 - float_exception_flags |= float_flag_inexact; 1795 + float_raise( float_flag_inexact ); 1787 1796 } 1788 1797 return z; 1789 1798 } ··· 1796 1805 Arithmetic. 1797 1806 ------------------------------------------------------------------------------- 1798 1807 */ 1799 - float32 float64_to_float32( float64 a ) 1808 + float32 float64_to_float32( struct roundingData *roundData, float64 a ) 1800 1809 { 1801 1810 flag aSign; 1802 1811 int16 aExp; ··· 1816 1825 zSig |= 0x40000000; 1817 1826 aExp -= 0x381; 1818 1827 } 1819 - return roundAndPackFloat32( aSign, aExp, zSig ); 1828 + return roundAndPackFloat32( roundData, aSign, aExp, zSig ); 1820 1829 1821 1830 } 1822 1831 ··· 1863 1872 Floating-point Arithmetic. 1864 1873 ------------------------------------------------------------------------------- 1865 1874 */ 1866 - float64 float64_round_to_int( float64 a ) 1875 + float64 float64_round_to_int( struct roundingData *roundData, float64 a ) 1867 1876 { 1868 1877 flag aSign; 1869 1878 int16 aExp; ··· 1880 1889 } 1881 1890 if ( aExp <= 0x3FE ) { 1882 1891 if ( (bits64) ( a<<1 ) == 0 ) return a; 1883 - float_exception_flags |= float_flag_inexact; 1892 + roundData->exception |= float_flag_inexact; 1884 1893 aSign = extractFloat64Sign( a ); 1885 - switch ( float_rounding_mode ) { 1894 + switch ( roundData->mode ) { 1886 1895 case float_round_nearest_even: 1887 1896 if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { 1888 1897 return packFloat64( aSign, 0x3FF, 0 ); ··· 1900 1909 lastBitMask <<= 0x433 - aExp; 1901 1910 roundBitsMask = lastBitMask - 1; 1902 1911 z = a; 1903 - roundingMode = float_rounding_mode; 1912 + roundingMode = roundData->mode; 1904 1913 if ( roundingMode == float_round_nearest_even ) { 1905 1914 z += lastBitMask>>1; 1906 1915 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; ··· 1911 1920 } 1912 1921 } 1913 1922 z &= ~ roundBitsMask; 1914 - if ( z != a ) float_exception_flags |= float_flag_inexact; 1923 + if ( z != a ) roundData->exception |= float_flag_inexact; 1915 1924 return z; 1916 1925 1917 1926 } ··· 1925 1934 Floating-point Arithmetic. 1926 1935 ------------------------------------------------------------------------------- 1927 1936 */ 1928 - static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) 1937 + static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign ) 1929 1938 { 1930 1939 int16 aExp, bExp, zExp; 1931 1940 bits64 aSig, bSig, zSig; ··· 1984 1993 ++zExp; 1985 1994 } 1986 1995 roundAndPack: 1987 - return roundAndPackFloat64( zSign, zExp, zSig ); 1996 + return roundAndPackFloat64( roundData, zSign, zExp, zSig ); 1988 1997 1989 1998 } 1990 1999 ··· 1997 2006 Standard for Binary Floating-point Arithmetic. 1998 2007 ------------------------------------------------------------------------------- 1999 2008 */ 2000 - static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) 2009 + static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign ) 2001 2010 { 2002 2011 int16 aExp, bExp, zExp; 2003 2012 bits64 aSig, bSig, zSig; ··· 2014 2023 if ( expDiff < 0 ) goto bExpBigger; 2015 2024 if ( aExp == 0x7FF ) { 2016 2025 if ( aSig | bSig ) return propagateFloat64NaN( a, b ); 2017 - float_raise( float_flag_invalid ); 2026 + roundData->exception |= float_flag_invalid; 2018 2027 return float64_default_nan; 2019 2028 } 2020 2029 if ( aExp == 0 ) { ··· 2023 2032 } 2024 2033 if ( bSig < aSig ) goto aBigger; 2025 2034 if ( aSig < bSig ) goto bBigger; 2026 - return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); 2035 + return packFloat64( roundData->mode == float_round_down, 0, 0 ); 2027 2036 bExpBigger: 2028 2037 if ( bExp == 0x7FF ) { 2029 2038 if ( bSig ) return propagateFloat64NaN( a, b ); ··· 2060 2069 zExp = aExp; 2061 2070 normalizeRoundAndPack: 2062 2071 --zExp; 2063 - return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); 2072 + return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig ); 2064 2073 2065 2074 } 2066 2075 ··· 2071 2080 Binary Floating-point Arithmetic. 2072 2081 ------------------------------------------------------------------------------- 2073 2082 */ 2074 - float64 float64_add( float64 a, float64 b ) 2083 + float64 float64_add( struct roundingData *roundData, float64 a, float64 b ) 2075 2084 { 2076 2085 flag aSign, bSign; 2077 2086 2078 2087 aSign = extractFloat64Sign( a ); 2079 2088 bSign = extractFloat64Sign( b ); 2080 2089 if ( aSign == bSign ) { 2081 - return addFloat64Sigs( a, b, aSign ); 2090 + return addFloat64Sigs( roundData, a, b, aSign ); 2082 2091 } 2083 2092 else { 2084 - return subFloat64Sigs( a, b, aSign ); 2093 + return subFloat64Sigs( roundData, a, b, aSign ); 2085 2094 } 2086 2095 2087 2096 } ··· 2093 2102 for Binary Floating-point Arithmetic. 2094 2103 ------------------------------------------------------------------------------- 2095 2104 */ 2096 - float64 float64_sub( float64 a, float64 b ) 2105 + float64 float64_sub( struct roundingData *roundData, float64 a, float64 b ) 2097 2106 { 2098 2107 flag aSign, bSign; 2099 2108 2100 2109 aSign = extractFloat64Sign( a ); 2101 2110 bSign = extractFloat64Sign( b ); 2102 2111 if ( aSign == bSign ) { 2103 - return subFloat64Sigs( a, b, aSign ); 2112 + return subFloat64Sigs( roundData, a, b, aSign ); 2104 2113 } 2105 2114 else { 2106 - return addFloat64Sigs( a, b, aSign ); 2115 + return addFloat64Sigs( roundData, a, b, aSign ); 2107 2116 } 2108 2117 2109 2118 } ··· 2115 2124 for Binary Floating-point Arithmetic. 2116 2125 ------------------------------------------------------------------------------- 2117 2126 */ 2118 - float64 float64_mul( float64 a, float64 b ) 2127 + float64 float64_mul( struct roundingData *roundData, float64 a, float64 b ) 2119 2128 { 2120 2129 flag aSign, bSign, zSign; 2121 2130 int16 aExp, bExp, zExp; ··· 2133 2142 return propagateFloat64NaN( a, b ); 2134 2143 } 2135 2144 if ( ( bExp | bSig ) == 0 ) { 2136 - float_raise( float_flag_invalid ); 2145 + roundData->exception |= float_flag_invalid; 2137 2146 return float64_default_nan; 2138 2147 } 2139 2148 return packFloat64( zSign, 0x7FF, 0 ); ··· 2141 2150 if ( bExp == 0x7FF ) { 2142 2151 if ( bSig ) return propagateFloat64NaN( a, b ); 2143 2152 if ( ( aExp | aSig ) == 0 ) { 2144 - float_raise( float_flag_invalid ); 2153 + roundData->exception |= float_flag_invalid; 2145 2154 return float64_default_nan; 2146 2155 } 2147 2156 return packFloat64( zSign, 0x7FF, 0 ); ··· 2163 2172 zSig0 <<= 1; 2164 2173 --zExp; 2165 2174 } 2166 - return roundAndPackFloat64( zSign, zExp, zSig0 ); 2175 + return roundAndPackFloat64( roundData, zSign, zExp, zSig0 ); 2167 2176 2168 2177 } 2169 2178 ··· 2174 2183 the IEC/IEEE Standard for Binary Floating-point Arithmetic. 2175 2184 ------------------------------------------------------------------------------- 2176 2185 */ 2177 - float64 float64_div( float64 a, float64 b ) 2186 + float64 float64_div( struct roundingData *roundData, float64 a, float64 b ) 2178 2187 { 2179 2188 flag aSign, bSign, zSign; 2180 2189 int16 aExp, bExp, zExp; ··· 2193 2202 if ( aSig ) return propagateFloat64NaN( a, b ); 2194 2203 if ( bExp == 0x7FF ) { 2195 2204 if ( bSig ) return propagateFloat64NaN( a, b ); 2196 - float_raise( float_flag_invalid ); 2205 + roundData->exception |= float_flag_invalid; 2197 2206 return float64_default_nan; 2198 2207 } 2199 2208 return packFloat64( zSign, 0x7FF, 0 ); ··· 2205 2214 if ( bExp == 0 ) { 2206 2215 if ( bSig == 0 ) { 2207 2216 if ( ( aExp | aSig ) == 0 ) { 2208 - float_raise( float_flag_invalid ); 2217 + roundData->exception |= float_flag_invalid; 2209 2218 return float64_default_nan; 2210 2219 } 2211 - float_raise( float_flag_divbyzero ); 2220 + roundData->exception |= float_flag_divbyzero; 2212 2221 return packFloat64( zSign, 0x7FF, 0 ); 2213 2222 } 2214 2223 normalizeFloat64Subnormal( bSig, &bExp, &bSig ); ··· 2234 2243 } 2235 2244 zSig |= ( rem1 != 0 ); 2236 2245 } 2237 - return roundAndPackFloat64( zSign, zExp, zSig ); 2246 + return roundAndPackFloat64( roundData, zSign, zExp, zSig ); 2238 2247 2239 2248 } 2240 2249 ··· 2245 2254 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. 2246 2255 ------------------------------------------------------------------------------- 2247 2256 */ 2248 - float64 float64_rem( float64 a, float64 b ) 2257 + float64 float64_rem( struct roundingData *roundData, float64 a, float64 b ) 2249 2258 { 2250 2259 flag aSign, bSign, zSign; 2251 2260 int16 aExp, bExp, expDiff; ··· 2263 2272 if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { 2264 2273 return propagateFloat64NaN( a, b ); 2265 2274 } 2266 - float_raise( float_flag_invalid ); 2275 + roundData->exception |= float_flag_invalid; 2267 2276 return float64_default_nan; 2268 2277 } 2269 2278 if ( bExp == 0x7FF ) { ··· 2272 2281 } 2273 2282 if ( bExp == 0 ) { 2274 2283 if ( bSig == 0 ) { 2275 - float_raise( float_flag_invalid ); 2284 + roundData->exception |= float_flag_invalid; 2276 2285 return float64_default_nan; 2277 2286 } 2278 2287 normalizeFloat64Subnormal( bSig, &bExp, &bSig ); ··· 2320 2329 } 2321 2330 zSign = ( (sbits64) aSig < 0 ); 2322 2331 if ( zSign ) aSig = - aSig; 2323 - return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); 2332 + return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig ); 2324 2333 2325 2334 } 2326 2335 ··· 2331 2340 Floating-point Arithmetic. 2332 2341 ------------------------------------------------------------------------------- 2333 2342 */ 2334 - float64 float64_sqrt( float64 a ) 2343 + float64 float64_sqrt( struct roundingData *roundData, float64 a ) 2335 2344 { 2336 2345 flag aSign; 2337 2346 int16 aExp, zExp; ··· 2345 2354 if ( aExp == 0x7FF ) { 2346 2355 if ( aSig ) return propagateFloat64NaN( a, a ); 2347 2356 if ( ! aSign ) return a; 2348 - float_raise( float_flag_invalid ); 2357 + roundData->exception |= float_flag_invalid; 2349 2358 return float64_default_nan; 2350 2359 } 2351 2360 if ( aSign ) { 2352 2361 if ( ( aExp | aSig ) == 0 ) return a; 2353 - float_raise( float_flag_invalid ); 2362 + roundData->exception |= float_flag_invalid; 2354 2363 return float64_default_nan; 2355 2364 } 2356 2365 if ( aExp == 0 ) { ··· 2381 2390 } 2382 2391 } 2383 2392 shift64RightJamming( zSig, 1, &zSig ); 2384 - return roundAndPackFloat64( 0, zExp, zSig ); 2393 + return roundAndPackFloat64( roundData, 0, zExp, zSig ); 2385 2394 2386 2395 } 2387 2396 ··· 2545 2554 overflows, the largest integer with the same sign as `a' is returned. 2546 2555 ------------------------------------------------------------------------------- 2547 2556 */ 2548 - int32 floatx80_to_int32( floatx80 a ) 2557 + int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a ) 2549 2558 { 2550 2559 flag aSign; 2551 2560 int32 aExp, shiftCount; ··· 2558 2567 shiftCount = 0x4037 - aExp; 2559 2568 if ( shiftCount <= 0 ) shiftCount = 1; 2560 2569 shift64RightJamming( aSig, shiftCount, &aSig ); 2561 - return roundAndPackInt32( aSign, aSig ); 2570 + return roundAndPackInt32( roundData, aSign, aSig ); 2562 2571 2563 2572 } 2564 2573 ··· 2589 2598 goto invalid; 2590 2599 } 2591 2600 else if ( 63 < shiftCount ) { 2592 - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; 2601 + if ( aExp || aSig ) float_raise( float_flag_inexact ); 2593 2602 return 0; 2594 2603 } 2595 2604 savedASig = aSig; ··· 2598 2607 if ( aSign ) z = - z; 2599 2608 if ( ( z < 0 ) ^ aSign ) { 2600 2609 invalid: 2601 - float_exception_flags |= float_flag_invalid; 2610 + float_raise( float_flag_invalid ); 2602 2611 return aSign ? 0x80000000 : 0x7FFFFFFF; 2603 2612 } 2604 2613 if ( ( aSig<<shiftCount ) != savedASig ) { 2605 - float_exception_flags |= float_flag_inexact; 2614 + float_raise( float_flag_inexact ); 2606 2615 } 2607 2616 return z; 2608 2617 ··· 2616 2625 Floating-point Arithmetic. 2617 2626 ------------------------------------------------------------------------------- 2618 2627 */ 2619 - float32 floatx80_to_float32( floatx80 a ) 2628 + float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a ) 2620 2629 { 2621 2630 flag aSign; 2622 2631 int32 aExp; ··· 2633 2642 } 2634 2643 shift64RightJamming( aSig, 33, &aSig ); 2635 2644 if ( aExp || aSig ) aExp -= 0x3F81; 2636 - return roundAndPackFloat32( aSign, aExp, aSig ); 2645 + return roundAndPackFloat32( roundData, aSign, aExp, aSig ); 2637 2646 2638 2647 } 2639 2648 ··· 2645 2654 Floating-point Arithmetic. 2646 2655 ------------------------------------------------------------------------------- 2647 2656 */ 2648 - float64 floatx80_to_float64( floatx80 a ) 2657 + float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a ) 2649 2658 { 2650 2659 flag aSign; 2651 2660 int32 aExp; ··· 2662 2671 } 2663 2672 shift64RightJamming( aSig, 1, &zSig ); 2664 2673 if ( aExp || aSig ) aExp -= 0x3C01; 2665 - return roundAndPackFloat64( aSign, aExp, zSig ); 2674 + return roundAndPackFloat64( roundData, aSign, aExp, zSig ); 2666 2675 2667 2676 } 2668 2677 ··· 2674 2683 Binary Floating-point Arithmetic. 2675 2684 ------------------------------------------------------------------------------- 2676 2685 */ 2677 - floatx80 floatx80_round_to_int( floatx80 a ) 2686 + floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a ) 2678 2687 { 2679 2688 flag aSign; 2680 2689 int32 aExp; ··· 2694 2703 && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { 2695 2704 return a; 2696 2705 } 2697 - float_exception_flags |= float_flag_inexact; 2706 + roundData->exception |= float_flag_inexact; 2698 2707 aSign = extractFloatx80Sign( a ); 2699 - switch ( float_rounding_mode ) { 2708 + switch ( roundData->mode ) { 2700 2709 case float_round_nearest_even: 2701 2710 if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) 2702 2711 ) { ··· 2720 2729 lastBitMask <<= 0x403E - aExp; 2721 2730 roundBitsMask = lastBitMask - 1; 2722 2731 z = a; 2723 - roundingMode = float_rounding_mode; 2732 + roundingMode = roundData->mode; 2724 2733 if ( roundingMode == float_round_nearest_even ) { 2725 2734 z.low += lastBitMask>>1; 2726 2735 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; ··· 2735 2744 ++z.high; 2736 2745 z.low = LIT64( 0x8000000000000000 ); 2737 2746 } 2738 - if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; 2747 + if ( z.low != a.low ) roundData->exception |= float_flag_inexact; 2739 2748 return z; 2740 2749 2741 2750 } ··· 2749 2758 Floating-point Arithmetic. 2750 2759 ------------------------------------------------------------------------------- 2751 2760 */ 2752 - static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) 2761 + static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign ) 2753 2762 { 2754 2763 int32 aExp, bExp, zExp; 2755 2764 bits64 aSig, bSig, zSig0, zSig1; ··· 2805 2814 roundAndPack: 2806 2815 return 2807 2816 roundAndPackFloatx80( 2808 - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); 2817 + roundData, zSign, zExp, zSig0, zSig1 ); 2809 2818 2810 2819 } 2811 2820 ··· 2818 2827 Standard for Binary Floating-point Arithmetic. 2819 2828 ------------------------------------------------------------------------------- 2820 2829 */ 2821 - static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) 2830 + static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign ) 2822 2831 { 2823 2832 int32 aExp, bExp, zExp; 2824 2833 bits64 aSig, bSig, zSig0, zSig1; ··· 2836 2845 if ( (bits64) ( ( aSig | bSig )<<1 ) ) { 2837 2846 return propagateFloatx80NaN( a, b ); 2838 2847 } 2839 - float_raise( float_flag_invalid ); 2848 + roundData->exception |= float_flag_invalid; 2840 2849 z.low = floatx80_default_nan_low; 2841 2850 z.high = floatx80_default_nan_high; 2842 2851 return z; ··· 2848 2857 zSig1 = 0; 2849 2858 if ( bSig < aSig ) goto aBigger; 2850 2859 if ( aSig < bSig ) goto bBigger; 2851 - return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); 2860 + return packFloatx80( roundData->mode == float_round_down, 0, 0 ); 2852 2861 bExpBigger: 2853 2862 if ( bExp == 0x7FFF ) { 2854 2863 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); ··· 2874 2883 normalizeRoundAndPack: 2875 2884 return 2876 2885 normalizeRoundAndPackFloatx80( 2877 - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); 2886 + roundData, zSign, zExp, zSig0, zSig1 ); 2878 2887 2879 2888 } 2880 2889 ··· 2885 2894 Standard for Binary Floating-point Arithmetic. 2886 2895 ------------------------------------------------------------------------------- 2887 2896 */ 2888 - floatx80 floatx80_add( floatx80 a, floatx80 b ) 2897 + floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b ) 2889 2898 { 2890 2899 flag aSign, bSign; 2891 2900 2892 2901 aSign = extractFloatx80Sign( a ); 2893 2902 bSign = extractFloatx80Sign( b ); 2894 2903 if ( aSign == bSign ) { 2895 - return addFloatx80Sigs( a, b, aSign ); 2904 + return addFloatx80Sigs( roundData, a, b, aSign ); 2896 2905 } 2897 2906 else { 2898 - return subFloatx80Sigs( a, b, aSign ); 2907 + return subFloatx80Sigs( roundData, a, b, aSign ); 2899 2908 } 2900 2909 2901 2910 } ··· 2907 2916 IEC/IEEE Standard for Binary Floating-point Arithmetic. 2908 2917 ------------------------------------------------------------------------------- 2909 2918 */ 2910 - floatx80 floatx80_sub( floatx80 a, floatx80 b ) 2919 + floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b ) 2911 2920 { 2912 2921 flag aSign, bSign; 2913 2922 2914 2923 aSign = extractFloatx80Sign( a ); 2915 2924 bSign = extractFloatx80Sign( b ); 2916 2925 if ( aSign == bSign ) { 2917 - return subFloatx80Sigs( a, b, aSign ); 2926 + return subFloatx80Sigs( roundData, a, b, aSign ); 2918 2927 } 2919 2928 else { 2920 - return addFloatx80Sigs( a, b, aSign ); 2929 + return addFloatx80Sigs( roundData, a, b, aSign ); 2921 2930 } 2922 2931 2923 2932 } ··· 2929 2938 IEC/IEEE Standard for Binary Floating-point Arithmetic. 2930 2939 ------------------------------------------------------------------------------- 2931 2940 */ 2932 - floatx80 floatx80_mul( floatx80 a, floatx80 b ) 2941 + floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b ) 2933 2942 { 2934 2943 flag aSign, bSign, zSign; 2935 2944 int32 aExp, bExp, zExp; ··· 2955 2964 if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); 2956 2965 if ( ( aExp | aSig ) == 0 ) { 2957 2966 invalid: 2958 - float_raise( float_flag_invalid ); 2967 + roundData->exception |= float_flag_invalid; 2959 2968 z.low = floatx80_default_nan_low; 2960 2969 z.high = floatx80_default_nan_high; 2961 2970 return z; ··· 2978 2987 } 2979 2988 return 2980 2989 roundAndPackFloatx80( 2981 - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); 2990 + roundData, zSign, zExp, zSig0, zSig1 ); 2982 2991 2983 2992 } 2984 2993 ··· 2989 2998 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. 2990 2999 ------------------------------------------------------------------------------- 2991 3000 */ 2992 - floatx80 floatx80_div( floatx80 a, floatx80 b ) 3001 + floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b ) 2993 3002 { 2994 3003 flag aSign, bSign, zSign; 2995 3004 int32 aExp, bExp, zExp; ··· 3020 3029 if ( bSig == 0 ) { 3021 3030 if ( ( aExp | aSig ) == 0 ) { 3022 3031 invalid: 3023 - float_raise( float_flag_invalid ); 3032 + roundData->exception |= float_flag_invalid; 3024 3033 z.low = floatx80_default_nan_low; 3025 3034 z.high = floatx80_default_nan_high; 3026 3035 return z; 3027 3036 } 3028 - float_raise( float_flag_divbyzero ); 3037 + roundData->exception |= float_flag_divbyzero; 3029 3038 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); 3030 3039 } 3031 3040 normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); ··· 3059 3068 } 3060 3069 return 3061 3070 roundAndPackFloatx80( 3062 - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); 3071 + roundData, zSign, zExp, zSig0, zSig1 ); 3063 3072 3064 3073 } 3065 3074 ··· 3070 3079 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. 3071 3080 ------------------------------------------------------------------------------- 3072 3081 */ 3073 - floatx80 floatx80_rem( floatx80 a, floatx80 b ) 3082 + floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b ) 3074 3083 { 3075 3084 flag aSign, bSign, zSign; 3076 3085 int32 aExp, bExp, expDiff; ··· 3098 3107 if ( bExp == 0 ) { 3099 3108 if ( bSig == 0 ) { 3100 3109 invalid: 3101 - float_raise( float_flag_invalid ); 3110 + roundData->exception |= float_flag_invalid; 3102 3111 z.low = floatx80_default_nan_low; 3103 3112 z.high = floatx80_default_nan_high; 3104 3113 return z; ··· 3155 3164 aSig1 = alternateASig1; 3156 3165 zSign = ! zSign; 3157 3166 } 3167 + 3158 3168 return 3159 3169 normalizeRoundAndPackFloatx80( 3160 - 80, zSign, bExp + expDiff, aSig0, aSig1 ); 3170 + roundData, zSign, bExp + expDiff, aSig0, aSig1 ); 3161 3171 3162 3172 } 3163 3173 ··· 3169 3177 for Binary Floating-point Arithmetic. 3170 3178 ------------------------------------------------------------------------------- 3171 3179 */ 3172 - floatx80 floatx80_sqrt( floatx80 a ) 3180 + floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a ) 3173 3181 { 3174 3182 flag aSign; 3175 3183 int32 aExp, zExp; ··· 3189 3197 if ( aSign ) { 3190 3198 if ( ( aExp | aSig0 ) == 0 ) return a; 3191 3199 invalid: 3192 - float_raise( float_flag_invalid ); 3200 + roundData->exception |= float_flag_invalid; 3193 3201 z.low = floatx80_default_nan_low; 3194 3202 z.high = floatx80_default_nan_high; 3195 3203 return z; ··· 3234 3242 } 3235 3243 return 3236 3244 roundAndPackFloatx80( 3237 - floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); 3245 + roundData, 0, zExp, zSig0, zSig1 ); 3238 3246 3239 3247 } 3240 3248 ··· 3256 3264 ) { 3257 3265 if ( floatx80_is_signaling_nan( a ) 3258 3266 || floatx80_is_signaling_nan( b ) ) { 3259 - float_raise( float_flag_invalid ); 3267 + roundData->exception |= float_flag_invalid; 3260 3268 } 3261 3269 return 0; 3262 3270 } ··· 3286 3294 || ( ( extractFloatx80Exp( b ) == 0x7FFF ) 3287 3295 && (bits64) ( extractFloatx80Frac( b )<<1 ) ) 3288 3296 ) { 3289 - float_raise( float_flag_invalid ); 3297 + roundData->exception |= float_flag_invalid; 3290 3298 return 0; 3291 3299 } 3292 3300 aSign = extractFloatx80Sign( a ); ··· 3320 3328 || ( ( extractFloatx80Exp( b ) == 0x7FFF ) 3321 3329 && (bits64) ( extractFloatx80Frac( b )<<1 ) ) 3322 3330 ) { 3323 - float_raise( float_flag_invalid ); 3331 + roundData->exception |= float_flag_invalid; 3324 3332 return 0; 3325 3333 } 3326 3334 aSign = extractFloatx80Sign( a ); ··· 3353 3361 || ( ( extractFloatx80Exp( b ) == 0x7FFF ) 3354 3362 && (bits64) ( extractFloatx80Frac( b )<<1 ) ) 3355 3363 ) { 3356 - float_raise( float_flag_invalid ); 3364 + roundData->exception |= float_flag_invalid; 3357 3365 return 0; 3358 3366 } 3359 3367 return ··· 3384 3392 ) { 3385 3393 if ( floatx80_is_signaling_nan( a ) 3386 3394 || floatx80_is_signaling_nan( b ) ) { 3387 - float_raise( float_flag_invalid ); 3395 + roundData->exception |= float_flag_invalid; 3388 3396 } 3389 3397 return 0; 3390 3398 } ··· 3421 3429 ) { 3422 3430 if ( floatx80_is_signaling_nan( a ) 3423 3431 || floatx80_is_signaling_nan( b ) ) { 3424 - float_raise( float_flag_invalid ); 3432 + roundData->exception |= float_flag_invalid; 3425 3433 } 3426 3434 return 0; 3427 3435 }
+29 -39
arch/arm/nwfpe/softfloat.h
··· 74 74 Software IEC/IEEE floating-point rounding mode. 75 75 ------------------------------------------------------------------------------- 76 76 */ 77 - extern signed char float_rounding_mode; 77 + //extern int8 float_rounding_mode; 78 78 enum { 79 79 float_round_nearest_even = 0, 80 80 float_round_to_zero = 1, ··· 86 86 ------------------------------------------------------------------------------- 87 87 Software IEC/IEEE floating-point exception flags. 88 88 ------------------------------------------------------------------------------- 89 - extern signed char float_exception_flags; 90 89 enum { 91 90 float_flag_inexact = 1, 92 91 float_flag_underflow = 2, ··· 98 99 Changed the enumeration to match the bit order in the FPA11. 99 100 */ 100 101 101 - extern signed char float_exception_flags; 102 102 enum { 103 103 float_flag_invalid = 1, 104 104 float_flag_divbyzero = 2, ··· 119 121 Software IEC/IEEE integer-to-floating-point conversion routines. 120 122 ------------------------------------------------------------------------------- 121 123 */ 122 - float32 int32_to_float32( signed int ); 124 + float32 int32_to_float32( struct roundingData *, signed int ); 123 125 float64 int32_to_float64( signed int ); 124 126 #ifdef FLOATX80 125 127 floatx80 int32_to_floatx80( signed int ); ··· 130 132 Software IEC/IEEE single-precision conversion routines. 131 133 ------------------------------------------------------------------------------- 132 134 */ 133 - signed int float32_to_int32( float32 ); 135 + signed int float32_to_int32( struct roundingData *, float32 ); 134 136 signed int float32_to_int32_round_to_zero( float32 ); 135 137 float64 float32_to_float64( float32 ); 136 138 #ifdef FLOATX80 ··· 142 144 Software IEC/IEEE single-precision operations. 143 145 ------------------------------------------------------------------------------- 144 146 */ 145 - float32 float32_round_to_int( float32 ); 146 - float32 float32_add( float32, float32 ); 147 - float32 float32_sub( float32, float32 ); 148 - float32 float32_mul( float32, float32 ); 149 - float32 float32_div( float32, float32 ); 150 - float32 float32_rem( float32, float32 ); 151 - float32 float32_sqrt( float32 ); 147 + float32 float32_round_to_int( struct roundingData*, float32 ); 148 + float32 float32_add( struct roundingData *, float32, float32 ); 149 + float32 float32_sub( struct roundingData *, float32, float32 ); 150 + float32 float32_mul( struct roundingData *, float32, float32 ); 151 + float32 float32_div( struct roundingData *, float32, float32 ); 152 + float32 float32_rem( struct roundingData *, float32, float32 ); 153 + float32 float32_sqrt( struct roundingData*, float32 ); 152 154 char float32_eq( float32, float32 ); 153 155 char float32_le( float32, float32 ); 154 156 char float32_lt( float32, float32 ); ··· 162 164 Software IEC/IEEE double-precision conversion routines. 163 165 ------------------------------------------------------------------------------- 164 166 */ 165 - signed int float64_to_int32( float64 ); 167 + signed int float64_to_int32( struct roundingData *, float64 ); 166 168 signed int float64_to_int32_round_to_zero( float64 ); 167 - float32 float64_to_float32( float64 ); 169 + float32 float64_to_float32( struct roundingData *, float64 ); 168 170 #ifdef FLOATX80 169 171 floatx80 float64_to_floatx80( float64 ); 170 172 #endif ··· 174 176 Software IEC/IEEE double-precision operations. 175 177 ------------------------------------------------------------------------------- 176 178 */ 177 - float64 float64_round_to_int( float64 ); 178 - float64 float64_add( float64, float64 ); 179 - float64 float64_sub( float64, float64 ); 180 - float64 float64_mul( float64, float64 ); 181 - float64 float64_div( float64, float64 ); 182 - float64 float64_rem( float64, float64 ); 183 - float64 float64_sqrt( float64 ); 179 + float64 float64_round_to_int( struct roundingData *, float64 ); 180 + float64 float64_add( struct roundingData *, float64, float64 ); 181 + float64 float64_sub( struct roundingData *, float64, float64 ); 182 + float64 float64_mul( struct roundingData *, float64, float64 ); 183 + float64 float64_div( struct roundingData *, float64, float64 ); 184 + float64 float64_rem( struct roundingData *, float64, float64 ); 185 + float64 float64_sqrt( struct roundingData *, float64 ); 184 186 char float64_eq( float64, float64 ); 185 187 char float64_le( float64, float64 ); 186 188 char float64_lt( float64, float64 ); ··· 196 198 Software IEC/IEEE extended double-precision conversion routines. 197 199 ------------------------------------------------------------------------------- 198 200 */ 199 - signed int floatx80_to_int32( floatx80 ); 201 + signed int floatx80_to_int32( struct roundingData *, floatx80 ); 200 202 signed int floatx80_to_int32_round_to_zero( floatx80 ); 201 - float32 floatx80_to_float32( floatx80 ); 202 - float64 floatx80_to_float64( floatx80 ); 203 - 204 - /* 205 - ------------------------------------------------------------------------------- 206 - Software IEC/IEEE extended double-precision rounding precision. Valid 207 - values are 32, 64, and 80. 208 - ------------------------------------------------------------------------------- 209 - */ 210 - extern signed char floatx80_rounding_precision; 203 + float32 floatx80_to_float32( struct roundingData *, floatx80 ); 204 + float64 floatx80_to_float64( struct roundingData *, floatx80 ); 211 205 212 206 /* 213 207 ------------------------------------------------------------------------------- 214 208 Software IEC/IEEE extended double-precision operations. 215 209 ------------------------------------------------------------------------------- 216 210 */ 217 - floatx80 floatx80_round_to_int( floatx80 ); 218 - floatx80 floatx80_add( floatx80, floatx80 ); 219 - floatx80 floatx80_sub( floatx80, floatx80 ); 220 - floatx80 floatx80_mul( floatx80, floatx80 ); 221 - floatx80 floatx80_div( floatx80, floatx80 ); 222 - floatx80 floatx80_rem( floatx80, floatx80 ); 223 - floatx80 floatx80_sqrt( floatx80 ); 211 + floatx80 floatx80_round_to_int( struct roundingData *, floatx80 ); 212 + floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 ); 213 + floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 ); 214 + floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 ); 215 + floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 ); 216 + floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 ); 217 + floatx80 floatx80_sqrt( struct roundingData *, floatx80 ); 224 218 char floatx80_eq( floatx80, floatx80 ); 225 219 char floatx80_le( floatx80, floatx80 ); 226 220 char floatx80_lt( floatx80, floatx80 );
+3
arch/arm/vfp/vfpdouble.c
··· 770 770 if ((s64)m_sig < 0) { 771 771 vdd->sign = vfp_sign_negate(vdd->sign); 772 772 m_sig = -m_sig; 773 + } else if (m_sig == 0) { 774 + vdd->sign = (fpscr & FPSCR_RMODE_MASK) == 775 + FPSCR_ROUND_MINUSINF ? 0x8000 : 0; 773 776 } 774 777 } else { 775 778 m_sig += vdn->significand;
+10 -39
drivers/char/watchdog/sa1100_wdt.c
··· 36 36 #include <asm/uaccess.h> 37 37 38 38 #define OSCR_FREQ CLOCK_TICK_RATE 39 - #define SA1100_CLOSE_MAGIC (0x5afc4453) 40 39 41 40 static unsigned long sa1100wdt_users; 42 - static int expect_close; 43 41 static int pre_margin; 44 42 static int boot_status; 45 - static int nowayout = WATCHDOG_NOWAYOUT; 46 43 47 44 /* 48 45 * Allow only one person to hold it open ··· 59 62 } 60 63 61 64 /* 62 - * Shut off the timer. 63 - * Lock it in if it's a module and we defined ...NOWAYOUT 64 - * Oddly, the watchdog can only be enabled, but we can turn off 65 - * the interrupt, which appears to prevent the watchdog timing out. 65 + * The watchdog cannot be disabled. 66 + * 67 + * Previous comments suggested that turning off the interrupt by 68 + * clearing OIER[E3] would prevent the watchdog timing out but this 69 + * does not appear to be true (at least on the PXA255). 66 70 */ 67 71 static int sa1100dog_release(struct inode *inode, struct file *file) 68 72 { 69 - OSMR3 = OSCR + pre_margin; 70 - 71 - if (expect_close == SA1100_CLOSE_MAGIC) { 72 - OIER &= ~OIER_E3; 73 - } else { 74 - printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly. WDT will not stop!\n"); 75 - } 73 + printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); 76 74 77 75 clear_bit(1, &sa1100wdt_users); 78 - expect_close = 0; 79 76 80 77 return 0; 81 78 } 82 79 83 80 static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 84 81 { 85 - if (len) { 86 - if (!nowayout) { 87 - size_t i; 88 - 89 - expect_close = 0; 90 - 91 - for (i = 0; i != len; i++) { 92 - char c; 93 - 94 - if (get_user(c, data + i)) 95 - return -EFAULT; 96 - if (c == 'V') 97 - expect_close = SA1100_CLOSE_MAGIC; 98 - } 99 - } 82 + if (len) 100 83 /* Refresh OSMR3 timer. */ 101 84 OSMR3 = OSCR + pre_margin; 102 - } 103 85 104 86 return len; 105 87 } 106 88 107 89 static struct watchdog_info ident = { 108 - .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 109 - WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 110 - .identity = "SA1100 Watchdog", 90 + .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 91 + .identity = "SA1100/PXA255 Watchdog", 111 92 }; 112 93 113 94 static int sa1100dog_ioctl(struct inode *inode, struct file *file, ··· 147 172 static struct miscdevice sa1100dog_miscdev = 148 173 { 149 174 .minor = WATCHDOG_MINOR, 150 - .name = "SA1100/PXA2xx watchdog", 175 + .name = "watchdog", 151 176 .fops = &sa1100dog_fops, 152 177 }; 153 178 ··· 169 194 if (ret == 0) 170 195 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", 171 196 margin); 172 - 173 197 return ret; 174 198 } 175 199 ··· 185 211 186 212 module_param(margin, int, 0); 187 213 MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); 188 - 189 - module_param(nowayout, int, 0); 190 - MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); 191 214 192 215 MODULE_LICENSE("GPL"); 193 216 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);