aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h
blob: a025ad562bd2a15f8dda642a4a70edb6f768c0a3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
/*
 * Support for Intel Camera Imaging ISP subsystem.
 * Copyright (c) 2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#ifndef __ISP_OP1W_H_INCLUDED__
#define __ISP_OP1W_H_INCLUDED__

/*
 * This file is part of the Multi-precision vector operations exstension package.
 */

/*
 * Single-precision vector operations
 */

/*
 * Prerequisites:
 *
 */

#ifdef INLINE_ISP_OP1W
#define STORAGE_CLASS_ISP_OP1W_FUNC_H static inline
#define STORAGE_CLASS_ISP_OP1W_DATA_H static inline_DATA
#else /* INLINE_ISP_OP1W */
#define STORAGE_CLASS_ISP_OP1W_FUNC_H extern
#define STORAGE_CLASS_ISP_OP1W_DATA_H extern_DATA
#endif  /* INLINE_ISP_OP1W */

/*
 * Single-precision data type specification
 */

#include "isp_op1w_types.h"
#include "isp_op2w_types.h" // for doubling operations.

/*
 * Single-precision prototype specification
 */

/* Arithmetic */

/** @brief bitwise AND
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		bitwise and of both input arguments
 *
 * This function will calculate the bitwise and.
 * result = _a & _b
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_and(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief bitwise OR
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		bitwise or of both input arguments
 *
 * This function will calculate the bitwise or.
 * result = _a | _b
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_or(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief bitwise XOR
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		bitwise xor of both input arguments
 *
 * This function will calculate the bitwise xor.
 * result = _a ^ _b
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_xor(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief bitwise inverse
 *
 * @param[in] _a	first argument
 *
 * @return		bitwise inverse of both input arguments
 *
 * This function will calculate the bitwise inverse.
 * result = ~_a
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_inv(
    const tvector1w     _a);

/* Additive */

/** @brief addition
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		sum of both input arguments
 *
 * This function will calculate the sum of the input arguments.
 * in case of overflow it will wrap around.
 * result = _a + _b
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_add(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief subtraction
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_b subtracted from _a.
 *
 * This function will subtract _b from _a.
 * in case of overflow it will wrap around.
 * result = _a - _b
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_sub(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief saturated addition
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		saturated sum of both input arguments
 *
 * This function will calculate the sum of the input arguments.
 * in case of overflow it will saturate.
 * result = CLIP(_a + _b, MIN_RANGE, MAX_RANGE);
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_addsat(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief saturated subtraction
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		saturated subtraction of both input arguments
 *
 * This function will subtract _b from _a.
 * in case of overflow it will saturate.
 * result = CLIP(_a - _b, MIN_RANGE, MAX_RANGE);
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subsat(
    const tvector1w     _a,
    const tvector1w     _b);

#ifdef ISP2401
/** @brief Unsigned saturated subtraction
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		saturated subtraction of both input arguments
 *
 * This function will subtract _b from _a.
 * in case of overflow it will saturate.
 * result = CLIP(_a - _b, 0, MAX_RANGE);
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w_unsigned OP_1w_subsat_u(
    const tvector1w_unsigned _a,
    const tvector1w_unsigned _b);

#endif
/** @brief subtraction with shift right and rounding
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		(a - b) >> 1
 *
 * This function subtracts _b from _a and right shifts
 * the result by 1 bit with rounding.
 * No overflow can occur.
 * result = (_a - _b) >> 1
 *
 * Note: This function will be deprecated due to
 * the naming confusion and it will be replaced
 * by "OP_1w_subhalfrnd".
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subasr1(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Subtraction with shift right and rounding
 *
 * @param[in] _a	first operand
 * @param[in] _b	second operand
 *
 * @return		(_a - _b) >> 1
 *
 * This function subtracts _b from _a and right shifts
 * the result by 1 bit with rounding.
 * No overflow can occur.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subhalfrnd(
    const tvector1w	_a,
    const tvector1w	_b);

/** @brief Subtraction with shift right and no rounding
 *
 * @param[in] _a	first operand
 * @param[in] _b	second operand
 *
 * @return		(_a - _b) >> 1
 *
 * This function subtracts _b from _a and right shifts
 * the result by 1 bit without rounding (i.e. truncation).
 * No overflow can occur.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subhalf(
    const tvector1w	_a,
    const tvector1w	_b);


/** @brief saturated absolute value
 *
 * @param[in] _a	input
 *
 * @return		saturated absolute value of the input
 *
 * This function will calculate the saturated absolute value of the input.
 * in case of overflow it will saturate.
 * if (_a > 0) return _a;<br>
 * else return CLIP(-_a, MIN_RANGE, MAX_RANGE);<br>
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_abs(
    const tvector1w     _a);

/** @brief saturated absolute difference
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		sat(abs(a-b));
 *
 * This function will calculate the saturated absolute value
 * of the saturated difference of both inputs.
 * result = sat(abs(sat(_a - _b)));
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subabssat(
    const tvector1w     _a,
    const tvector1w     _b);

/* Multiplicative */

