0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #ifndef __DAL_FIXED31_32_H__
0027 #define __DAL_FIXED31_32_H__
0028
0029 #ifndef LLONG_MAX
0030 #define LLONG_MAX 9223372036854775807ll
0031 #endif
0032 #ifndef LLONG_MIN
0033 #define LLONG_MIN (-LLONG_MAX - 1ll)
0034 #endif
0035
0036 #define FIXED31_32_BITS_PER_FRACTIONAL_PART 32
0037 #ifndef LLONG_MIN
0038 #define LLONG_MIN (1LL<<63)
0039 #endif
0040 #ifndef LLONG_MAX
0041 #define LLONG_MAX (-1LL>>1)
0042 #endif
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 struct fixed31_32 {
0058 long long value;
0059 };
0060
0061
0062
0063
0064
0065
0066
0067 static const struct fixed31_32 dc_fixpt_zero = { 0 };
0068 static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
0069 static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
0070 static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 struct fixed31_32 dc_fixpt_from_fraction(long long numerator, long long denominator);
0082
0083
0084
0085
0086
0087 static inline struct fixed31_32 dc_fixpt_from_int(int arg)
0088 {
0089 struct fixed31_32 res;
0090
0091 res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART;
0092
0093 return res;
0094 }
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 static inline struct fixed31_32 dc_fixpt_neg(struct fixed31_32 arg)
0106 {
0107 struct fixed31_32 res;
0108
0109 res.value = -arg.value;
0110
0111 return res;
0112 }
0113
0114
0115
0116
0117
0118 static inline struct fixed31_32 dc_fixpt_abs(struct fixed31_32 arg)
0119 {
0120 if (arg.value < 0)
0121 return dc_fixpt_neg(arg);
0122 else
0123 return arg;
0124 }
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static inline bool dc_fixpt_lt(struct fixed31_32 arg1, struct fixed31_32 arg2)
0136 {
0137 return arg1.value < arg2.value;
0138 }
0139
0140
0141
0142
0143
0144 static inline bool dc_fixpt_le(struct fixed31_32 arg1, struct fixed31_32 arg2)
0145 {
0146 return arg1.value <= arg2.value;
0147 }
0148
0149
0150
0151
0152
0153 static inline bool dc_fixpt_eq(struct fixed31_32 arg1, struct fixed31_32 arg2)
0154 {
0155 return arg1.value == arg2.value;
0156 }
0157
0158
0159
0160
0161
0162 static inline struct fixed31_32 dc_fixpt_min(struct fixed31_32 arg1, struct fixed31_32 arg2)
0163 {
0164 if (arg1.value <= arg2.value)
0165 return arg1;
0166 else
0167 return arg2;
0168 }
0169
0170
0171
0172
0173
0174 static inline struct fixed31_32 dc_fixpt_max(struct fixed31_32 arg1, struct fixed31_32 arg2)
0175 {
0176 if (arg1.value <= arg2.value)
0177 return arg2;
0178 else
0179 return arg1;
0180 }
0181
0182
0183
0184
0185
0186
0187
0188 static inline struct fixed31_32 dc_fixpt_clamp(
0189 struct fixed31_32 arg,
0190 struct fixed31_32 min_value,
0191 struct fixed31_32 max_value)
0192 {
0193 if (dc_fixpt_le(arg, min_value))
0194 return min_value;
0195 else if (dc_fixpt_le(max_value, arg))
0196 return max_value;
0197 else
0198 return arg;
0199 }
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 static inline struct fixed31_32 dc_fixpt_shl(struct fixed31_32 arg, unsigned char shift)
0211 {
0212 ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
0213 ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift))));
0214
0215 arg.value = arg.value << shift;
0216
0217 return arg;
0218 }
0219
0220
0221
0222
0223
0224 static inline struct fixed31_32 dc_fixpt_shr(struct fixed31_32 arg, unsigned char shift)
0225 {
0226 bool negative = arg.value < 0;
0227
0228 if (negative)
0229 arg.value = -arg.value;
0230 arg.value = arg.value >> shift;
0231 if (negative)
0232 arg.value = -arg.value;
0233 return arg;
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 static inline struct fixed31_32 dc_fixpt_add(struct fixed31_32 arg1, struct fixed31_32 arg2)
0246 {
0247 struct fixed31_32 res;
0248
0249 ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
0250 ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
0251
0252 res.value = arg1.value + arg2.value;
0253
0254 return res;
0255 }
0256
0257
0258
0259
0260
0261 static inline struct fixed31_32 dc_fixpt_add_int(struct fixed31_32 arg1, int arg2)
0262 {
0263 return dc_fixpt_add(arg1, dc_fixpt_from_int(arg2));
0264 }
0265
0266
0267
0268
0269
0270 static inline struct fixed31_32 dc_fixpt_sub(struct fixed31_32 arg1, struct fixed31_32 arg2)
0271 {
0272 struct fixed31_32 res;
0273
0274 ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
0275 ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
0276
0277 res.value = arg1.value - arg2.value;
0278
0279 return res;
0280 }
0281
0282
0283
0284
0285
0286 static inline struct fixed31_32 dc_fixpt_sub_int(struct fixed31_32 arg1, int arg2)
0287 {
0288 return dc_fixpt_sub(arg1, dc_fixpt_from_int(arg2));
0289 }
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 struct fixed31_32 dc_fixpt_mul(struct fixed31_32 arg1, struct fixed31_32 arg2);
0302
0303
0304
0305
0306
0307
0308 static inline struct fixed31_32 dc_fixpt_mul_int(struct fixed31_32 arg1, int arg2)
0309 {
0310 return dc_fixpt_mul(arg1, dc_fixpt_from_int(arg2));
0311 }
0312
0313
0314
0315
0316
0317 struct fixed31_32 dc_fixpt_sqr(struct fixed31_32 arg);
0318
0319
0320
0321
0322
0323 static inline struct fixed31_32 dc_fixpt_div_int(struct fixed31_32 arg1, long long arg2)
0324 {
0325 return dc_fixpt_from_fraction(arg1.value, dc_fixpt_from_int((int)arg2).value);
0326 }
0327
0328
0329
0330
0331
0332 static inline struct fixed31_32 dc_fixpt_div(struct fixed31_32 arg1, struct fixed31_32 arg2)
0333 {
0334 return dc_fixpt_from_fraction(arg1.value, arg2.value);
0335 }
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 struct fixed31_32 dc_fixpt_recip(struct fixed31_32 arg);
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 struct fixed31_32 dc_fixpt_sinc(struct fixed31_32 arg);
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 struct fixed31_32 dc_fixpt_sin(struct fixed31_32 arg);
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 struct fixed31_32 dc_fixpt_cos(struct fixed31_32 arg);
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400 struct fixed31_32 dc_fixpt_exp(struct fixed31_32 arg);
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 struct fixed31_32 dc_fixpt_log(struct fixed31_32 arg);
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426 static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2)
0427 {
0428 if (arg1.value == 0)
0429 return arg2.value == 0 ? dc_fixpt_one : dc_fixpt_zero;
0430
0431 return dc_fixpt_exp(
0432 dc_fixpt_mul(
0433 dc_fixpt_log(arg1),
0434 arg2));
0435 }
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446 static inline int dc_fixpt_floor(struct fixed31_32 arg)
0447 {
0448 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
0449
0450 if (arg.value >= 0)
0451 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
0452 else
0453 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
0454 }
0455
0456
0457
0458
0459
0460 static inline int dc_fixpt_round(struct fixed31_32 arg)
0461 {
0462 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
0463
0464 const long long summand = dc_fixpt_half.value;
0465
0466 ASSERT(LLONG_MAX - (long long)arg_value >= summand);
0467
0468 arg_value += summand;
0469
0470 if (arg.value >= 0)
0471 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
0472 else
0473 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
0474 }
0475
0476
0477
0478
0479
0480 static inline int dc_fixpt_ceil(struct fixed31_32 arg)
0481 {
0482 unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value;
0483
0484 const long long summand = dc_fixpt_one.value -
0485 dc_fixpt_epsilon.value;
0486
0487 ASSERT(LLONG_MAX - (long long)arg_value >= summand);
0488
0489 arg_value += summand;
0490
0491 if (arg.value >= 0)
0492 return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
0493 else
0494 return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
0495 }
0496
0497
0498
0499
0500
0501
0502
0503 unsigned int dc_fixpt_u4d19(struct fixed31_32 arg);
0504
0505 unsigned int dc_fixpt_u3d19(struct fixed31_32 arg);
0506
0507 unsigned int dc_fixpt_u2d19(struct fixed31_32 arg);
0508
0509 unsigned int dc_fixpt_u0d19(struct fixed31_32 arg);
0510
0511 unsigned int dc_fixpt_clamp_u0d14(struct fixed31_32 arg);
0512
0513 unsigned int dc_fixpt_clamp_u0d10(struct fixed31_32 arg);
0514
0515 int dc_fixpt_s4d19(struct fixed31_32 arg);
0516
0517 static inline struct fixed31_32 dc_fixpt_truncate(struct fixed31_32 arg, unsigned int frac_bits)
0518 {
0519 bool negative = arg.value < 0;
0520
0521 if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) {
0522 ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART);
0523 return arg;
0524 }
0525
0526 if (negative)
0527 arg.value = -arg.value;
0528 arg.value &= (~0LL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits);
0529 if (negative)
0530 arg.value = -arg.value;
0531 return arg;
0532 }
0533
0534 #endif