Composite operations on unsigned long integers for i386. More...

`#include <linux/types.h>`

Go to the source code of this file.

## Defines | |

#define | ul_shl_div(num, SHF, den) |

Computes '(num << SHF) / den' as unsigned long (32 bits). | |

#define | ul_shl_ceil(num, SHF, den) |

Computes 'ceil((num << SHF) / den' as unsigned long (32 bits). | |

#define | ul_mul_div(x, num, den) |

Computes '(x * num) / den' as unsigned long (32 bits). | |

#define | ul_mul_shr(x, y, SHF) |

Computes '(x * y) >> SHF' as unsigned long (32 bits). |

Composite operations on unsigned long integers for i386.

These are implemented in assembler with intermediate results on 64 bits, using native 32-bit multiply and divide operations of the processor. Resulting implementation is hopefully more appropriate than general long-long arithmetics functions coming with gcc, which would not be available anycase inside the kernel (their use would require linking the gcc long-long module within a kernel module).

Definition in file qos_ul_i386.h.

#define ul_mul_div | ( | x, | |||

num, | |||||

den | ) |

({ \ __volatile__ __u32 _ul_x = (x); \ __volatile__ __u32 _ul_num = (num); \ __volatile__ __u32 _ul_den = (den); \ __volatile__ __u32 _ul_res; \ __asm__ __volatile__("\n" \ " mull %%edx \n" \ " divl %3 \n" \ : "=a" (_ul_res) \ : "0" (_ul_x), "d" (_ul_num), "r" (_ul_den)); \ _ul_res; \ })

Computes '(x * num) / den' as unsigned long (32 bits).

Computation is carried on with intermediate result (x * num) on 64 bits.

**Parameters:**-
*x*an unsigned long integer (32 bits) *num*an unsigned long integer (32 bits) *den*an unsigned long integer (32 bits)

**Returns:**- the result as an unsigned long integer (32 bits)

**Note:**- No overflow check is made after the division.

**Todo:**- Investigate on volatiles, that do not allow optimizations. They should not be required, but without them bw2Q(), which uses ul_mul_shr, outputs zero instead of the correct value.

Definition at line 97 of file qos_ul_i386.h.

Referenced by main(), and rres_activate_nosched().

#define ul_mul_shr | ( | x, | |||

y, | |||||

SHF | ) |

({ \ __volatile__ __u32 _ul_x = (x); \ __volatile__ __u32 _ul_y = (y); \ __volatile__ __u32 _ul_res; \ __asm__ __volatile__ ("\n" \ " mull %%edx \n" \ " shrdl %2, %%edx, %%eax \n" \ : "=a" (_ul_res) \ : "0" (_ul_x), "I" ((SHF)), "d" (_ul_y)); \ _ul_res; \ })

Computes '(x * y) >> SHF' as unsigned long (32 bits).

The computation is carried on with intermediate result (x*y) on 64 bits.

This macro is useful for multiplying two integers where one of them represents a real in fixed precision with SHF decimal bits (i.e. 1.0 is represented as 1ul<<SHF).

**Parameters:**-
*x*an unsigned long integer (32 bits) *y*an unsigned long integer (32 bits) *SHF*a macro which evaluates to an integer within 1 and 31

**Returns:**- the result as an unsigned long integer (32 bits)

**Note:**- No overflow check is made after the shift.

**Todo:**- Investigate on volatiles, that do not allow optimizations. They should not be required, but without them bw2Q(), which uses ul_mul_shr, outputs zero instead of the correct value.

Definition at line 130 of file qos_ul_i386.h.

Referenced by bw2Q(), main(), and mul_by_bw().

#define ul_shl_ceil | ( | num, | |||

SHF, | |||||

den | ) |

({ \ __volatile__ __u32 _ul_num = (num); \ __volatile__ __u32 _ul_den = (den); \ __volatile__ __u32 _ul_res; \ __asm__ __volatile__("\n" \ " xorl %%edx, %%edx \n" \ " shldl %2, %%eax, %%edx \n" \ " shll %2, %%eax \n" \ " divl %3 \n" \ " cmpl $0,%%edx \n" \ " jz 0f \n" \ " incl %%eax \n" \ "0:\n" \ : "=a" (_ul_res) \ : "0" (_ul_num), "I" ((SHF)), "r" (_ul_den) \ : "%edx"); \ _ul_res; \ })

Computes 'ceil((num << SHF) / den' as unsigned long (32 bits).

This macro makes the same computation as ul_shl_div, but the result is rounded up to the next value, if it cannot be precisely represented.

Definition at line 62 of file qos_ul_i386.h.

Referenced by main(), and r2bw_ceil().

#define ul_shl_div | ( | num, | |||

SHF, | |||||

den | ) |

({ \ __volatile__ __u32 _ul_num = (num); \ __volatile__ __u32 _ul_den = (den); \ __volatile__ __u32 _ul_res; \ __asm__ __volatile__("\n" \ " xorl %%edx, %%edx \n" \ " shldl %2, %%eax, %%edx \n" \ " shll %2, %%eax \n" \ " divl %3 \n" \ : "=a" (_ul_res) \ : "0" (_ul_num), "I" ((SHF)), "r" (_ul_den) \ : "%edx"); \ _ul_res; \ })

Computes '(num << SHF) / den' as unsigned long (32 bits).

Computation is carried on with intermediate result (num << SHF) on 64 bits. This macro is useful for representing the result of the division num/dev as a real in fixed precision with SHF decimal bits (i.e. 1.0 is represented as 1ul<<SHF).

**Parameters:**-
*num*an unsigned long integer (32 bits) *SHF*a macro which evaluates to an integer within 1 and 31 *den*an unsigned long integer (32 bits)

**Returns:**- the result as an unsigned long integer (32 bits)

**Note:**- No overflow check is made after the division.

**Todo:**- Investigate on volatiles, that do not allow optimizations. They should not be required, but without them bw2Q(), which uses ul_mul_shr, outputs zero instead of the correct value.

Definition at line 41 of file qos_ul_i386.h.

Referenced by div_by_bw(), main(), and r2bw().

Generated on Mon Aug 2 22:39:17 2010 for qosres by 1.6.3