/** @brief doubling multiply
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		product of _a and _b
 *
 * This function will calculate the product
 * of the input arguments and returns a double
 * precision result.
 * No overflow can occur.
 * result = _a * _b;
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector2w OP_1w_muld(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief integer multiply
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		product of _a and _b
 *
 * This function will calculate the product
 * of the input arguments and returns the LSB
 * aligned single precision result.
 * In case of overflow it will wrap around.
 * result = _a * _b;
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_mul(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief fractional saturating multiply
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		saturated product of _a and _b
 *
 * This function will calculate the fixed point
 * product of the input arguments
 * and returns a single precision result.
 * In case of overflow it will saturate.
 * FP_UNITY * FP_UNITY => FP_UNITY.
 * result = CLIP(_a * _b >> (NUM_BITS-1), MIN_RANGE, MAX_RANGE);
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_qmul(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief fractional saturating multiply with rounding
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		product of _a and _b
 *
 * This function will calculate the fixed point
 * product of the input arguments
 * and returns a single precision result.
 * FP_UNITY * FP_UNITY => FP_UNITY.
 * Depending on the rounding mode of the core
 * it will round to nearest or to nearest even.
 * result = CLIP(_a * _b >> (NUM_BITS-1), MIN_RANGE, MAX_RANGE);
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_qrmul(
    const tvector1w     _a,
    const tvector1w     _b);

/* Comparative */

/** @brief equal
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a == _b
 *
 * This function will return true if both inputs
 * are equal, and false if not equal.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_eq(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief not equal
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a != _b
 *
 * This function will return false if both inputs
 * are equal, and true if not equal.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_ne(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief less or equal
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a <= _b
 *
 * This function will return true if _a is smaller
 * or equal than _b.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_le(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief less then
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a < _b
 *
 * This function will return true if _a is smaller
 * than _b.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_lt(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief greater or equal
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a >= _b
 *
 * This function will return true if _a is greater
 * or equal than _b.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_ge(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief greater than
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a > _b
 *
 * This function will return true if _a is greater
 * than _b.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_gt(
    const tvector1w     _a,
    const tvector1w     _b);

/* Shift */

