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

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