/** @brief aritmetic shift right
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a >> _b
 *
 * This function will shift _a with _b bits to the right,
 * preserving the sign bit.
 * It asserts 0 <= _b <= MAX_SHIFT_1W.
 *
 * The operation count for this function assumes that
 * the shift amount is a cloned scalar input.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_asr(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief aritmetic shift right with rounding
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a >> _b
 *
 * If _b < NUM_BITS, this function will shift _a with _b bits to the right,
 * preserving the sign bit, and depending on the rounding mode of the core
 * it will round to nearest or to nearest even.
 * If _b >= NUM_BITS, this function will return 0.
 * It asserts 0 <= _b <= MAX_SHIFT_1W.
 * The operation count for this function assumes that
 * the shift amount is a cloned scalar input.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_asrrnd(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief saturating arithmetic shift left
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a << _b
 *
 * If _b < MAX_BITDEPTH, this function will shift _a with _b bits to the left,
 * saturating at MIN_RANGE/MAX_RANGE in case of overflow.
 * If _b >= MAX_BITDEPTH, this function will return MIN_RANGE if _a < 0,
 * MAX_RANGE if _a > 0, 0 if _a == 0.
 * (with MAX_BITDEPTH=64)
 * It asserts 0 <= _b <= MAX_SHIFT_1W.
 * The operation count for this function assumes that
 * the shift amount is a cloned scalar input.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_asl(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief saturating aritmetic shift left
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a << _b
 *
 * This function is identical to OP_1w_asl( )
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_aslsat(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief logical shift left
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a << _b
 *
 * This function will shift _a with _b bits to the left.
 * It will insert zeroes on the right.
 * It asserts 0 <= _b <= MAX_SHIFT_1W.
 * The operation count for this function assumes that
 * the shift amount is a cloned scalar input.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_lsl(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief logical shift right
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a >> _b
 *
 * This function will shift _a with _b bits to the right.
 * It will insert zeroes on the left.
 * It asserts 0 <= _b <= MAX_SHIFT_1W.
 * The operation count for this function assumes that
 * the shift amount is a cloned scalar input.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_lsr(
    const tvector1w     _a,
    const tvector1w     _b);

#ifdef ISP2401
/** @brief bidirectional saturating arithmetic shift
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a << |_b| if _b is positive
 *			_a >> |_b| if _b is negative
 *
 * If _b > 0, this function will shift _a with _b bits to the left,
 * saturating at MIN_RANGE/MAX_RANGE in case of overflow.
 * if _b < 0, this function will shift _a with _b bits to the right.
 * It asserts -MAX_SHIFT_1W <= _b <= MAX_SHIFT_1W.
 * If _b = 0, it returns _a.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_ashift_sat(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief bidirectional non-saturating arithmetic shift
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a << |_b| if _b is positive
 *			_a >> |_b| if _b is negative
 *
 * If _b > 0, this function will shift _a with _b bits to the left,
 * no saturation is performed in case of overflow.
 * if _b < 0, this function will shift _a with _b bits to the right.
 * It asserts -MAX_SHIFT_1W <= _b <= MAX_SHIFT_1W.
 * If _b = 0, it returns _a.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_ashift(
    const tvector1w     _a,
    const tvector1w     _b);


/** @brief bidirectional logical shift
 *
 * @param[in] _a	input
 * @param[in] _b	shift amount
 *
 * @return		_a << |_b| if _b is positive
 *			_a >> |_b| if _b is negative
 *
 * This function will shift _a with _b bits to the left if _b is positive.
 * This function will shift _a with _b bits to the right if _b is negative.
 * It asserts -MAX_SHIFT_1W <= _b <= MAX_SHIFT_1W.
 * It inserts zeros on the left or right depending on the shift direction: 
 * right or left.
 * The operation count for this function assumes that
 * the shift amount is a cloned scalar input.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_lshift(
    const tvector1w     _a,
    const tvector1w     _b);

#endif
/* Cast */

/** @brief Cast from int to 1w
 *
 * @param[in] _a	input
 *
 * @return		_a
 *
 * This function casts the input from integer type to
 * single precision. It asserts there is no overflow.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_int_cast_to_1w(
    const int           _a);

/** @brief Cast from 1w to int
 *
 * @param[in] _a	input
 *
 * @return		_a
 *
 * This function casts the input from single precision type to
 * integer, preserving value and sign.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H int OP_1w_cast_to_int(
    const tvector1w      _a);

/** @brief Cast from 1w to 2w
 *
 * @param[in] _a	input
 *
 * @return		_a
 *
 * This function casts the input from single precision type to
 * double precision, preserving value and sign.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector2w OP_1w_cast_to_2w(
    const tvector1w     _a);

/** @brief Cast from 2w to 1w
 *
 * @param[in] _a	input
 *
 * @return		_a
 *
 * This function casts the input from double precision type to
 * single precision. In case of overflow it will wrap around.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_2w_cast_to_1w(
    const tvector2w    _a);


/** @brief Cast from 2w to 1w with saturation
 *
 * @param[in] _a	input
 *
 * @return		_a
 *
 * This function casts the input from double precision type to
 * single precision after saturating it to the range of single
 * precision.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_2w_sat_cast_to_1w(
    const tvector2w    _a);

/* clipping */

/** @brief Clip asymmetrical
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a clipped between ~_b and b
 *
 * This function will clip the first argument between
 * (-_b - 1) and _b.
 * It asserts _b >= 0.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_clip_asym(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Clip zero
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a clipped beteween 0 and _b
 *
 * This function will clip the first argument between
 * zero and _b.
 * It asserts _b >= 0.
 *
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_clipz(
    const tvector1w     _a,
    const tvector1w     _b);

/* division */

/** @brief Truncated division
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		trunc( _a / _b )
 *
 * This function will divide the first argument by
 * the second argument, with rounding toward 0.
 * If _b == 0 and _a <  0, the function will return MIN_RANGE.
 * If _b == 0 and _a == 0, the function will return 0.
 * If _b == 0 and _a >  0, the function will return MAX_RANGE.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_div(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Fractional saturating divide
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a / _b
 *
 * This function will perform fixed point division of
 * the first argument by the second argument, with rounding toward 0.
 * In case of overflow it will saturate.
 * If _b == 0 and _a <  0, the function will return MIN_RANGE.
 * If _b == 0 and _a == 0, the function will return 0.
 * If _b == 0 and _a >  0, the function will return MAX_RANGE.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_qdiv(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Modulo
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		_a % _b
 *
 * This function will return the remainder r = _a - _b * trunc( _a / _b ),
 * Note that the sign of the remainder is always equal to the sign of _a.
 * If _b == 0 the function will return _a.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_mod(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Unsigned integer Square root
 *
 * @param[in] _a	input
 *
 * @return		Integer square root of _a
 *
 * This function will calculate the Integer square root of _a
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w_unsigned OP_1w_sqrt_u(
	const tvector1w_unsigned     _a);

/* Miscellaneous */

/** @brief Multiplexer
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 * @param[in] _c	condition
 *
 * @return		_c ? _a : _b
 *
 * This function will return _a if the condition _c
 * is true and _b otherwise.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_mux(
    const tvector1w     _a,
    const tvector1w     _b,
    const tflags           _c);

/** @brief Average without rounding
 *
 * @param[in] _a	first operand
 * @param[in] _b	second operand
 *
 * @return		(_a + _b) >> 1
 *
 * This function will add _a and _b, and right shift
 * the result by one without rounding. No overflow
 * will occur because addition is performed in the
 * proper precision.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w  OP_1w_avg(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Average with rounding
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		(_a + _b) >> 1
 *
 * This function will add _a and _b at full precision,
 * and right shift with rounding the result with 1 bit.
 * Depending on the rounding mode of the core
 * it will round to nearest or to nearest even.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_avgrnd(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Minimum
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		(_a < _b) ? _a : _b;
 *
 * This function will return the smallest of both
 * input arguments.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_min(
    const tvector1w     _a,
    const tvector1w     _b);

/** @brief Maximum
 *
 * @param[in] _a	first argument
 * @param[in] _b	second argument
 *
 * @return		(_a > _b) ? _a : _b;
 *
 * This function will return the largest of both
 * input arguments.
 */
STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_max(
    const tvector1w     _a,
    const tvector1w     _b);

#ifndef INLINE_ISP_OP1W
#define STORAGE_CLASS_ISP_OP1W_FUNC_C
#define STORAGE_CLASS_ISP_OP1W_DATA_C const
#else /* INLINE_ISP_OP1W */
#define STORAGE_CLASS_ISP_OP1W_FUNC_C STORAGE_CLASS_ISP_OP1W_FUNC_H
#define STORAGE_CLASS_ISP_OP1W_DATA_C STORAGE_CLASS_ISP_OP1W_DATA_H
#include "isp_op1w.c"
#define ISP_OP1W_INLINED
#endif  /* INLINE_ISP_OP1W */

#endif /* __ISP_OP1W_H_INCLUDED__ */