-
Notifications
You must be signed in to change notification settings - Fork 0
/
vec__bcd__ppc_8h.html
5050 lines (4819 loc) · 394 KB
/
vec__bcd__ppc_8h.html
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
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.17"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>POWER Vector Library Manual: src/pveclib/vec_bcd_ppc.h File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">POWER Vector Library Manual
 <span id="projectnumber">1.0.4</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.17 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_68267d1309a1af8e8297ef4c3efbcdba.html">src</a></li><li class="navelem"><a class="el" href="dir_3653a864936a87c29f489ec2a5b8be1c.html">pveclib</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#define-members">Macros</a> |
<a href="#func-members">Functions</a> </div>
<div class="headertitle">
<div class="title">vec_bcd_ppc.h File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p>Header package containing a collection of Binary Coded Decimal (<b>BCD</b>) computation and Zoned Character conversion operations on vector registers.
<a href="#details">More...</a></p>
<div class="textblock"><code>#include <<a class="el" href="vec__common__ppc_8h_source.html">pveclib/vec_common_ppc.h</a>></code><br />
<code>#include <<a class="el" href="vec__char__ppc_8h_source.html">pveclib/vec_char_ppc.h</a>></code><br />
<code>#include <<a class="el" href="vec__int128__ppc_8h_source.html">pveclib/vec_int128_ppc.h</a>></code><br />
</div>
<p><a href="vec__bcd__ppc_8h_source.html">Go to the source code of this file.</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
Macros</h2></td></tr>
<tr class="memitem:a3bf3bca0987b1225b4c33bfdf0c5c532"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>   <a class="el" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a></td></tr>
<tr class="memdesc:a3bf3bca0987b1225b4c33bfdf0c5c532"><td class="mdescLeft"> </td><td class="mdescRight">vector signed BCD integer of up to 31 decimal digits. <a href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">More...</a><br /></td></tr>
<tr class="separator:a3bf3bca0987b1225b4c33bfdf0c5c532"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a86aa60d4e8d1f7ef10e3796d052499d7"><td class="memItemLeft" align="right" valign="top"><a id="a86aa60d4e8d1f7ef10e3796d052499d7"></a>
#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a>   <a class="el" href="vec__common__ppc_8h.html#aafeddf1e79ef817440ff01fafb0e00ca">vb32_t</a></td></tr>
<tr class="memdesc:a86aa60d4e8d1f7ef10e3796d052499d7"><td class="mdescLeft"> </td><td class="mdescRight">vector vector bool from 128-bit signed BCD integer. <br /></td></tr>
<tr class="separator:a86aa60d4e8d1f7ef10e3796d052499d7"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ac2eb804164fac106d89ef8fb9cf6a877"><td class="memItemLeft" align="right" valign="top"><a id="ac2eb804164fac106d89ef8fb9cf6a877"></a>
#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ac2eb804164fac106d89ef8fb9cf6a877">_BCD_CONST_PLUS_NINES</a>   ((<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="el" href="vec__common__ppc_8h.html#a562dba1b4daf1f8ecb38841ec38c9b4d">CONST_VINT128_DW128</a>(0x9999999999999999, 0x999999999999999c))</td></tr>
<tr class="memdesc:ac2eb804164fac106d89ef8fb9cf6a877"><td class="mdescLeft"> </td><td class="mdescRight">vector signed BCD constant +9s. <br /></td></tr>
<tr class="separator:ac2eb804164fac106d89ef8fb9cf6a877"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a2dc4f754b3261ac01c51a4e30b332488"><td class="memItemLeft" align="right" valign="top"><a id="a2dc4f754b3261ac01c51a4e30b332488"></a>
#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>   ((<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="el" href="vec__common__ppc_8h.html#a562dba1b4daf1f8ecb38841ec38c9b4d">CONST_VINT128_DW128</a>(0, 0x1c))</td></tr>
<tr class="memdesc:a2dc4f754b3261ac01c51a4e30b332488"><td class="mdescLeft"> </td><td class="mdescRight">vector signed BCD constant +1. <br /></td></tr>
<tr class="separator:a2dc4f754b3261ac01c51a4e30b332488"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a33ef981c324ce5c25152651b9f40965c"><td class="memItemLeft" align="right" valign="top"><a id="a33ef981c324ce5c25152651b9f40965c"></a>
#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a33ef981c324ce5c25152651b9f40965c">_BCD_CONST_MINUS_ONE</a>   ((<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="el" href="vec__common__ppc_8h.html#a562dba1b4daf1f8ecb38841ec38c9b4d">CONST_VINT128_DW128</a>(0, 0x1d))</td></tr>
<tr class="memdesc:a33ef981c324ce5c25152651b9f40965c"><td class="mdescLeft"> </td><td class="mdescRight">vector signed BCD constant -1. <br /></td></tr>
<tr class="separator:a33ef981c324ce5c25152651b9f40965c"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a65571de03c8870470db44b1abb9dbcb7"><td class="memItemLeft" align="right" valign="top"><a id="a65571de03c8870470db44b1abb9dbcb7"></a>
#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>   ((<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="el" href="vec__common__ppc_8h.html#a562dba1b4daf1f8ecb38841ec38c9b4d">CONST_VINT128_DW128</a>(0, 0x0c))</td></tr>
<tr class="memdesc:a65571de03c8870470db44b1abb9dbcb7"><td class="mdescLeft"> </td><td class="mdescRight">vector signed BCD constant +0. <br /></td></tr>
<tr class="separator:a65571de03c8870470db44b1abb9dbcb7"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a50e023591594ad9e7110702fed96d9c7"><td class="memItemLeft" align="right" valign="top"><a id="a50e023591594ad9e7110702fed96d9c7"></a>
#define </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a50e023591594ad9e7110702fed96d9c7">_BCD_CONST_SIGN_MASK</a>   ((<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="el" href="vec__common__ppc_8h.html#a562dba1b4daf1f8ecb38841ec38c9b4d">CONST_VINT128_DW128</a>(0, 0xf))</td></tr>
<tr class="memdesc:a50e023591594ad9e7110702fed96d9c7"><td class="mdescLeft"> </td><td class="mdescRight">vector BCD sign mask in bits 124:127. <br /></td></tr>
<tr class="separator:a50e023591594ad9e7110702fed96d9c7"><td class="memSeparator" colspan="2"> </td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:adc0e4636d0720f8b3b6d22268b2cc3e0"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#adc0e4636d0720f8b3b6d22268b2cc3e0">vec_BCD2BIN</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> val)</td></tr>
<tr class="memdesc:adc0e4636d0720f8b3b6d22268b2cc3e0"><td class="mdescLeft"> </td><td class="mdescRight">Convert vector of 2 x unsigned 16-digit BCD values to vector 2 x doubleword binary values. <a href="vec__bcd__ppc_8h.html#adc0e4636d0720f8b3b6d22268b2cc3e0">More...</a><br /></td></tr>
<tr class="separator:adc0e4636d0720f8b3b6d22268b2cc3e0"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aa924d03e2f88506e323c4b70f4b7df8b"><td class="memItemLeft" align="right" valign="top">static _Decimal128 </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> val)</td></tr>
<tr class="memdesc:aa924d03e2f88506e323c4b70f4b7df8b"><td class="mdescLeft"> </td><td class="mdescRight">Convert a Vector Signed BCD value to __Decimal128. <a href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">More...</a><br /></td></tr>
<tr class="separator:aa924d03e2f88506e323c4b70f4b7df8b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ad4222bd4b90a5248015fbea12cbc0a21"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ad4222bd4b90a5248015fbea12cbc0a21">vec_BIN2BCD</a> (<a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> val)</td></tr>
<tr class="memdesc:ad4222bd4b90a5248015fbea12cbc0a21"><td class="mdescLeft"> </td><td class="mdescRight">Convert vector unsigned doubleword binary values to Vector unsigned 16-digit BCD values. <a href="vec__bcd__ppc_8h.html#ad4222bd4b90a5248015fbea12cbc0a21">More...</a><br /></td></tr>
<tr class="separator:ad4222bd4b90a5248015fbea12cbc0a21"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ad8123fa00f666a0d439a049eb4f7c7eb"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ad8123fa00f666a0d439a049eb4f7c7eb">vec_DFP2BCD</a> (_Decimal128 val)</td></tr>
<tr class="memdesc:ad8123fa00f666a0d439a049eb4f7c7eb"><td class="mdescLeft"> </td><td class="mdescRight">Convert a __Decimal128 value to Vector BCD. <a href="vec__bcd__ppc_8h.html#ad8123fa00f666a0d439a049eb4f7c7eb">More...</a><br /></td></tr>
<tr class="separator:ad8123fa00f666a0d439a049eb4f7c7eb"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a047be6d6339193b854e0b41759888939"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">vec_bcdadd</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a047be6d6339193b854e0b41759888939"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Add Signed Modulo Quadword. <a href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">More...</a><br /></td></tr>
<tr class="separator:a047be6d6339193b854e0b41759888939"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a76d5034289bea5c7d9159db1d443f6b7"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a76d5034289bea5c7d9159db1d443f6b7">vec_bcdaddcsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a76d5034289bea5c7d9159db1d443f6b7"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Add & write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#a76d5034289bea5c7d9159db1d443f6b7">More...</a><br /></td></tr>
<tr class="separator:a76d5034289bea5c7d9159db1d443f6b7"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a6bf159e0abdccaa6fca21c6567b2067b"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a6bf159e0abdccaa6fca21c6567b2067b">vec_bcdaddecsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c)</td></tr>
<tr class="memdesc:a6bf159e0abdccaa6fca21c6567b2067b"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Add Extended & write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#a6bf159e0abdccaa6fca21c6567b2067b">More...</a><br /></td></tr>
<tr class="separator:a6bf159e0abdccaa6fca21c6567b2067b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a3411797c249e42c9c96f6e0b239e6e50"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">vec_bcdaddesqm</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c)</td></tr>
<tr class="memdesc:a3411797c249e42c9c96f6e0b239e6e50"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Add Extended Signed Modulo Quadword. <a href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">More...</a><br /></td></tr>
<tr class="separator:a3411797c249e42c9c96f6e0b239e6e50"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a5a1aec05a6dadcf5a1a8e028223745df"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a5a1aec05a6dadcf5a1a8e028223745df">vec_bcdcfsq</a> (<a class="el" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a> vrb)</td></tr>
<tr class="memdesc:a5a1aec05a6dadcf5a1a8e028223745df"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert From Signed Quadword returning up to 31 BCD digits. <a href="vec__bcd__ppc_8h.html#a5a1aec05a6dadcf5a1a8e028223745df">More...</a><br /></td></tr>
<tr class="separator:a5a1aec05a6dadcf5a1a8e028223745df"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a049f327cf7468a13cfbda107a178d009"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a049f327cf7468a13cfbda107a178d009">vec_bcdcfud</a> (<a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> vrb)</td></tr>
<tr class="memdesc:a049f327cf7468a13cfbda107a178d009"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert From Unsigned doubleword returning up to 2x16 BCD digits. <a href="vec__bcd__ppc_8h.html#a049f327cf7468a13cfbda107a178d009">More...</a><br /></td></tr>
<tr class="separator:a049f327cf7468a13cfbda107a178d009"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a7b8b5371d537cd878ffb37337e93ba14"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a7b8b5371d537cd878ffb37337e93ba14">vec_bcdcfuq</a> (<a class="el" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> vra)</td></tr>
<tr class="memdesc:a7b8b5371d537cd878ffb37337e93ba14"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert From Unsigned Quadword returning up to 32 BCD digits. <a href="vec__bcd__ppc_8h.html#a7b8b5371d537cd878ffb37337e93ba14">More...</a><br /></td></tr>
<tr class="separator:a7b8b5371d537cd878ffb37337e93ba14"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ae4923e7e5746c5c6f21ddc9993894692"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ae4923e7e5746c5c6f21ddc9993894692">vec_bcdcfz</a> (<a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vrb)</td></tr>
<tr class="memdesc:ae4923e7e5746c5c6f21ddc9993894692"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert From Zoned. <a href="vec__bcd__ppc_8h.html#ae4923e7e5746c5c6f21ddc9993894692">More...</a><br /></td></tr>
<tr class="separator:ae4923e7e5746c5c6f21ddc9993894692"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ac547402f2432e08ac47123d93a0dc36d"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ac547402f2432e08ac47123d93a0dc36d">vec_bcdcmp_eqsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:ac547402f2432e08ac47123d93a0dc36d"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for equal. <a href="vec__bcd__ppc_8h.html#ac547402f2432e08ac47123d93a0dc36d">More...</a><br /></td></tr>
<tr class="separator:ac547402f2432e08ac47123d93a0dc36d"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a128ecc0b91f7157902f4f5b1c9fc2cc5"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a128ecc0b91f7157902f4f5b1c9fc2cc5">vec_bcdcmp_gesq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a128ecc0b91f7157902f4f5b1c9fc2cc5"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for greater than or equal. <a href="vec__bcd__ppc_8h.html#a128ecc0b91f7157902f4f5b1c9fc2cc5">More...</a><br /></td></tr>
<tr class="separator:a128ecc0b91f7157902f4f5b1c9fc2cc5"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a4da91176af0a3ec68eb23cab56fd97e8"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a4da91176af0a3ec68eb23cab56fd97e8">vec_bcdcmp_gtsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a4da91176af0a3ec68eb23cab56fd97e8"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for greater than. <a href="vec__bcd__ppc_8h.html#a4da91176af0a3ec68eb23cab56fd97e8">More...</a><br /></td></tr>
<tr class="separator:a4da91176af0a3ec68eb23cab56fd97e8"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aefb25dd6da317584946ad502045742e6"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aefb25dd6da317584946ad502045742e6">vec_bcdcmp_lesq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:aefb25dd6da317584946ad502045742e6"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for less than or equal. <a href="vec__bcd__ppc_8h.html#aefb25dd6da317584946ad502045742e6">More...</a><br /></td></tr>
<tr class="separator:aefb25dd6da317584946ad502045742e6"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a8b44c71b7e48d79892356c3ceb86df26"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a8b44c71b7e48d79892356c3ceb86df26">vec_bcdcmp_ltsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a8b44c71b7e48d79892356c3ceb86df26"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for less than. <a href="vec__bcd__ppc_8h.html#a8b44c71b7e48d79892356c3ceb86df26">More...</a><br /></td></tr>
<tr class="separator:a8b44c71b7e48d79892356c3ceb86df26"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aefb8a409eea857401b082dbdb129e88f"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a86aa60d4e8d1f7ef10e3796d052499d7">vbBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aefb8a409eea857401b082dbdb129e88f">vec_bcdcmp_nesq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:aefb8a409eea857401b082dbdb129e88f"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for not equal. <a href="vec__bcd__ppc_8h.html#aefb8a409eea857401b082dbdb129e88f">More...</a><br /></td></tr>
<tr class="separator:aefb8a409eea857401b082dbdb129e88f"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a1dcd1cfe33aeaa26b23bdd6f9f535361"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a1dcd1cfe33aeaa26b23bdd6f9f535361">vec_bcdcmpeq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a1dcd1cfe33aeaa26b23bdd6f9f535361"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for equal. <a href="vec__bcd__ppc_8h.html#a1dcd1cfe33aeaa26b23bdd6f9f535361">More...</a><br /></td></tr>
<tr class="separator:a1dcd1cfe33aeaa26b23bdd6f9f535361"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a9c029287dd2dbc35725faa77354ab599"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a9c029287dd2dbc35725faa77354ab599">vec_bcdcmpge</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a9c029287dd2dbc35725faa77354ab599"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for greater than or equal. <a href="vec__bcd__ppc_8h.html#a9c029287dd2dbc35725faa77354ab599">More...</a><br /></td></tr>
<tr class="separator:a9c029287dd2dbc35725faa77354ab599"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aec74a780fd101d45c3c0823ad3d575ca"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aec74a780fd101d45c3c0823ad3d575ca">vec_bcdcmpgt</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:aec74a780fd101d45c3c0823ad3d575ca"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for greater than. <a href="vec__bcd__ppc_8h.html#aec74a780fd101d45c3c0823ad3d575ca">More...</a><br /></td></tr>
<tr class="separator:aec74a780fd101d45c3c0823ad3d575ca"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a3d4226f530eac6fdd969ed108261847e"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a3d4226f530eac6fdd969ed108261847e">vec_bcdcmple</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a3d4226f530eac6fdd969ed108261847e"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for less than or equal. <a href="vec__bcd__ppc_8h.html#a3d4226f530eac6fdd969ed108261847e">More...</a><br /></td></tr>
<tr class="separator:a3d4226f530eac6fdd969ed108261847e"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a53238244fe1850d37020510aa488d14e"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a53238244fe1850d37020510aa488d14e">vec_bcdcmplt</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a53238244fe1850d37020510aa488d14e"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for less than. <a href="vec__bcd__ppc_8h.html#a53238244fe1850d37020510aa488d14e">More...</a><br /></td></tr>
<tr class="separator:a53238244fe1850d37020510aa488d14e"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a0666db6a81b174fd84f3b5cffe2f93ae"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a0666db6a81b174fd84f3b5cffe2f93ae">vec_bcdcmpne</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a0666db6a81b174fd84f3b5cffe2f93ae"><td class="mdescLeft"> </td><td class="mdescRight">Vector Compare Signed BCD Quadword for not equal. <a href="vec__bcd__ppc_8h.html#a0666db6a81b174fd84f3b5cffe2f93ae">More...</a><br /></td></tr>
<tr class="separator:a0666db6a81b174fd84f3b5cffe2f93ae"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:abeda7137bef8dfc50d539c86f40d8070"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:abeda7137bef8dfc50d539c86f40d8070"><td class="mdescLeft"> </td><td class="mdescRight">Vector copy sign BCD. <a href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">More...</a><br /></td></tr>
<tr class="separator:abeda7137bef8dfc50d539c86f40d8070"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a5086ba6056febb11acd5d5cd18e96dfb"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a5086ba6056febb11acd5d5cd18e96dfb">vec_bcdctsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:a5086ba6056febb11acd5d5cd18e96dfb"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert to Signed Quadword. <a href="vec__bcd__ppc_8h.html#a5086ba6056febb11acd5d5cd18e96dfb">More...</a><br /></td></tr>
<tr class="separator:a5086ba6056febb11acd5d5cd18e96dfb"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:af89689661c664a010554081b8aba5a49"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#af89689661c664a010554081b8aba5a49">vec_bcdctub</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:af89689661c664a010554081b8aba5a49"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert Binary Coded Decimal (BCD) digit pairs to binary unsigned bytes . <a href="vec__bcd__ppc_8h.html#af89689661c664a010554081b8aba5a49">More...</a><br /></td></tr>
<tr class="separator:af89689661c664a010554081b8aba5a49"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:af039194f94028cd7e61d5e52ebb57ce5"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#af039194f94028cd7e61d5e52ebb57ce5">vec_bcdctuh</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:af039194f94028cd7e61d5e52ebb57ce5"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert groups of 4 BCD digits to binary unsigned halfwords. <a href="vec__bcd__ppc_8h.html#af039194f94028cd7e61d5e52ebb57ce5">More...</a><br /></td></tr>
<tr class="separator:af039194f94028cd7e61d5e52ebb57ce5"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a4a7a98ef7beb93faed6506bbb1145e6e"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a4a7a98ef7beb93faed6506bbb1145e6e">vec_bcdctuw</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:a4a7a98ef7beb93faed6506bbb1145e6e"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert groups of 8 BCD digits to binary unsigned words. <a href="vec__bcd__ppc_8h.html#a4a7a98ef7beb93faed6506bbb1145e6e">More...</a><br /></td></tr>
<tr class="separator:a4a7a98ef7beb93faed6506bbb1145e6e"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a62b3902055ebf8321ea36881773ac35b"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a62b3902055ebf8321ea36881773ac35b">vec_bcdctud</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:a62b3902055ebf8321ea36881773ac35b"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert groups of 16 BCD digits to binary unsigned doublewords. <a href="vec__bcd__ppc_8h.html#a62b3902055ebf8321ea36881773ac35b">More...</a><br /></td></tr>
<tr class="separator:a62b3902055ebf8321ea36881773ac35b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a29ae39efd0668fc35b5b6a33d2d46f9e"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a29ae39efd0668fc35b5b6a33d2d46f9e">vec_bcdctuq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:a29ae39efd0668fc35b5b6a33d2d46f9e"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert groups of 32 BCD digits to binary unsigned quadword. <a href="vec__bcd__ppc_8h.html#a29ae39efd0668fc35b5b6a33d2d46f9e">More...</a><br /></td></tr>
<tr class="separator:a29ae39efd0668fc35b5b6a33d2d46f9e"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a832d31ded0b33a2b46f6491bcb71ea51"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a832d31ded0b33a2b46f6491bcb71ea51">vec_bcdctz</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a832d31ded0b33a2b46f6491bcb71ea51"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert To Zoned. <a href="vec__bcd__ppc_8h.html#a832d31ded0b33a2b46f6491bcb71ea51">More...</a><br /></td></tr>
<tr class="separator:a832d31ded0b33a2b46f6491bcb71ea51"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a31e982fe4ae794073eb8e60a2525bb0e"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a31e982fe4ae794073eb8e60a2525bb0e">vec_bcddiv</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a31e982fe4ae794073eb8e60a2525bb0e"><td class="mdescLeft"> </td><td class="mdescRight">Divide a Vector Signed BCD 31 digit value by another BCD value. <a href="vec__bcd__ppc_8h.html#a31e982fe4ae794073eb8e60a2525bb0e">More...</a><br /></td></tr>
<tr class="separator:a31e982fe4ae794073eb8e60a2525bb0e"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:af423945a09a2ed7c4b53a7de336b42dc"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#af423945a09a2ed7c4b53a7de336b42dc">vec_bcddive</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:af423945a09a2ed7c4b53a7de336b42dc"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Divide Extended. <a href="vec__bcd__ppc_8h.html#af423945a09a2ed7c4b53a7de336b42dc">More...</a><br /></td></tr>
<tr class="separator:af423945a09a2ed7c4b53a7de336b42dc"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:abd65a5de9b45c2ecd452ee8a546d1418"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#abd65a5de9b45c2ecd452ee8a546d1418">vec_bcdmul</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:abd65a5de9b45c2ecd452ee8a546d1418"><td class="mdescLeft"> </td><td class="mdescRight">Multiply two Vector Signed BCD 31 digit values. <a href="vec__bcd__ppc_8h.html#abd65a5de9b45c2ecd452ee8a546d1418">More...</a><br /></td></tr>
<tr class="separator:abd65a5de9b45c2ecd452ee8a546d1418"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a54558167b9339ac9459d3f6cecb7ca14"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a54558167b9339ac9459d3f6cecb7ca14">vec_bcdmulh</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a54558167b9339ac9459d3f6cecb7ca14"><td class="mdescLeft"> </td><td class="mdescRight">Vector Signed BCD Multiply High. <a href="vec__bcd__ppc_8h.html#a54558167b9339ac9459d3f6cecb7ca14">More...</a><br /></td></tr>
<tr class="separator:a54558167b9339ac9459d3f6cecb7ca14"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a158f05b60fc824fc8459d6885f2ee9ad"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a158f05b60fc824fc8459d6885f2ee9ad">vec_bcds</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__common__ppc_8h.html#a748bbf6563e6ab1ddcb694c86e2aaef4">vi8_t</a> vrb)</td></tr>
<tr class="memdesc:a158f05b60fc824fc8459d6885f2ee9ad"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Shift. Shift a vector signed BCD value, left or right a variable amount of digits (nibbles). The sign nibble is preserved. <a href="vec__bcd__ppc_8h.html#a158f05b60fc824fc8459d6885f2ee9ad">More...</a><br /></td></tr>
<tr class="separator:a158f05b60fc824fc8459d6885f2ee9ad"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a08f861b495ad778c57b081f003ac3091"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a08f861b495ad778c57b081f003ac3091">vec_bcdsetsgn</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vrb)</td></tr>
<tr class="memdesc:a08f861b495ad778c57b081f003ac3091"><td class="mdescLeft"> </td><td class="mdescRight">Vector Set preferred BCD Sign. <a href="vec__bcd__ppc_8h.html#a08f861b495ad778c57b081f003ac3091">More...</a><br /></td></tr>
<tr class="separator:a08f861b495ad778c57b081f003ac3091"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a7c776218e50cd0f1d1878b3f99e111c8"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a7c776218e50cd0f1d1878b3f99e111c8">vec_bcdslqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned int _N)</td></tr>
<tr class="memdesc:a7c776218e50cd0f1d1878b3f99e111c8"><td class="mdescLeft"> </td><td class="mdescRight">Vector BCD Shift Right Signed Quadword. <a href="vec__bcd__ppc_8h.html#a7c776218e50cd0f1d1878b3f99e111c8">More...</a><br /></td></tr>
<tr class="separator:a7c776218e50cd0f1d1878b3f99e111c8"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a21c6f7871451ad14edc2f1a5a40e5ae5"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a21c6f7871451ad14edc2f1a5a40e5ae5">vec_bcdsluqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned int _N)</td></tr>
<tr class="memdesc:a21c6f7871451ad14edc2f1a5a40e5ae5"><td class="mdescLeft"> </td><td class="mdescRight">Vector BCD Shift Right unsigned Quadword. <a href="vec__bcd__ppc_8h.html#a21c6f7871451ad14edc2f1a5a40e5ae5">More...</a><br /></td></tr>
<tr class="separator:a21c6f7871451ad14edc2f1a5a40e5ae5"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ae23289e90f886499ca671f1eb8d1a686"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ae23289e90f886499ca671f1eb8d1a686">vec_bcdsr</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__common__ppc_8h.html#a748bbf6563e6ab1ddcb694c86e2aaef4">vi8_t</a> vrb)</td></tr>
<tr class="memdesc:ae23289e90f886499ca671f1eb8d1a686"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Shift and Round. Shift a vector signed BCD value, left or right a variable amount of digits (nibbles). The sign nibble is preserved. If byte element 7 of the shift count is negative (right shift), and the last digit shifted out is greater then or equal to 5, then increment the shifted magnitude by 1. <a href="vec__bcd__ppc_8h.html#ae23289e90f886499ca671f1eb8d1a686">More...</a><br /></td></tr>
<tr class="separator:ae23289e90f886499ca671f1eb8d1a686"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a76cd98e594ec0b867a4ffd4be62e77f6"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6">vec_bcdsrqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned int _N)</td></tr>
<tr class="memdesc:a76cd98e594ec0b867a4ffd4be62e77f6"><td class="mdescLeft"> </td><td class="mdescRight">Vector BCD Shift Right Signed Quadword Immediate. <a href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6">More...</a><br /></td></tr>
<tr class="separator:a76cd98e594ec0b867a4ffd4be62e77f6"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a3f600475b9eddc66b8cc35bf525e5153"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a3f600475b9eddc66b8cc35bf525e5153">vec_bcdsrrqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned int _N)</td></tr>
<tr class="memdesc:a3f600475b9eddc66b8cc35bf525e5153"><td class="mdescLeft"> </td><td class="mdescRight">Vector BCD Shift Right and Round Signed Quadword Immediate. <a href="vec__bcd__ppc_8h.html#a3f600475b9eddc66b8cc35bf525e5153">More...</a><br /></td></tr>
<tr class="separator:a3f600475b9eddc66b8cc35bf525e5153"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a07e013a0fb2fc89a1ad44164f538654d"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a07e013a0fb2fc89a1ad44164f538654d">vec_bcdsruqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned int _N)</td></tr>
<tr class="memdesc:a07e013a0fb2fc89a1ad44164f538654d"><td class="mdescLeft"> </td><td class="mdescRight">Vector BCD Shift Right Unsigned Quadword immediate. <a href="vec__bcd__ppc_8h.html#a07e013a0fb2fc89a1ad44164f538654d">More...</a><br /></td></tr>
<tr class="separator:a07e013a0fb2fc89a1ad44164f538654d"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aeb48adc4d015b874089fdf9fc4318509"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aeb48adc4d015b874089fdf9fc4318509">vec_bcdsub</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:aeb48adc4d015b874089fdf9fc4318509"><td class="mdescLeft"> </td><td class="mdescRight">Subtract two Vector Signed BCD 31 digit values. <a href="vec__bcd__ppc_8h.html#aeb48adc4d015b874089fdf9fc4318509">More...</a><br /></td></tr>
<tr class="separator:aeb48adc4d015b874089fdf9fc4318509"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:abd666963d18930e07be06aeb563eeb71"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#abd666963d18930e07be06aeb563eeb71">vec_bcdsubcsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:abd666963d18930e07be06aeb563eeb71"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Sudtract & write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#abd666963d18930e07be06aeb563eeb71">More...</a><br /></td></tr>
<tr class="separator:abd666963d18930e07be06aeb563eeb71"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a7eeb50993901b8bef76fa72cea668a15"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a7eeb50993901b8bef76fa72cea668a15">vec_bcdsubecsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c)</td></tr>
<tr class="memdesc:a7eeb50993901b8bef76fa72cea668a15"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Add Extended & write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#a7eeb50993901b8bef76fa72cea668a15">More...</a><br /></td></tr>
<tr class="separator:a7eeb50993901b8bef76fa72cea668a15"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a67047bcf3b7e676f9a5229ffa4cfda2b"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a67047bcf3b7e676f9a5229ffa4cfda2b">vec_bcdsubesqm</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c)</td></tr>
<tr class="memdesc:a67047bcf3b7e676f9a5229ffa4cfda2b"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Subtract Extended Signed Modulo Quadword. <a href="vec__bcd__ppc_8h.html#a67047bcf3b7e676f9a5229ffa4cfda2b">More...</a><br /></td></tr>
<tr class="separator:a67047bcf3b7e676f9a5229ffa4cfda2b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ac1893edfe60aa10d3983615b2cbb3554"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ac1893edfe60aa10d3983615b2cbb3554">vec_bcdtrunc</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> vrb)</td></tr>
<tr class="memdesc:ac1893edfe60aa10d3983615b2cbb3554"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Truncate. Truncate a vector signed BCD value vra to N-digits, where N is the unsigned integer value in bits 48-63 of vrb. The first 31-N digits are set to 0 and the result returned. <a href="vec__bcd__ppc_8h.html#ac1893edfe60aa10d3983615b2cbb3554">More...</a><br /></td></tr>
<tr class="separator:ac1893edfe60aa10d3983615b2cbb3554"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a8f135c421ca6bce377de71ff61be03b2"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a8f135c421ca6bce377de71ff61be03b2">vec_bcdtruncqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned short _N)</td></tr>
<tr class="memdesc:a8f135c421ca6bce377de71ff61be03b2"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Truncate Quadword Immediate. Truncate a vector signed BCD value vra to N-digits, where N is a unsigned short integer constant. The first 31-N digits are set to 0 and the result returned. <a href="vec__bcd__ppc_8h.html#a8f135c421ca6bce377de71ff61be03b2">More...</a><br /></td></tr>
<tr class="separator:a8f135c421ca6bce377de71ff61be03b2"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aedaeb6bf4ee28d7325e6cd87f209b8e7"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aedaeb6bf4ee28d7325e6cd87f209b8e7">vec_bcdus</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__common__ppc_8h.html#a748bbf6563e6ab1ddcb694c86e2aaef4">vi8_t</a> vrb)</td></tr>
<tr class="memdesc:aedaeb6bf4ee28d7325e6cd87f209b8e7"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Unsigned Shift. Shift a vector unsigned BCD value, left or right a variable amount of digits (nibbles). <a href="vec__bcd__ppc_8h.html#aedaeb6bf4ee28d7325e6cd87f209b8e7">More...</a><br /></td></tr>
<tr class="separator:aedaeb6bf4ee28d7325e6cd87f209b8e7"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:abd828916ab936edc1301b02f28f0accb"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#abd828916ab936edc1301b02f28f0accb">vec_bcdutrunc</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, <a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> vrb)</td></tr>
<tr class="memdesc:abd828916ab936edc1301b02f28f0accb"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Unsigned Truncate. Truncate a vector unsigned BCD value vra to N-digits, where N is the unsigned integer value in bits 48-63 of vrb. The first 32-N digits are set to 0 and the result returned. <a href="vec__bcd__ppc_8h.html#abd828916ab936edc1301b02f28f0accb">More...</a><br /></td></tr>
<tr class="separator:abd828916ab936edc1301b02f28f0accb"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a05a8e1bbc5ab13592b507c433f25b116"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a05a8e1bbc5ab13592b507c433f25b116">vec_bcdutruncqi</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra, const unsigned short _N)</td></tr>
<tr class="memdesc:a05a8e1bbc5ab13592b507c433f25b116"><td class="mdescLeft"> </td><td class="mdescRight">Decimal Unsigned Truncate Quadword Immediate. Truncate a vector unsigned BCD value vra to N-digits, where N is a unsigned short integer constant. The first 32-N digits are set to 0 and the result returned. <a href="vec__bcd__ppc_8h.html#a05a8e1bbc5ab13592b507c433f25b116">More...</a><br /></td></tr>
<tr class="separator:a05a8e1bbc5ab13592b507c433f25b116"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a486605817b8ca4850f7cf5584c751f45"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a486605817b8ca4850f7cf5584c751f45">vec_cbcdaddcsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> *cout, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a486605817b8ca4850f7cf5584c751f45"><td class="mdescLeft"> </td><td class="mdescRight">Combined Decimal Add & Write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#a486605817b8ca4850f7cf5584c751f45">More...</a><br /></td></tr>
<tr class="separator:a486605817b8ca4850f7cf5584c751f45"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:af9718d91a7e14c4a21e14a53f2f65041"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#af9718d91a7e14c4a21e14a53f2f65041">vec_cbcdaddecsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> *cout, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> cin)</td></tr>
<tr class="memdesc:af9718d91a7e14c4a21e14a53f2f65041"><td class="mdescLeft"> </td><td class="mdescRight">Combined Decimal Add Extended & write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#af9718d91a7e14c4a21e14a53f2f65041">More...</a><br /></td></tr>
<tr class="separator:af9718d91a7e14c4a21e14a53f2f65041"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a39a5438b38414210fceb891ff2261e7b"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a39a5438b38414210fceb891ff2261e7b">vec_cbcdmul</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> *p_high, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a39a5438b38414210fceb891ff2261e7b"><td class="mdescLeft"> </td><td class="mdescRight">Combined Vector Signed BCD Multiply High/Low. <a href="vec__bcd__ppc_8h.html#a39a5438b38414210fceb891ff2261e7b">More...</a><br /></td></tr>
<tr class="separator:a39a5438b38414210fceb891ff2261e7b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a67fa591c2015f76168c800957083f4b5"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a67fa591c2015f76168c800957083f4b5">vec_cbcdsubcsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> *cout, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</td></tr>
<tr class="memdesc:a67fa591c2015f76168c800957083f4b5"><td class="mdescLeft"> </td><td class="mdescRight">Combined Decimal Subtract & Write Carry Signed Quadword. <a href="vec__bcd__ppc_8h.html#a67fa591c2015f76168c800957083f4b5">More...</a><br /></td></tr>
<tr class="separator:a67fa591c2015f76168c800957083f4b5"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ae3ce6a47849278477fe4ea35cff5ca12"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#ae5cccc22e004bddbb80a51117c448675">vf64_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ae3ce6a47849278477fe4ea35cff5ca12">vec_pack_Decimal128</a> (_Decimal128 lval)</td></tr>
<tr class="memdesc:ae3ce6a47849278477fe4ea35cff5ca12"><td class="mdescLeft"> </td><td class="mdescRight">Pack a FPR pair (_Decimal128) to a doubleword vector (vector double). <a href="vec__bcd__ppc_8h.html#ae3ce6a47849278477fe4ea35cff5ca12">More...</a><br /></td></tr>
<tr class="separator:ae3ce6a47849278477fe4ea35cff5ca12"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a75ec76de573013acc571e371e7200187"><td class="memItemLeft" align="right" valign="top">static _Decimal128 </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a75ec76de573013acc571e371e7200187">vec_quantize0_Decimal128</a> (_Decimal128 val)</td></tr>
<tr class="memdesc:a75ec76de573013acc571e371e7200187"><td class="mdescLeft"> </td><td class="mdescRight">Quantize (truncate) a _Decimal128 value before convert to BCD. <a href="vec__bcd__ppc_8h.html#a75ec76de573013acc571e371e7200187">More...</a><br /></td></tr>
<tr class="separator:a75ec76de573013acc571e371e7200187"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a226e0f45eb9c65e388ee86b3b80540e7"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a226e0f45eb9c65e388ee86b3b80540e7">vec_rdxcf100b</a> (<a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</td></tr>
<tr class="memdesc:a226e0f45eb9c65e388ee86b3b80540e7"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert Binary Coded Decimal (BCD) digit pairs from radix 100 binary integer bytes. <a href="vec__bcd__ppc_8h.html#a226e0f45eb9c65e388ee86b3b80540e7">More...</a><br /></td></tr>
<tr class="separator:a226e0f45eb9c65e388ee86b3b80540e7"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a72f2f0f36250358a499d809c6779432b"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a72f2f0f36250358a499d809c6779432b">vec_rdxcf10kh</a> (<a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> vra)</td></tr>
<tr class="memdesc:a72f2f0f36250358a499d809c6779432b"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 10,000 Binary halfwords to pairs of radix 100 binary bytes. <a href="vec__bcd__ppc_8h.html#a72f2f0f36250358a499d809c6779432b">More...</a><br /></td></tr>
<tr class="separator:a72f2f0f36250358a499d809c6779432b"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aa356ff16b5b295a8a392ebba48b8a590"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aa356ff16b5b295a8a392ebba48b8a590">vec_rdxcf100mw</a> (<a class="el" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> vra)</td></tr>
<tr class="memdesc:aa356ff16b5b295a8a392ebba48b8a590"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 10**8 Binary words to pairs of radix 10,000 binary halfwords. <a href="vec__bcd__ppc_8h.html#aa356ff16b5b295a8a392ebba48b8a590">More...</a><br /></td></tr>
<tr class="separator:aa356ff16b5b295a8a392ebba48b8a590"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aa1f71d7219b9d4a975c74a84fd55bbda"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aa1f71d7219b9d4a975c74a84fd55bbda">vec_rdxcf10E16d</a> (<a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> vra)</td></tr>
<tr class="memdesc:aa1f71d7219b9d4a975c74a84fd55bbda"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 10**16 Binary doublewords to pairs of radix 10**8 binary words. <a href="vec__bcd__ppc_8h.html#aa1f71d7219b9d4a975c74a84fd55bbda">More...</a><br /></td></tr>
<tr class="separator:aa1f71d7219b9d4a975c74a84fd55bbda"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aab57aa00d4c2c17bc2eee01b50523a5a"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aab57aa00d4c2c17bc2eee01b50523a5a">vec_rdxcf10e32q</a> (<a class="el" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> vra)</td></tr>
<tr class="memdesc:aab57aa00d4c2c17bc2eee01b50523a5a"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 10**32 Binary quadword to pairs of radix 10**16 binary doublewords. <a href="vec__bcd__ppc_8h.html#aab57aa00d4c2c17bc2eee01b50523a5a">More...</a><br /></td></tr>
<tr class="separator:aab57aa00d4c2c17bc2eee01b50523a5a"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ae3a00fe6b7eefdb4e7dc93686068725e"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ae3a00fe6b7eefdb4e7dc93686068725e">vec_rdxcfzt100b</a> (<a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> zone00, <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> zone16)</td></tr>
<tr class="memdesc:ae3a00fe6b7eefdb4e7dc93686068725e"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert Zoned Decimal digit pairs to to radix 100 binary integer bytes.. <a href="vec__bcd__ppc_8h.html#ae3a00fe6b7eefdb4e7dc93686068725e">More...</a><br /></td></tr>
<tr class="separator:ae3a00fe6b7eefdb4e7dc93686068725e"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a7e490fa302fb2275fe07368c6276cf9c"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a7e490fa302fb2275fe07368c6276cf9c">vec_rdxct100b</a> (<a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</td></tr>
<tr class="memdesc:a7e490fa302fb2275fe07368c6276cf9c"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert Binary Coded Decimal (BCD) digit pairs to radix 100 binary integer bytes. <a href="vec__bcd__ppc_8h.html#a7e490fa302fb2275fe07368c6276cf9c">More...</a><br /></td></tr>
<tr class="separator:a7e490fa302fb2275fe07368c6276cf9c"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a58484a98545f49712158d7943047b875"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a58484a98545f49712158d7943047b875">vec_rdxct10kh</a> (<a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</td></tr>
<tr class="memdesc:a58484a98545f49712158d7943047b875"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 100 digit pairs to radix 10,000 binary integer halfwords. <a href="vec__bcd__ppc_8h.html#a58484a98545f49712158d7943047b875">More...</a><br /></td></tr>
<tr class="separator:a58484a98545f49712158d7943047b875"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a2e857a02bebc27fb0bb18eea5ceddf0d"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a2e857a02bebc27fb0bb18eea5ceddf0d">vec_rdxct100mw</a> (<a class="el" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> vra)</td></tr>
<tr class="memdesc:a2e857a02bebc27fb0bb18eea5ceddf0d"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 10,000 digit halfword pairs to radix 100,000,000 binary integer words. <a href="vec__bcd__ppc_8h.html#a2e857a02bebc27fb0bb18eea5ceddf0d">More...</a><br /></td></tr>
<tr class="separator:a2e857a02bebc27fb0bb18eea5ceddf0d"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a3e5105096cab9b9a2ae703262e403352"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a3e5105096cab9b9a2ae703262e403352">vec_rdxct10E16d</a> (<a class="el" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> vra)</td></tr>
<tr class="memdesc:a3e5105096cab9b9a2ae703262e403352"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 100,000,000 digit word pairs to radix 10E16 binary integer doublewords. <a href="vec__bcd__ppc_8h.html#a3e5105096cab9b9a2ae703262e403352">More...</a><br /></td></tr>
<tr class="separator:a3e5105096cab9b9a2ae703262e403352"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:aa3cdbd0a0ce3687c82bdcfad7b2281f9"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#aa3cdbd0a0ce3687c82bdcfad7b2281f9">vec_rdxct10e32q</a> (<a class="el" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> vra)</td></tr>
<tr class="memdesc:aa3cdbd0a0ce3687c82bdcfad7b2281f9"><td class="mdescLeft"> </td><td class="mdescRight">Vector Decimal Convert radix 10E16 digit pairs to radix 10E32 __int128 quadwords. <a href="vec__bcd__ppc_8h.html#aa3cdbd0a0ce3687c82bdcfad7b2281f9">More...</a><br /></td></tr>
<tr class="separator:aa3cdbd0a0ce3687c82bdcfad7b2281f9"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a3e8374dc8f6699a5559502799d0ae628"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a16cdf519bbbf190c311bd27d3e254208">vb128_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a3e8374dc8f6699a5559502799d0ae628">vec_setbool_bcdinv</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:a3e8374dc8f6699a5559502799d0ae628"><td class="mdescLeft"> </td><td class="mdescRight">Vector Set Bool from Signed BCD Quadword if invalid. <a href="vec__bcd__ppc_8h.html#a3e8374dc8f6699a5559502799d0ae628">More...</a><br /></td></tr>
<tr class="separator:a3e8374dc8f6699a5559502799d0ae628"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:ae45a804885d0e9d78fd87f1995da018c"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#a16cdf519bbbf190c311bd27d3e254208">vb128_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#ae45a804885d0e9d78fd87f1995da018c">vec_setbool_bcdsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:ae45a804885d0e9d78fd87f1995da018c"><td class="mdescLeft"> </td><td class="mdescRight">Vector Set Bool from Signed BCD Quadword. <a href="vec__bcd__ppc_8h.html#ae45a804885d0e9d78fd87f1995da018c">More...</a><br /></td></tr>
<tr class="separator:ae45a804885d0e9d78fd87f1995da018c"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a1d314ab5381ff7997a23f88df2f663d9"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a1d314ab5381ff7997a23f88df2f663d9">vec_signbit_bcdsq</a> (<a class="el" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</td></tr>
<tr class="memdesc:a1d314ab5381ff7997a23f88df2f663d9"><td class="mdescLeft"> </td><td class="mdescRight">Vector Sign bit from Signed BCD Quadword. <a href="vec__bcd__ppc_8h.html#a1d314ab5381ff7997a23f88df2f663d9">More...</a><br /></td></tr>
<tr class="separator:a1d314ab5381ff7997a23f88df2f663d9"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a9c19a6744e6f0b5fde60a0f36289e468"><td class="memItemLeft" align="right" valign="top">static _Decimal128 </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a9c19a6744e6f0b5fde60a0f36289e468">vec_unpack_Decimal128</a> (<a class="el" href="vec__common__ppc_8h.html#ae5cccc22e004bddbb80a51117c448675">vf64_t</a> lval)</td></tr>
<tr class="memdesc:a9c19a6744e6f0b5fde60a0f36289e468"><td class="mdescLeft"> </td><td class="mdescRight">Unpack a doubleword vector (vector double) into a FPR pair. (_Decimal128). <a href="vec__bcd__ppc_8h.html#a9c19a6744e6f0b5fde60a0f36289e468">More...</a><br /></td></tr>
<tr class="separator:a9c19a6744e6f0b5fde60a0f36289e468"><td class="memSeparator" colspan="2"> </td></tr>
<tr class="memitem:a72744e7e29d3226952ae5817b76bf6dd"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="vec__bcd__ppc_8h.html#a72744e7e29d3226952ae5817b76bf6dd">vec_zndctuq</a> (<a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> zone00, <a class="el" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> zone16)</td></tr>
<tr class="memdesc:a72744e7e29d3226952ae5817b76bf6dd"><td class="mdescLeft"> </td><td class="mdescRight">Vector Zoned Decimal Convert 32 digits to binary unsigned quadword. <a href="vec__bcd__ppc_8h.html#a72744e7e29d3226952ae5817b76bf6dd">More...</a><br /></td></tr>
<tr class="separator:a72744e7e29d3226952ae5817b76bf6dd"><td class="memSeparator" colspan="2"> </td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Header package containing a collection of Binary Coded Decimal (<b>BCD</b>) computation and Zoned Character conversion operations on vector registers. </p>
<p>Many of these operations are implemented in a single VMX or DFP instruction on newer (POWER8/POWER9) processors. This header serves to fill in functional gaps for older (POWER7, POWER8) processors (using existing VMX, VSX, and DFP instructions) and provides in-line assembler implementations for older compilers that do not provide the built-ins.</p>
<p>Starting with POWER6 introduced a Decimal Floating-point (<em>DFP</em>) Facility implementing the <a href="https://en.wikipedia.org/wiki/IEEE_754-2008_revision">IEEE 754-2008 revision</a> standard. This is implemented in hardware as an independent Decimal Floating-point Unit (<em>DFU</em>). This is supported with ISO C/C++ language bindings and runtime libraries.</p>
<p>The DFP Facility supports a different data format <a href="https://en.wikipedia.org/wiki/Densely_packed_decimal">Densely packed decimal</a> (<em>DPD</em> and a more extensive set of operations then BCD or Zoned. So DFP and the comprehensive C language and runtime library support makes it a better target for new business oriented applications. As the DFP Facility supports conversions between DPD and BCD, existing DFP operations can be used to emulate BCD operations on older processors and fill in operational gaps in the vector BCD instruction set.</p>
<p>As DFP is supported directly in the hardware and has extensive language and runtime support, there is little that PVECLIB can contribute to general decimal radix computation. However the vector unit and recent BCD and Zoned extensions can still be useful in areas include large order multiple precision computation and conversions between binary and decimal radix. Both are required to convert large decimal numeric or floating-point values with extreme exponents for input or print.</p>
<p>So what operations are needed, what does the PowerISA provide, and what does the ABI and/or compiler provide. Some useful operations include:</p><ul>
<li>conversions between BCD and __int128<ul>
<li>As intermediate step between external decimal/_Decimal128 and _Float128</li>
</ul>
</li>
<li>Conversions between BCD and Zoned (character)</li>
<li>Conversions between BCD and DFP</li>
<li>BCD add/subtract with carry/extend</li>
<li>BCD compare equal, greater than, less than</li>
<li>BCD copy sign and set bool from sign</li>
<li>BCD digit shift left/right</li>
<li>BCD multiply/divide</li>
</ul>
<p>The original VMX (AKA Altivec) only defined a few instructions that operated on the 128-bit vector as a whole. This included the vector shifts by bit and octet, and generalized vector permute, general binary integer add, subtract and multiply for byte/halfword/word. But no BCD or decimal character operations.</p>
<p>POWER6 introduced the Decimal Floating-point Facility. DFP provides a robust set of operations with 7 (_Decimal32), 16 (_Decimal64), and 34 (_Decimal128) digit precision. Arithmetic operations include add, subtract, multiply, divide, and compare. Special operations insert/extract exponent, quantize, and digit shift. Conversions to and from signed (31-digits) and unsigned (32-digit) BCD. And conversions to and from binary signed long (64-bit) integer. DFP operations use the existing floating-point registers (FPRs). The 128-bit DFP (quadword) instructions operate on even/odd 64-bit Floating-point register pairs (FPRp).</p>
<p>POWER6 also implemented the Vector Facility (VMX) instructions. No additional vectors operations where added and the Vector Registers (VRs) where separate from the GRPs and FPRs. The only transfer data path between register sets is via storage. So while the DFP Facility could be used for BCD operations and conversions, there was little synergy with the vector unit, in POWER6.</p>
<p>POWER7 introduced the VSX facility providing 64x128-bit Vector Scalar Registers (VSRs) that overlaid both the FPRs (VSRs 0-31) and VRs (VSRs 32-63). It also added useful doubleword permute immediate (xxpermdi) and logical/select operations with access to all 64 VSRs. This greatly simplifies data transfers between VRs and FPRs (FPRps) (see <a class="el" href="vec__bcd__ppc_8h.html#ae3ce6a47849278477fe4ea35cff5ca12" title="Pack a FPR pair (_Decimal128) to a doubleword vector (vector double).">vec_pack_Decimal128()</a>, <a class="el" href="vec__bcd__ppc_8h.html#a9c19a6744e6f0b5fde60a0f36289e468" title="Unpack a doubleword vector (vector double) into a FPR pair. (_Decimal128).">vec_unpack_Decimal128()</a>). This makes it more practical to transfer vector contents to the DFP Facility for processing (see <a class="el" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b" title="Convert a Vector Signed BCD value to __Decimal128.">vec_BCD2DFP()</a> and <a class="el" href="vec__bcd__ppc_8h.html#ad8123fa00f666a0d439a049eb4f7c7eb" title="Convert a __Decimal128 value to Vector BCD.">vec_DFP2BCD()</a>.</p>
<dl class="section note"><dt>Note</dt><dd>All the BCD instructions and the quadword binary add/subtract are defined as vector class and can only access vector registers (VSRs 32-63). The DFP instructions can only access FPRs (VSRs 0-31). So only a VSX instruction (like xxpermdi) can perform the transfer without going through storage.</dd></dl>
<p>POWER8 added vector add/subtract modulo/carry/extend unsigned quadword for binary integer (vector [unsigned] __int128). This combined with the wider (word) multiply greatly enhances multiple precision operations on large (> 128-bit) binary numbers. POWER8 also added signed BCD add/subtract instructions with up to 31-digits. While the PowerISA did not provide carry/extend forms of bcdadd/bcdsub, it does set a condition code with bits for GT/LT/EQ/OVF. This allows for implementations of BCD compare and the overflow (OVF) bit supports carry/extend operations. Also the lack of BCD multiply/divide in the vector unit is not a problem because we can leverage DFP (see <a class="el" href="vec__bcd__ppc_8h.html#abd65a5de9b45c2ecd452ee8a546d1418" title="Multiply two Vector Signed BCD 31 digit values.">vec_bcdmul()</a>, <a class="el" href="vec__bcd__ppc_8h.html#a31e982fe4ae794073eb8e60a2525bb0e" title="Divide a Vector Signed BCD 31 digit value by another BCD value.">vec_bcddiv()</a>).</p>
<p>POWER9 (PowerISA 3.0B) adds BCD copy sign, set sign, shift, round, and truncate instructions. There are also unsigned (32-digit) forms of the shift and truncate instructions. And instructions to convert between signed BCD and quadword (__int128) and signed BCD and Zoned. POWER9 also added quadword binary multiply 10 with carry extend forms than can also help with decimal to binary conversion.</p>
<p>The <a href="https://openpowerfoundation.org/?resource_lib=64-bit-elf-v2-abi-specification-power-architecture">OpenPOWER ABI</a> does have an <em>Appendix B. Binary-Coded Decimal Built-In Functions</em> and proposes that compilers provide a <b>bcd.h</b> header file. At this time no compiler provides this header. GCC does provides compiler built-ins to generate the bcdadd/bcdsub instructions and access the associated condition codes in <em>if</em> statements. GCC also provides built-ins to generate the DFP instruction encode/decode to and from BCD.</p>
<dl class="section note"><dt>Note</dt><dd>The compiler disables built-ins if the <b>mcpu</b> target does not enable the specific instruction. For example if you compile with <b>-mcpu=power7</b>, __builtin_bcdadd and __builtin_bcdsub are not supported. But <a class="el" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939" title="Decimal Add Signed Modulo Quadword.">vec_bcdadd()</a> is always defined in this header, will generate the minimum code, appropriate for the target, and produce correct results.</dd></dl>
<p>This header covers operations that are either:</p>
<ul>
<li>Operations implemented in hardware instructions for later processors and useful to programmers, on slightly older processors, even if the equivalent function requires more instructions. Examples include quadword BCD add and subtract.</li>
<li>Defined in the OpenPOWER ABI but <em>not</em> yet defined in <altivec.n> or <bcd.h> provided by available compilers in common use. Examples include bcd_add, bcd_cmpg and bcd_mul.</li>
<li>Commonly used operations, not covered by the ABI or <altivec.h>, and require multiple instructions or are not obvious. Examples include <a class="el" href="vec__bcd__ppc_8h.html#ae3ce6a47849278477fe4ea35cff5ca12" title="Pack a FPR pair (_Decimal128) to a doubleword vector (vector double).">vec_pack_Decimal128()</a> and <a class="el" href="vec__bcd__ppc_8h.html#a9c19a6744e6f0b5fde60a0f36289e468" title="Unpack a doubleword vector (vector double) into a FPR pair. (_Decimal128).">vec_unpack_Decimal128()</a>.</li>
</ul>
<p>See <a class="el" href="index.html#mainpage_sub_1_3">Returning extended quadword results.</a> for more background on extended quadword computation.</p>
<h1><a class="anchor" id="bcd128_endian_issues_0_0"></a>
Endian problems with quadword implementations</h1>
<p>Technically, operations on quadword elements should not require any endian specific transformation. There is only one element so there can be no confusion about element numbering or order. However some of the more complex quadword operations are constructed from operations on smaller elements. And those operations as provided by <altivec.h> are required by the OpenPOWER ABI to be endian sensitive. See <a class="el" href="vec__int64__ppc_8h.html#i64_endian_issues_0_0">Endian problems with doubleword operations</a> for a more detailed discussion.</p>
<p>In any case, the arithmetic (high to low) order of digit nibbles in BCD or characters in Zoned are defined in the PowerISA. In the vector register, high order digits are on the left while low order digits and the sign are on the right. (See <a class="el" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939" title="Decimal Add Signed Modulo Quadword.">vec_bcdadd()</a> and <a class="el" href="vec__bcd__ppc_8h.html#aeb48adc4d015b874089fdf9fc4318509" title="Subtract two Vector Signed BCD 31 digit values.">vec_bcdsub()</a>). So pveclib implementations will need to either:</p><ul>
<li>Nullify little endian transforms of <altivec.h> operations. The <altivec.h> built-ins vec_mule(), vec_mulo(), and vec_pack() are endian sensitive and often require nullification that restores the original operation.</li>
<li>Use new operations that are specifically defined to be stable across BE/LE implementations. The pveclib operations; <a class="el" href="vec__int128__ppc_8h.html#a84e6361054b52ac4564bcef25b718151" title="Vector Multiply Even Unsigned Doublewords.">vec_vmuleud()</a> and <a class="el" href="vec__char__ppc_8h.html#a425151e5a82ee9e204ffd81b1ec7a92c" title="Vector Multiply Unsigned Byte Modulo.">vec_mulubm()</a> are defined to be endian stable.</li>
</ul>
<h1><a class="anchor" id="bcd128_details_0_0"></a>
Some details of BCD computation</h1>
<p><a href="https://en.wikipedia.org/wiki/Binary-coded_decimal">Binary-coded decimal</a> (Also called <em>packed decimal</em>) and the related <em>Zoned Decimal</em> are common representations of signed decimal radix (base 10) numbers. BCD is more compact and usually faster then zoned. Zoned format is more closely aligned with human readable and printable character formats. In both formats the sign indicator is associated (in the same character or byte) with the low order digit.</p>
<p>BCD and Zoned formats and operations were implemented for some of the earliest computers. Then circuitry was costly and arithmetic was often implemented as a digit (or bit) serial operation. Modern computers have more circuitry with wider data paths and more complex arithmetic/logic units. The current trend is for each processor core implementation to include multiple computational units that can operate in parallel.</p>
<p>For POWER server class processors separate and multiple Fixed-Point Units (FXU), (binary) Floating-point Units (FPU), and Vector Processing Units (VPU) are the norm. POWER6 introduced a Decimal Floating-point (<em>DFP</em>) Facility implementing the <a href="https://en.wikipedia.org/wiki/IEEE_754-2008_revision">IEEE 754-2008 revision</a> standard. This is implemented in hardware as an independent Decimal Floating-point Unit (<em>DFU</em>). This is supported with ISO C/C++ language bindings and runtime libraries.</p>
<p>The DFU supports a different data format <a href="https://en.wikipedia.org/wiki/Densely_packed_decimal">Densely packed decimal</a> (<em>DPD</em> and a more extensive set of operations then BCD or Zoned. So hardware DFP and the comprehensive C language and runtime library support makes it a better target for new business oriented applications. As DFP is supported directly in the hardware and has extensive language and runtime support, there is little that PVECLIB can contribute to general decimal radix computation.</p>
<dl class="section note"><dt>Note</dt><dd>BCD and DFP support requires at least PowerISA 2.05 (POWER6) or later server level processor support.</dd></dl>
<p>However the vector unit and recent BCD and Zoned extensions can still be useful in areas including large order multiple precision computation and conversions between binary and decimal radix. Both are required to convert large decimal numeric or floating-point values with extreme exponents for input or print. And conventions between _Float128 and _Decimal128 types is even more challenging. Basically both POSIX and IEEE 754-2008 require that it possible to convert floating-point values to an external character decimal representation, with the specified rounding, and back recovering the original value. This always requires more precision for the conversion then is available in the given format and size.</p>
<h2><a class="anchor" id="bcd128_extended_0_1"></a>
Preferred sign, zone, and zero.</h2>
<p>BCD and Zoned Decimal have a long history with multiple computer manufacturers, and this is reflected as multiple encodings of the same basic concept. This is in turn reflected in the PowerISA as Preferred Sign <b>PS</b> immediate operand on BCD instructions.</p>
<p>This header implementation assumes that users of PVECLIB are not interested in this detail and just want access to BCD computation with consistent results. So PVECLIB does not expose preferred sign at the API and provides reasonable defaults in the implementation.</p>
<p>PVECLIB is targeted at the Linux ecosystem with ASCII character encoding, so the implementation defaults for:</p><ul>
<li>preferred zone nibble 0x3. ASCII encodes decimal characters as 0x30 - 0x39.</li>
<li>preferred sign code nibbles 0xC and 0xD. Historically accounting refers to <em><b>C</b>redit</em> as positive and <em><b>D</b>edit</em> for negative.</li>
</ul>
<p>The PowerISA implementation is permissive of sign encoding of input values and will accept four (0xA, 0xC, 0xE, 0xF) encodings of positive and two (0xB, 0xD) for negative. But the sign code of the result is always set to the preferred sign.</p>
<p>The BCD encoding allows for signed zeros (-0, +0) but the PowerISA implementation prefers the positive encoding for zero results. Again the implementation is permissive of both encodings for input operands. Usually this is not an issue but can be when dealing with conversions from other formats (DFP also allows signed 0.0) and implementations of BCD operations for older (POWER7/8) processors.</p>
<p>This is most likely to effect user code in comparisons of BCD values for 0. One might expect the following vector binary word compare all </p><div class="fragment"><div class="line"><span class="keywordflow">if</span> (vec_all_eq((<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) t, (<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>))</div>
</div><!-- fragment --><p> to give the same result as </p><div class="fragment"><div class="line"><span class="keywordflow">if</span> (<a class="code" href="vec__bcd__ppc_8h.html#a1dcd1cfe33aeaa26b23bdd6f9f535361">vec_bcdcmpeq</a> (t, <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>))</div>
</div><!-- fragment --><p> The vector binary compare is likely to have lower latency (on POWER7/8), but will miss compare on <em>-0</em>. The BCD compare operation (i.e. vec_bcdcmpeq ()) is recommended, unless the programs knows the details for the source operands generation, and have good (performance and latency) reasons to to use the alternative compare. Pveclib strives to provide correct preferred zeros results in its implementation of BCD operations.</p>
<h2><a class="anchor" id="bcd128_extended_0_2"></a>
Extended Precision computation with BCD</h2>
<p>Extended precision requires carry and extend forms of bcdadd/sub. Also BCD multiply with multiply high and and double quadword (62-digit) forms. The vector unit does not support BCD multiply so pveclib leverages the DFP Facility to implement these operations. Finally algorithms and extended precision conversions require BCD divide and divide extended. Again leveraging the DPU to implement these operations.</p>
<h3><a class="anchor" id="bcd128_extended_0_2_0"></a>
Vector Add/Subtrace with Carry/Extend example</h3>
<p>The PowerISA does not provide the extend and write-carry forms of the bcdadd/sub instructions. But bcdadd/sub instructions do post status to CR field 6 which includes:</p><ul>
<li>Result is less than zero (CR.bit[56])</li>
<li>Result is greater than zero (CR.bit[57])</li>
<li>Result is equal to zero (CR.bit[58])</li>
<li>Result overflowed (CR.bit[59])</li>
</ul>
<p>which provides a basis for BCD comparison and the overflow may be used for carry/extend logic. The GCC compiler provides built-ins to generate the bcdadd/sub and test the resulting CR bits in if statements.</p>
<p>Unfortunately, the Overflow flag generated by bcdadd/bcdsub is not a true carry/borrow. If the operands have the same sign for bcdadd (different sign for bcdsub) and there is a carry out of the high order digit, then:</p><ul>
<li>The sum is truncated to the low order 31 digits</li>
<li>The sum's sign matches the operands signs</li>
<li>The overflow flag (CR.bit[59]) is set.</li>
</ul>
<dl class="section note"><dt>Note</dt><dd>overflow is only set in conjunction with greater than zero (positive) or less than zero (negative) results. This implies that BCD carries are tri-state; +1, 0, or -1.</dd></dl>
<p>This can be used to simulate a <b>Add and Write-Carry</b> operation. However if the operands have different signs the bcdadd (same sign for bcdsub) the operation does the following:</p><ul>
<li>The smaller magnitude is subtracted from the larger magnitude.</li>
<li>The sign matches the sign of the larger magnitude.</li>
<li>The ox_flag (CR.bit[59]) is NOT set.</li>
</ul>
<p>For a simple BCD add this is the desired result (overflow is avoided and the borrow is recorded in the sign). But for multiple precision BCD operation, this will delay propagation of borrows to the higher order digits and the result is a mixture of signs across elements of the larger multiple precision value. This would have to be corrected at some later stage. For example the sum of 32 digits: </p><div class="fragment"><div class="line"> 21000000000000000000000000000008</div>
<div class="line">+ 19000000000000000000000000000008</div>
<div class="line">= 40000000000000000000000000000016</div>
</div><!-- fragment --><p> This exceeds the 31-digit capacity of Vector signed BCD so we are forced to represent each number as two or more BCD values. For example: </p><div class="fragment"><div class="line"> 0000000000000000000000000000002c 1000000000000000000000000000008c</div>
<div class="line">+ 0000000000000000000000000000001c 9000000000000000000000000000008c</div>
<div class="line">= 0000000000000000000000000000004c 0000000000000000000000000000016c</div>
</div><!-- fragment --><p> The sum of the low order operands will overflow, so we need to detect this overflow and generate a carry that we can apply to sum of the high order operands. For example the following code using the GCC's __builtin_bcdadd_ov. </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a76d5034289bea5c7d9159db1d443f6b7">vec_bcdaddcsq</a> (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c, sum_ab;</div>
<div class="line"> c = <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>;</div>
<div class="line"> <span class="comment">// compute the sum of (a + b)</span></div>
<div class="line"> sum_ab = (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) __builtin_bcdadd ((<a class="code" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a>) a, (<a class="code" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a>) b, 0);;</div>
<div class="line"> <span class="comment">// Detect the overflow, which should be rare</span></div>
<div class="line"> <span class="keywordflow">if</span> (__builtin_expect (__builtin_bcdadd_ov ((<a class="code" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a>) a, (<a class="code" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a>) b, 0), 0))</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// use copysign to generate a carry based on the sign of the sum_ab</span></div>
<div class="line"> c = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>, sum_ab);</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">return</span> (c);</div>
<div class="line">}</div>
</div><!-- fragment --> <div class="fragment"><div class="line"> 0000000000000000000000000000002c 1000000000000000000000000000008c</div>
<div class="line"> 0000000000000000000000000000001c + 9000000000000000000000000000008c</div>
<div class="line"> =</div>
<div class="line"> 1c 0000000000000000000000000000016c</div>
<div class="line">+ 0000000000000000000000000000002c</div>
<div class="line">+ 0000000000000000000000000000001c</div>
<div class="line"> </div>
<div class="line">= 0000000000000000000000000000004c</div>
</div><!-- fragment --><p> The higher operands requires a 3-way (a+b+c) sum to propagate the carry. </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">vec_bcdaddesqm</a> (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b, <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> t;</div>
<div class="line"> t = <a class="code" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">vec_bcdadd</a> (<a class="code" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">vec_bcdadd</a> (a, b), c);</div>
<div class="line"> <span class="keywordflow">return</span> (t);</div>
<div class="line">}</div>
</div><!-- fragment --><p> where vec_bcdadd is a pveclib wrapper around __builtin_bcdadd to simplify the code. The simplified multiple precision BCD use case looks like this: </p><div class="fragment"><div class="line"><span class="comment">// r_h|r_l = a_h|a_l + b_h|b_l</span></div>
<div class="line">r_l = <a class="code" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">vec_bcdadd</a> (a_l, b_l);</div>
<div class="line">c_l = <a class="code" href="vec__bcd__ppc_8h.html#a76d5034289bea5c7d9159db1d443f6b7">vec_bcdaddcsq</a> (a_l, b_l);</div>
<div class="line">r_h = <a class="code" href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">vec_bcdaddesqm</a> (a_h, b_h, c_l)</div>
</div><!-- fragment --><p>But we should look at some more examples before we assume we have a complete solution. For example a subtract that requires a borrow: </p><div class="fragment"><div class="line"> 21000000000000000000000000000008</div>
<div class="line">- 19000000000000000000000000000008</div>
<div class="line">= 02000000000000000000000000000000</div>
</div><!-- fragment --><p> The multiple precision BCD would look like this: </p><div class="fragment"><div class="line"> 0000000000000000000000000000002c 1000000000000000000000000000008c</div>
<div class="line">+ 0000000000000000000000000000001d 9000000000000000000000000000008d</div>
</div><!-- fragment --><p> But with the example code above we expected result: </p><div class="fragment"><div class="line">= 0000000000000000000000000000000c 2000000000000000000000000000000c</div>
</div><!-- fragment --><p> instead we see: </p><div class="fragment"><div class="line">= 0000000000000000000000000000001c 8000000000000000000000000000000d</div>
</div><!-- fragment --><p>The BCD overflow flag only captures carry/borrow when the bcdadd operands have the same sign (or different signs for bcdsub). In this case it looks like (1 - 9 = -8) which does not overflow. </p><div class="fragment"><div class="line"> 0000000000000000000000000000002c 1000000000000000000000000000008c</div>
<div class="line"> 0000000000000000000000000000001d + 9000000000000000000000000000008d</div>
<div class="line"> =</div>
<div class="line"> 0c 8000000000000000000000000000000d</div>
<div class="line">+ 0000000000000000000000000000002c</div>
<div class="line">+ 0000000000000000000000000000001d</div>
<div class="line"> </div>
<div class="line">= 0000000000000000000000000000001c</div>
</div><!-- fragment --><p> We need a way to detect the borrow and fix up the sum to look like (11 - 9 = 2) and generate a carry digit (-1) to propagate the borrow to the higher order digits.</p>
<p>The secondary borrow is detected by comparing the sign of the result to the sign of the first operand. Something like this: </p><div class="fragment"><div class="line">t = <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>;</div>
<div class="line">sign_ab = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (sum_ab, a);</div>
<div class="line"><span class="keywordflow">if</span> (!vec_all_eq(sign_ab, sum_ab))</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Borrow fix-up code</span></div>
<div class="line"> }</div>
</div><!-- fragment --><p> For multiple precision operations it would be better to retain the sign from the first operand and generate a borrow digit (value of '1' with the sign of the uncorrected result).</p>
<p>This requires re-computing the sum/difference, while applying the effect of borrow, and replacing the carry (currently 0) with a signed borrow digit. The corrected sum is the 10's complement (9's complement +1) of the initial sum (like (10 - 8 = 2) or (9 - 8 + 1 = 2). As we obviously don't know how to represent signed BCD with more then 31-digits (10**32 is 32-digits), the 9's complement + 1 is a better plan. We know that initial sum has a different sign from the original first operand. So adding 10**31 with the sign of the first operand to the initial sum applies the borrow operation.</p>
<div class="fragment"><div class="line">c = <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>;</div>
<div class="line">sign_ab = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (sum_ab, a);</div>
<div class="line"><span class="keywordflow">if</span> (!vec_all_eq(sign_ab, t) && !vec_all_eq(<a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>, t))</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// 10**31 with the original sign of the first operand</span></div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> nines = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#ac2eb804164fac106d89ef8fb9cf6a877">_BCD_CONST_PLUS_NINES</a>, a);</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c10s = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>, a);</div>
<div class="line"> <span class="comment">// Generate the Borrow digit from the initial sum</span></div>
<div class="line"> c = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>, sum_ab);</div>
<div class="line"> <span class="comment">// Invert the sum using the 10s complement</span></div>
<div class="line"> sum_ab = <a class="code" href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">vec_bcdaddesqm</a> (nines, sum_ab, c10s);</div>
<div class="line"> }</div>
</div><!-- fragment --> <div class="fragment"><div class="line"> 0000000000000000000000000000002c 1000000000000000000000000000008c</div>
<div class="line"> 0000000000000000000000000000001d + 9000000000000000000000000000008d</div>
<div class="line"> = ?</div>
<div class="line"> 8000000000000000000000000000000d</div>
<div class="line"> + 9999999999999999999999999999999c</div>
<div class="line"> + 0000000000000000000000000000001c</div>
<div class="line"> 1d 2000000000000000000000000000000c</div>
<div class="line">+ 0000000000000000000000000000002c</div>
<div class="line">+ 0000000000000000000000000000001d</div>
<div class="line"> </div>
<div class="line">= 0000000000000000000000000000000c</div>
</div><!-- fragment --><p>This does not fit well into the separate <em>add modulo</em> and <em>add and write-carry</em> operations commonly used for fixed binary arithmetic. Instead it requires a combined operation returning both the generated borrow and a sum/difference result with a corrected sign code. The combined add with carry looks like this: </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a486605817b8ca4850f7cf5584c751f45">vec_cbcdaddcsq</a> (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> *cout, <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> t, c;</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> sum_ab, sign_a, sign_ab;</div>
<div class="line"> </div>
<div class="line"> sum_ab = <a class="code" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">vec_bcdadd</a> (a, b);</div>
<div class="line"> <span class="keywordflow">if</span> (__builtin_expect (__builtin_bcdadd_ov ((<a class="code" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a>) a, (<a class="code" href="vec__common__ppc_8h.html#a3b2bbf9f23490ccca3bdc08bc1dc7831">vi128_t</a>) b, 0), 0))</div>
<div class="line"> {</div>
<div class="line"> c = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>, sum_ab);</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">else</span> <span class="comment">// (a + b) did not overflow, but did it borrow?</span></div>
<div class="line"> {</div>
<div class="line"> c = <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>;</div>
<div class="line"> sign_ab = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (sum_ab, a);</div>
<div class="line"> <span class="keywordflow">if</span> (!vec_all_eq(sign_ab, sum_ab) && !vec_all_eq(<a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>, t))</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// 10**31 with the original sign of the first operand</span></div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> nines = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#ac2eb804164fac106d89ef8fb9cf6a877">_BCD_CONST_PLUS_NINES</a>, a);</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> c10s = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>, a);</div>
<div class="line"> <span class="comment">// Generate the Borrow digit from the initial sum</span></div>
<div class="line"> c = <a class="code" href="vec__bcd__ppc_8h.html#abeda7137bef8dfc50d539c86f40d8070">vec_bcdcpsgn</a> (<a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>, sum_ab);</div>
<div class="line"> <span class="comment">// Invert the sum using the 10s complement</span></div>
<div class="line"> sum_ab = <a class="code" href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">vec_bcdaddesqm</a> (nines, sum_ab, c10s);</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> *cout = c;</div>
<div class="line"> <span class="keywordflow">return</span> (sum_ab);</div>
<div class="line">}</div>
</div><!-- fragment --><p> and the usage example looks like this: </p><div class="fragment"><div class="line"><span class="comment">// r_h|r_l = a_h|a_l + b_h|b_l</span></div>
<div class="line">r_l = <a class="code" href="vec__bcd__ppc_8h.html#a486605817b8ca4850f7cf5584c751f45">vec_cbcdaddcsq</a> (&c_l, a_l, b_l);</div>
<div class="line">r_h = <a class="code" href="vec__bcd__ppc_8h.html#a3411797c249e42c9c96f6e0b239e6e50">vec_bcdaddesqm</a> (a_h, b_h, c_l)</div>
</div><!-- fragment --><dl class="todo"><dt><b><a class="el" href="todo.html#_todo000004">Todo:</a></b></dt><dd>The BCD add/subtract extend/carry story is not complete. The carry extend operations based only on the <b>OV</b> condition codes only works as expected for bcdadd operands with the same sign and bcdsub with different signs. See <a class="el" href="vec__bcd__ppc_8h.html#a76d5034289bea5c7d9159db1d443f6b7" title="Decimal Add & write Carry Signed Quadword.">vec_bcdaddcsq()</a> and <a class="el" href="vec__bcd__ppc_8h.html#a6bf159e0abdccaa6fca21c6567b2067b" title="Decimal Add Extended & write Carry Signed Quadword.">vec_bcdaddecsq()</a>. Extended BCD difference (or subtract the same sign or add with different signs) is more complicated. See <a class="el" href="vec__bcd__ppc_8h.html#abd666963d18930e07be06aeb563eeb71" title="Decimal Sudtract & write Carry Signed Quadword.">vec_bcdsubcsq()</a> and <a class="el" href="vec__bcd__ppc_8h.html#a7eeb50993901b8bef76fa72cea668a15" title="Decimal Add Extended & write Carry Signed Quadword.">vec_bcdsubecsq()</a>. Generating a true borrow seems to require looking one (31-digit) column ahead or behind. The first attempt at generating correct borrowing is implemented in <a class="el" href="vec__bcd__ppc_8h.html#a486605817b8ca4850f7cf5584c751f45" title="Combined Decimal Add & Write Carry Signed Quadword.">vec_cbcdaddcsq()</a> and <a class="el" href="vec__bcd__ppc_8h.html#af9718d91a7e14c4a21e14a53f2f65041" title="Combined Decimal Add Extended & write Carry Signed Quadword.">vec_cbcdaddecsq()</a>. There are still cases where these operation will generate a borrow and invert (10s complement) incorrectly. The net seems to be that for BCD multiple precision difference to work correctly, the larger magnitude must be the first operand.</dd></dl>
<h3><a class="anchor" id="bcd128_muldiv_0_2_1"></a>
Vector BCD Multiply/Divide Quadword example</h3>
<p>BCD multiply and divide operations are not directly supported in the current PowerISA. Decimal multiply and divide are supported in the Decimal Floating-point (DFP) Facility, as well as conversion to and from signed (unsigned) BCD.</p>
<p>So BCD multiply and divide operations can be routed through the DFP Facility with a few caveats.</p><ul>
<li>DFP Extended format supports up to 34 digits precision</li>
<li>DFP significand represent digits to the <em>left</em> of the implied decimal point.</li>
<li>DFP finite number are not normalized.</li>
</ul>
<p>This allows DFP to represent decimal integer and fixed point decimal values with a preferred exponent of 0. The DFP Facility will maintain this preferred exponent for DPF arithmetic operations until:</p><ul>
<li>An arithmetic operation involves a operand with a non-zero exponent.</li>
<li>A divide operation generates a result with fractional digits</li>
<li>A multiply operation generates a result that exceeds 34 digits.</li>
</ul>
<p>The implementation can insure that input operands are derived from 31-digit BCD values. The results of any divide operations can be truncated back to decimal integer with the preferred 0 exponent. This can be achieved with the DFP Quantize Immediate instruction, specifying the ideal exponent of 0 and a rounding mode of <em>round toward 0</em> (see <a class="el" href="vec__bcd__ppc_8h.html#a75ec76de573013acc571e371e7200187" title="Quantize (truncate) a _Decimal128 value before convert to BCD.">vec_quantize0_Decimal128()</a>). This allows the following implementation: </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a31e982fe4ae794073eb8e60a2525bb0e">vec_bcddiv</a> (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> a, <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> b)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> t;</div>
<div class="line"> _Decimal128 d_t, d_a, d_b;</div>
<div class="line"> d_a = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (a);</div>
<div class="line"> d_b = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (b);</div>
<div class="line"> d_t = <a class="code" href="vec__bcd__ppc_8h.html#a75ec76de573013acc571e371e7200187">vec_quantize0_Decimal128</a> (d_a / d_b);</div>
<div class="line"> t = <a class="code" href="vec__bcd__ppc_8h.html#ad8123fa00f666a0d439a049eb4f7c7eb">vec_DFP2BCD</a> (d_t);</div>
<div class="line"> <span class="keywordflow">return</span> (t);</div>
<div class="line">}</div>
</div><!-- fragment --><p>The multiply case is bit more complicated as we need to produce up to 62 digit results without losing precision and DFP only supports 34 digits. This requires splitting the input operands into groups of digits where partial products of any combination of these groups is guaranteed not exceed 34 digits.</p>
<p>One way to do this is split each 31-digit operand into two 16-digit chunks (actually 15 and 16-digits). These chunks are converted to DFP extended format and multiplied to produce four 32-digit partial products. These partial products can be aligned and summed to produce the high and low 31-digits of the full 62-digit product. This is the basis for vec_bcd_mul(), <a class="el" href="vec__bcd__ppc_8h.html#a54558167b9339ac9459d3f6cecb7ca14" title="Vector Signed BCD Multiply High.">vec_bcdmulh()</a>, and <a class="el" href="vec__bcd__ppc_8h.html#a39a5438b38414210fceb891ff2261e7b" title="Combined Vector Signed BCD Multiply High/Low.">vec_cbcdmul()</a>.</p>
<p>A simple vec_and() can be used to isolate the low order 16 BCD digits. It is simple at this point to detect if both operands are 16-digits or less by comparing the original operand to the isolate value. In this case the product can not exceed 32 digits and we can short circuit the product to a single multiply. Here we can safely use binary compare all.</p>
<div class="fragment"><div class="line"><span class="keyword">const</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> dword_mask = (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="code" href="vec__common__ppc_8h.html#a9ed8c282b57705c960542ed869de3325">CONST_VINT128_DW</a>(15, -1);</div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> t, low_a, low_b, high_a, high_b;</div>
<div class="line">_Decimal128 d_p, d_t, d_a, d_b;</div>
<div class="line"> </div>
<div class="line">low_a = vec_and (a, dword_mask);</div>
<div class="line">low_b = vec_and (b, dword_mask);</div>
<div class="line">d_a = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (low_a);</div>
<div class="line">d_b = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (low_b);</div>
<div class="line">d_p = d_a * d_b;</div>
<div class="line"><span class="keywordflow">if</span> (__builtin_expect ((<a class="code" href="vec__int128__ppc_8h.html#a2c2c01f3aa165fedba47600f87067768">vec_cmpuq_all_eq</a> ((<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) low_a, (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) a)</div>
<div class="line"> && <a class="code" href="vec__int128__ppc_8h.html#a2c2c01f3aa165fedba47600f87067768">vec_cmpuq_all_eq</a> ((<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) low_b, (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) b)), 1))</div>
<div class="line"> {</div>
<div class="line"> d_t = d_p;</div>
<div class="line"> }</div>
<div class="line"><span class="keywordflow">else</span></div>
<div class="line"> {</div>
<div class="line"> ...</div>
<div class="line"> }</div>
<div class="line">t = <a class="code" href="vec__bcd__ppc_8h.html#ad8123fa00f666a0d439a049eb4f7c7eb">vec_DFP2BCD</a> (d_t);</div>
</div><!-- fragment --><p> This is a case where negative 0 can be generated in the DFP multiply and converted unchanged to BCD. This is handled with the following fix up code: </p><div class="fragment"><div class="line"> <span class="comment">// Minus zero</span></div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> mz = <a class="code" href="vec__common__ppc_8h.html#ae4520a89b9b5a292a3e647a6d5b712ad">CONST_VINT128_W</a> (0, 0, 0, 0x0000000d);</div>
<div class="line"> ...</div>
<div class="line">#ifdef _ARCH_PWR9</div>
<div class="line"> t = <a class="code" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939">vec_bcdadd</a> (t, <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> <span class="keywordflow">if</span> (vec_all_eq((<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) t, mz))</div>
<div class="line"> t = <a class="code" href="vec__bcd__ppc_8h.html#a65571de03c8870470db44b1abb9dbcb7">_BCD_CONST_ZERO</a>;</div>
<div class="line"><span class="preprocessor">#endif</span></div>
<div class="line"><span class="preprocessor"> return t;</span></div>
</div><!-- fragment --><p> From here the code diverges for multiply low and multiply high (and full combined multiply). Multiply low only needs the 3 lower order partial products. The highest order partial product does not impact the lower order 31-digits and is not needed. Multiply high requires the generation and summation of all 4 partial products. Following code completes the implementation of BCD multiply low: </p><div class="fragment"><div class="line">...</div>
<div class="line">else</div>
<div class="line"> {</div>
<div class="line"> _Decimal128 d_ah, d_bh, d_hl, d_lh, d_h;</div>
<div class="line"> </div>
<div class="line"> high_a = <a class="code" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6">vec_bcdsrqi</a> (a, 16);</div>
<div class="line"> high_b = <a class="code" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6">vec_bcdsrqi</a> (b, 16);</div>
<div class="line"> </div>
<div class="line"> d_ah = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (high_a);</div>
<div class="line"> d_bh = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (high_b);</div>
<div class="line"> </div>
<div class="line"> d_hl = d_ah * d_b;</div>
<div class="line"> d_lh = d_a * d_bh;</div>
<div class="line"> </div>
<div class="line"> d_h = d_hl + d_lh;</div>
<div class="line"> d_h = __builtin_dscliq (d_h, 17);</div>
<div class="line"> d_h = __builtin_dscriq (d_h, 1);</div>
<div class="line"> </div>
<div class="line"> d_t = d_p + d_h;</div>
<div class="line"> }</div>
</div><!-- fragment --><p> Here we know that there are higher order digits in one or both operands. First use <a class="el" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6" title="Vector BCD Shift Right Signed Quadword Immediate.">vec_bcdsrqi()</a> to isolate the high 15-digits of operands a and b. Both Vector unit and DFP Facility have decimal shift operations, but the vector shift operation is faster.</p>
<p>Then convert to DFP and multiply (high_a * low_b and high_b * low_a) for the two middle order partial products which are summed. This sum represents the high 32-digits (the 31-digit sum can carry) of a 48-digit product. Only the lower 16-digits of this sum is needed for the final sum and this needs to be aligned with the high 16 digits of the original lower order partial product.</p>
<p>For this case use <b>DFP Shift Significand Left Immediate</b> and <b>DFP Shift Significand Right Immediate</b>. All the data is in the DFP Facility and the high cost of the DFP Facility shift is offset by avoiding extra format conversions. We use shift left 17 followed by shift right 1 to clear the highest order DFP digit and avoid any overflow. A final DFP add produces the low order 32 digits of the product which will be truncated to 31-digits in the conversion to BCD.</p>
<p>How we can look at the BCD multiply high (generate the full 62-digit product returning the high 31 digits) and point out the differences. Multiply high also starts by isolating the low order 16 BCD digits, performing the low order multiply (low_a * low_b), and testing for the short circuit (all higher order digits are 0). The first difference (from multiply low) is that in this case only the high digit of the potential 32-digit product is returned.</p>
<div class="fragment"><div class="line"><span class="keyword">const</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> dword_mask = (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="code" href="vec__common__ppc_8h.html#a9ed8c282b57705c960542ed869de3325">CONST_VINT128_DW</a>(15, -1);</div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> t, low_a, low_b, high_a, high_b;</div>
<div class="line">_Decimal128 d_p, d_t, d_a, d_b;</div>
<div class="line"> </div>
<div class="line">low_a = vec_and (a, dword_mask);</div>
<div class="line">low_b = vec_and (b, dword_mask);</div>
<div class="line">d_a = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (low_a);</div>
<div class="line">d_b = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (low_b);</div>
<div class="line">d_p = d_a * d_b;</div>
<div class="line"><span class="keywordflow">if</span> (__builtin_expect ((<a class="code" href="vec__int128__ppc_8h.html#a2c2c01f3aa165fedba47600f87067768">vec_cmpuq_all_eq</a> ((<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) low_a, (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) a)</div>
<div class="line"> && <a class="code" href="vec__int128__ppc_8h.html#a2c2c01f3aa165fedba47600f87067768">vec_cmpuq_all_eq</a> ((<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) low_b, (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) b)), 1))</div>
<div class="line"> {</div>
<div class="line"> d_t = __builtin_dscriq (d_p, 31);</div>
<div class="line"> }</div>
<div class="line"><span class="keywordflow">else</span></div>
<div class="line"> {</div>
<div class="line"> ...</div>
<div class="line"> }</div>
<div class="line">t = <a class="code" href="vec__bcd__ppc_8h.html#ad8123fa00f666a0d439a049eb4f7c7eb">vec_DFP2BCD</a> (d_t);</div>
</div><!-- fragment --><p> So the short circuit code shifts the low partial product right 31 digits and returns that value.</p>
<p>If we can not short circuit, Multiply high requires the generation and summation of all four partial products. Following code completes the implementation of BCD multiply high: </p><div class="fragment"><div class="line">...</div>
<div class="line">else</div>
<div class="line"> {</div>
<div class="line"> _Decimal128 d_ah, d_bh, d_hl, d_lh, d_h, d_ll, d_m;</div>
<div class="line"> </div>
<div class="line"> high_a = <a class="code" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6">vec_bcdsrqi</a> (a, 16);</div>
<div class="line"> high_b = <a class="code" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6">vec_bcdsrqi</a> (b, 16);</div>
<div class="line"> d_ah = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (high_a);</div>
<div class="line"> d_bh = <a class="code" href="vec__bcd__ppc_8h.html#aa924d03e2f88506e323c4b70f4b7df8b">vec_BCD2DFP</a> (high_b);</div>
<div class="line"> </div>
<div class="line"> d_hl = d_ah * d_bl;</div>
<div class="line"> d_lh = d_al * d_bh;</div>
<div class="line"> d_ll = __builtin_dscriq (d_p, 16);</div>
<div class="line"> </div>
<div class="line"> d_m = d_hl + d_lh + d_ll;</div>
<div class="line"> d_m = __builtin_dscriq (d_m, 15);</div>
<div class="line"> </div>
<div class="line"> d_h = d_ah * d_bh;</div>
<div class="line"> d_h = __builtin_dscliq (d_h, 1);</div>
<div class="line"> d_t = d_m + d_h;</div>
<div class="line"> }</div>
</div><!-- fragment --><p> Again we know that there are higher order digits in one or both operands and use <a class="el" href="vec__bcd__ppc_8h.html#a76cd98e594ec0b867a4ffd4be62e77f6" title="Vector BCD Shift Right Signed Quadword Immediate.">vec_bcdsrqi()</a> to isolate the high 15-digits of operands a and b. Then convert to DFP and multiply (high_a * low_b and high_b * low_a) for the two middle order partial products (d_hl and d_lh).</p>
<p>The low order partial product (d_p) was generated above but we need only the high order 15 digits for summation. Shift the low partial product right 16 digits then sum (d_hl + d_lh + d_ll) the low and middle order partial products. This produces the high 32 digits of the lower 48 digit partial sum. Shift this right 15 digits to align with the high order 31 digits for the product.</p>
<p>Then multiply (high_a * high_b) to generate the high order partial product. This represents the high 30 digits of a 62 digits. Shift this left 1 digit to correct the alignment. The sum of the adjusted high and middle order partials gives the high order 31 digits of the 62-digit product.</p>
<h3><a class="anchor" id="bcd128_convert_0_2_2"></a>
Vector BCD to/from Binary conversion</h3>
<p>Conversions between Decimal (BCD, Zoned, or string) and binary is another topic which is more complicated that it first appears. Everyone that takes computer science should have learned about <em>atoi</em> and <em>itoa</em> for conversions between strings of decimal character and binary integers.</p>
<p>ASCII to integer is basically;</p><ul>
<li>initialize a integer accumulator to 0</li>
<li>loop<ul>
<li>multiply the accumulator by 10</li>
<li>load the next character and convert to a binary decimal digit</li>
<li>Add this digit to the accumulator</li>
</ul>
</li>
<li>repeat until end of string.</li>
</ul>
<p>Integer to ASCII is basically;</p><ul>
<li>initialize a temp variable with the integer number</li>
<li>loop<ul>
<li>compute the remainder/modulo of temp by 10</li>
<li>convert this binary digit to a character and store as the next char</li>
<li>divide temp by 10 and use that for the next iteration</li>
</ul>
</li>
<li>repeat until temp is zero.</li>
</ul>
<p>You may have noticed that the algorithms above are not exactly vector ready. Both are serialized on expensive multiply and divide operations. This is not so bad for 9 digit (32-bit) integers but will be noticeable when converting between 128-bit binary and 31-digit BCD.</p>
<p>For the vector BCD equivalent of <b><em>atoi</em></b> we could use the PVECLIB implementation of <b>Vector Multiply by 10 Extended Unsigned Quadword</b>. For POWER8, <a class="el" href="vec__int128__ppc_8h.html#a2245626e7b90621b33ba79b763a4215e" title="Vector Multiply by 10 Extended Unsigned Quadword.">vec_mul10euq()</a> uses; multiple even/odd, a couple of shift left octet immediates, and add quadword. This sequence runs 5-7 instructions and has a minimum latency of 13 cycles. To convert from BCD to binary we need to shift and isolate, one BCD digit at time, then feed that into <a class="el" href="vec__int128__ppc_8h.html#a2245626e7b90621b33ba79b763a4215e" title="Vector Multiply by 10 Extended Unsigned Quadword.">vec_mul10euq()</a>. Ignoring for now the latency associated with shifting the BCD digits, we can quickly estimate 13 * 32 = 416 cycles to convert 32 digits.</p>
<p>For the vector BCD equivalent of <b><em>itoa</em></b> we could use the POWER8 <b>Decimal Add Modulo</b> instruction. For POWER8 <a class="el" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939" title="Decimal Add Signed Modulo Quadword.">vec_bcdadd()</a> has a latency of 13 cycles. But the conversion would be one bit at a time. Use <a class="el" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939" title="Decimal Add Signed Modulo Quadword.">vec_bcdadd()</a> to multiply by 2 then shift / issolate a bit from the binary value, format / convert that bit to BCD 0/1. and <a class="el" href="vec__bcd__ppc_8h.html#a047be6d6339193b854e0b41759888939" title="Decimal Add Signed Modulo Quadword.">vec_bcdadd()</a> again. So a quick estimate for this conversion is 13 * 2 * 128 = 3328 cycles.</p>
<h4><a class="anchor" id="bcd128_convert_0_2_2_1"></a>
Vector Parallel conversion</h4>
<p>Clearly just using bigger registers for bigger numbers is not helping. So we want to think about algorithms that do more in parallel and leverage the vector unit we have.</p>
<p>For POWER9 we have Decimal Convert From/To Signed Quadword and Decimal Convert From/To Zoned (See <a class="el" href="vec__bcd__ppc_8h.html#a5a1aec05a6dadcf5a1a8e028223745df" title="Vector Decimal Convert From Signed Quadword returning up to 31 BCD digits.">vec_bcdcfsq()</a>, <a class="el" href="vec__bcd__ppc_8h.html#a5086ba6056febb11acd5d5cd18e96dfb" title="Vector Decimal Convert to Signed Quadword.">vec_bcdctsq()</a>, <a class="el" href="vec__bcd__ppc_8h.html#ae4923e7e5746c5c6f21ddc9993894692" title="Vector Decimal Convert From Zoned.">vec_bcdcfz()</a>, <a class="el" href="vec__bcd__ppc_8h.html#a832d31ded0b33a2b46f6491bcb71ea51" title="Vector Decimal Convert To Zoned.">vec_bcdctz()</a>). These provide direct conversion between quadword binary and signed BCD and between signed BCD and zoned characters.</p>
<p>The BCD convert from/to Zoned are simple operation that run 3 cycles latency on POWER9 and 14-27 cycles for the POWER8 implementation. For POWER8 there is some additional complexity verify and converting the preferred <em>sign code</em> between BCD and Zoned (of course they are different).</p>
<p>But the BCD convert from/to Signed Quadword operations are a bit heavier, running 37 and 23 cycles latency on POWER9. These instructions execute in the DFU and so are single issue. They also keeps the DFU pipeline busy (for 25 and 11 cycles) and block execution of the next DFU operation for a while. Still this is better than the serial conversion examples described above.</p>
<p>But part of the value of PVECLIB is to provide support across POWER7/8/9 and across compiler versions. The convert instructions above are not supported in current compilers with built-ins so PVECLIB provides in-line assembler implementations for these operations. Now we need look into better algorithms for implementing these operations on POWER7/8.</p>
<p>The Vector unit can multiply, add, or subtract integer elements in parallel. The conversion process is basically multiply and add/sub as we can replace divide operations with the multiplicative inverse. So if we are looking for a way to break the conversion down into steps that can be performed in parallel on elements of the larger value and require fewer steps.</p>
<p>For now we can simplify the problem to unsigned radix conversion and deal with signed conversion as a later cleanup step based on the complete unsigned conversion.</p>
<h4><a class="anchor" id="bcd128_convert_0_2_2_2"></a>
Vector Parallel BCD to quadword conversion</h4>
<p>Starting with BCD (Radix 10) to Binary (Radix 2) conversion. The data is represented as 32 BCD digits encoded as 4-bit <em>nibbles</em> starting with high orders digits on the left, to low order digits on the right.</p>
<p>Said differently, unsigned BCD vectors are represented as 16-bytes each containing a pair of BCD digits, each in the range 00-99. This is helpful because the PowerISA has instructions that multiply and add integer bytes, in parallel. So it seems possible to convert bytes containing even/odd pairs of BCD digits to integer bytes, each in the range 0-99: simply multiply the even digit by 10 and add the odd digit.</p>
<p>The result is a vector of 16 x radix-100 bytes (binary integers in the range 0-99). Said differently a radix 100 vector represented as 8 halfwords each containing a pair of radix 100 digits, each in the range 0-99. Again these pairs of digits (bytes) can be converted by multiply and add to radix 10,000 halfwords.</p>
<p>Repeat the process three more times:</p><ul>
<li>convert 8 halfwords pairwise into 4 words each containing values in the range 0-99999999 (radix 10**8 digits).</li>
<li>convert 4 words pairwise into 2 doublewords, each containing values in the range 0-9999999999999999 (radix 10*16 digits).</li>
<li>convert 2 doublewords pairwise into a quadword integer in the range 0-99999999999999999999999999999999.</li>
</ul>
<p>So in 5 steps, each only using vector multiply and add, we convert 32 BCD digits to a quadword integer.</p>
<dl class="section note"><dt>Note</dt><dd>Actually 10**32 can be represented in 107 bits, but who is counting.</dd></dl>
<p>Actually, it is a little more complicated than multiply and add. The digits of the digit pair must be isolated and shifted into alignment before the multiply and add. Looking something like this:</p>
<div class="fragment"><div class="line"><a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a></div>
<div class="line">test_vec_rdxct100b_0 (<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> x10, c10, high_digit, low_digit;</div>
<div class="line"> <span class="comment">// Isolate the low_digit</span></div>
<div class="line"> low_digit = <a class="code" href="vec__char__ppc_8h.html#a095741b255775d4ccf6228a5655599a2">vec_slbi</a> (vra, 4);</div>
<div class="line"> low_digit = <a class="code" href="vec__char__ppc_8h.html#a495109a7d46f4a97b56f22bb315ac567">vec_srbi</a> (low_digit, 4);</div>
<div class="line"> <span class="comment">// Shift the high digit into the units position</span></div>
<div class="line"> high_digit = <a class="code" href="vec__char__ppc_8h.html#a495109a7d46f4a97b56f22bb315ac567">vec_srbi</a> (vra, 4);</div>
<div class="line"> <span class="comment">// multiply the high digit by 10</span></div>
<div class="line"> c10 = vec_splats ((<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>) 10);</div>
<div class="line"> x10 = <a class="code" href="vec__char__ppc_8h.html#a425151e5a82ee9e204ffd81b1ec7a92c">vec_mulubm</a> (high_digit, c10);</div>
<div class="line"> <span class="comment">// add the low_digit to high_digit * 10.</span></div>
<div class="line"> <span class="keywordflow">return</span> vec_add (x10, low_digit);</div>
<div class="line">}</div>
</div><!-- fragment --><p> The PowerISA does not provide general <em>nibble</em> arithmetic, only byte. So the first operations involve isolating each nibble into separate (high_digit and low_digit) bytes. The high_digit shift also aligns the binary for the multiply and add.</p>
<p>The Multiply Unsigned Byte Modulo (<a class="el" href="vec__char__ppc_8h.html#a425151e5a82ee9e204ffd81b1ec7a92c" title="Vector Multiply Unsigned Byte Modulo.">vec_mulubm()</a>) generates vmuleub/vmuloub then loads a permute control vector and permutes the low order bytes of the halfword (even/odd) products into a single vector. Finally, add the x10 product and low_digit to get the binary value in the range 0-99.</p>
<p>This sequence runs 6-10 instructions and 13-22 cycles latency. The lower values assume the shift control and permute control vectors are commoned with other operations.</p>
<p>This is a case where the process on paper is much simpler than the reality of programming computers. The operation is actually (bcd_byte / 16 * 10) + (bcd_byte * 16 / 16) where 16 is the <em>alignment</em> radix and 10 is the <em>decimal</em> radix at this step. The alignment radix operations are (fortunately) strength reduced to vector byte shift left/right.</p>
<p>Let's use a little algebra to eliminate some of these steps. One approach is to generate a correction factor from the high_digit and the difference between the <em>alignment</em> and decimal radix. This correction factor is subtracted directly from the original BCD byte and reduces the operation to (bcd_byte - ((bcd_byte / 16) x (16 - 10)) Which looks something like: </p><div class="fragment"><div class="line"><a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a></div>
<div class="line">test_vec_rdxct100b_1 (<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> x6, c6, high_digit;</div>
<div class="line"> <span class="comment">// Compute the high digit correction factor. For BCD to binary 100s</span></div>
<div class="line"> <span class="comment">// this is the isolated high digit multiplied by the radix difference</span></div>
<div class="line"> <span class="comment">// in binary. For this stage we use 0x10 - 10 = 6.</span></div>
<div class="line"> high_digit = <a class="code" href="vec__char__ppc_8h.html#a495109a7d46f4a97b56f22bb315ac567">vec_srbi</a> (vra, 4);</div>
<div class="line"> c6 = vec_splats ((<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>) (16-10));</div>
<div class="line"> x6 = <a class="code" href="vec__char__ppc_8h.html#a425151e5a82ee9e204ffd81b1ec7a92c">vec_mulubm</a> (high_digit, c6);</div>
<div class="line"> <span class="comment">// Subtract the high digit correction bytes from the original</span></div>
<div class="line"> <span class="comment">// BCD bytes in binary. This reduces byte range to 0-99.</span></div>
<div class="line"> <span class="keywordflow">return</span> vec_sub (vra, x6);</div>
<div class="line">}</div>
</div><!-- fragment --><p> Another opportunity is to let the compiler strength reduce the multiply to shift and add. Newer versions of GCC will perform this optimization when using the generic vec_mul built-in for vector integer elements. </p><dl class="section note"><dt>Note</dt><dd>Previous to GCC 8, vec_mul() was only supported for vector float and double.</dd></dl>
<div class="fragment"><div class="line"><span class="preprocessor">#if (__GNUC__ > 7)</span></div>
<div class="line"> x6 = vec_mul (high_digit, c6);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> x6 = <a class="code" href="vec__char__ppc_8h.html#a425151e5a82ee9e204ffd81b1ec7a92c">vec_mulubm</a> (high_digit, c6);</div>
<div class="line"><span class="preprocessor">#endif</span></div>
</div><!-- fragment --><p> This eliminates vector multiply even/odd, the permute, and the load associated with the permute. The final sequence runs 5-7 instructions and 10-12 cycles latency and looks something like this: </p><div class="fragment"><div class="line">vspltisb v1,4</div>
<div class="line">vspltisb v13,1</div>
<div class="line">vsrb v1,v2,v1</div>
<div class="line">vslb v0,v1,v13</div>
<div class="line">vaddubm v0,v0,v1</div>
<div class="line">vslb v0,v0,v13</div>
<div class="line">vsububm v2,v2,v0</div>
</div><!-- fragment --><p>The next step converts adjacent byte pairs to halfwords. We use the same basic formula but adjust the radix constants to; (rdx_hword - ((rdx_hword / 256) x (256 - 100)). Here we need a byte multiply producing a halfword correction factor. No shifts are needed as the vmuleub multiply will access the high byte of each halfword directly.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a58484a98545f49712158d7943047b875">vec_rdxct10kh</a> (<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> c156;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> x156;</div>
<div class="line"> <span class="comment">// Compute the high digit correction factor. For 100s to binary 10ks</span></div>
<div class="line"> <span class="comment">// this is the isolated high digit multiplied by the radix difference</span></div>
<div class="line"> <span class="comment">// in binary. For this stage we use 256 - 100 = 156.</span></div>
<div class="line"> c156 = vec_splats ((<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>) 156);</div>
<div class="line"><span class="preprocessor">#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__</span></div>
<div class="line"> x156 = vec_mulo ((<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a>) vra, c156);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> x156 = vec_mule ((<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a>) vra, c156);</div>
<div class="line"><span class="preprocessor">#endif</span></div>
<div class="line"> <span class="comment">// Subtract the high digit correction halfword from the original</span></div>
<div class="line"> <span class="comment">// 100s byte pair in binary. This reduces the range to 0-9999.</span></div>
<div class="line"> <span class="keywordflow">return</span> vec_sub ((<a class="code" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a>) vra, x156);</div>
<div class="line">}</div>
</div><!-- fragment --><p> This requires: a constant load, a multiply even byte and subtract halfword. The final sequence runs 2-5 instructions and 9-18 cycles latency and looks something like this: </p><div class="fragment"><div class="line">addis r9,r2,.rodata.cst16+0x90@ha</div>
<div class="line">addi r9,r9,.rodata.cst16+0x90@l</div>
<div class="line">lvx v0,0,r9</div>
<div class="line">vmuleub v0,v2,v0</div>
<div class="line">vsubuhm v2,v2,v0</div>
</div><!-- fragment --><p>This pattern continues for converting halfwords to words, words to doublewords, and doublewords to quadwords. For POWER8 the first 4 steps are supported by vector multiply and subtract instructions. The last step requires a <a class="el" href="vec__int128__ppc_8h.html#a84e6361054b52ac4564bcef25b718151" title="Vector Multiply Even Unsigned Doublewords.">vec_vmuleud()</a> operation implemented in <a class="el" href="vec__int128__ppc_8h.html" title="Header package containing a collection of 128-bit computation functions implemented with PowerISA VMX...">vec_int128_ppc.h</a>, based on <a class="el" href="vec__int32__ppc_8h.html#ac93f07d5ad73243db2771da83b50d6d8" title="Vector multiply even unsigned words.">vec_muleuw()</a>, <a class="el" href="vec__int32__ppc_8h.html#a3ca45c65b9627abfc493d4ad500a961d" title="Vector multiply odd unsigned words.">vec_mulouw()</a> and <a class="el" href="vec__int128__ppc_8h.html#a539de2a4426a84102471306acc571ce8" title="Vector Add Unsigned Quadword Modulo.">vec_adduqm()</a>. The <a class="el" href="vec__int128__ppc_8h.html#a539de2a4426a84102471306acc571ce8" title="Vector Add Unsigned Quadword Modulo.">vec_adduqm()</a> operation is single instruction for POWER8. For POWER7 we will need to leverage more operations implemented in <a class="el" href="vec__int64__ppc_8h.html" title="Header package containing a collection of 128-bit SIMD operations over 64-bit integer elements.">vec_int64_ppc.h</a> and <a class="el" href="vec__int128__ppc_8h.html" title="Header package containing a collection of 128-bit computation functions implemented with PowerISA VMX...">vec_int128_ppc.h</a> for the last two steps.</p>
<p>The complete set of steps for converting 32 BCD digits to quadword __int128 binary looks like this: </p><div class="fragment"><div class="line"><a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a></div>
<div class="line">example_vec_bcdctuq (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> d100;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> d10k;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> d100m;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> d10e;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> result;</div>
<div class="line"> </div>
<div class="line"> d100 = <a class="code" href="vec__bcd__ppc_8h.html#a7e490fa302fb2275fe07368c6276cf9c">vec_rdxct100b</a> ((<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a>) vra);</div>
<div class="line"> d10k = <a class="code" href="vec__bcd__ppc_8h.html#a58484a98545f49712158d7943047b875">vec_rdxct10kh</a> (d100);</div>
<div class="line"> d100m = <a class="code" href="vec__bcd__ppc_8h.html#a2e857a02bebc27fb0bb18eea5ceddf0d">vec_rdxct100mw</a> (d10k);</div>
<div class="line"> d10e = <a class="code" href="vec__bcd__ppc_8h.html#a3e5105096cab9b9a2ae703262e403352">vec_rdxct10E16d</a> (d100m);</div>
<div class="line"> result = <a class="code" href="vec__bcd__ppc_8h.html#aa3cdbd0a0ce3687c82bdcfad7b2281f9">vec_rdxct10e32q</a> (d10e);</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> result;</div>
<div class="line">}</div>
</div><!-- fragment --><p> For POWER8 the whole sequence runs 24-36 instructions and 65-78 cycles latency. For POWER9 the whole sequence runs 17-26 instructions and 52-65 cycles latency.</p>
<dl class="section note"><dt>Note</dt><dd>POWER9 has a Decimal Convert to Signed Quadword instruction, but no unsigned (32-digit) convert.</dd></dl>
<p>However we can leverage the POWER9 <b>Vector Multiply by 10 Extended Unsigned Quadword</b> instruction to extend the 31-digit convert to a full 32-digits. Basically use the <b>bcdctsq</b> to convert the high 31-digits and then multiply by 10 and add the last digit. See example below:</p>
<div class="fragment"><div class="line"><a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a></div>
<div class="line">example_vec_bcdctuq_2 (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> vrt;</div>
<div class="line"><span class="preprocessor">#ifdef _ARCH_PWR9</span></div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> bcd_one = (<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#a2dc4f754b3261ac01c51a4e30b332488">_BCD_CONST_PLUS_ONE</a>;</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> sign_mask = (<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#a50e023591594ad9e7110702fed96d9c7">_BCD_CONST_SIGN_MASK</a>;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> vrd;</div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> sbcd;</div>
<div class="line"> <span class="comment">// Need to convert BCD unsigned to signed for bcdctsq</span></div>
<div class="line"> <span class="comment">// But can't use bcdcpsgn as the unit digit is not a sign code</span></div>
<div class="line"> <span class="comment">// So use vec_and/sel to extract unit digit and insert sign</span></div>
<div class="line"> vrd = (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) vec_and ((<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) vra, sign_mask);</div>
<div class="line"> sbcd = (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) vec_sel ((<a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a>) vra, bcd_one, sign_mask);</div>
<div class="line"> <span class="comment">// Convert top 31 digits to binary</span></div>
<div class="line"> vrt = (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#a5086ba6056febb11acd5d5cd18e96dfb">vec_bcdctsq</a> (sbcd);</div>
<div class="line"> <span class="comment">// Then X 10 plus the unit digit to complete 32-digit convert</span></div>
<div class="line"> vrt = <a class="code" href="vec__int128__ppc_8h.html#a2245626e7b90621b33ba79b763a4215e">vec_mul10euq</a> (vrt, vrd);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> <span class="comment">// P7/P8 implementation as above</span></div>
<div class="line"><span class="preprocessor">#endif</span></div>
<div class="line"> <span class="keywordflow">return</span> vrt;</div>
<div class="line">}</div>
</div><!-- fragment --><p> This adds a few more cycles to split the high digits from the low digit and insert a positive sign code. This requires loading some vector constants which may be commoned with loads from other operations. This adds 2-11 cycles. The <b>mul10euq</b> only adds 3 cycles latency to complete the BCD to Binary conversion. This is adds only a 21% to 60% latency over the base <b>bcdctsq</b> instruction.</p>
<dl class="section note"><dt>Note</dt><dd>This process can be extended to 256, 512, 1024-bits, etc by widening the BCD to binary conversion appropriately to blocks of 31 or 32 digits. Then use the basic <em>atoi</em> algorithm using extended quadword multiply / add operations from <a class="el" href="vec__int128__ppc_8h.html" title="Header package containing a collection of 128-bit computation functions implemented with PowerISA VMX...">vec_int128_ppc.h</a> (<a class="el" href="vec__bcd__ppc_8h.html#bcd128_convert_0_2_3">Multiple precision BCD to/from Binary conversion</a>).</dd></dl>
<h4><a class="anchor" id="bcd128_convert_0_2_2_3"></a>
Vector Parallel quadword to BCD conversion</h4>
<dl class="section note"><dt>Note</dt><dd>Binary to BCD conversions are challenging a in a number of ways. First any conversion requires division by non powers of 2. Second, for the same element size binary representation holds more equivalent decimal digits then BCD. If the binary value is too large for the BCD target's element size, the results are often undefined. For example <a class="el" href="vec__bcd__ppc_8h.html#a5a1aec05a6dadcf5a1a8e028223745df" title="Vector Decimal Convert From Signed Quadword returning up to 31 BCD digits.">vec_bcdcfsq()</a>. So it is important to constrain the magnitude of the binary to fit the BCD target before conversion. See <a class="el" href="vec__int128__ppc_8h.html#int128_examples_0_1_2">Converting Vector __int128 values to BCD</a> for details.</dd></dl>
<p>In most senses, binary to BCD is the reverse of BCD to binary. The radix number in the conversion formula exchange places and the conversion starts with the largest element size (quadword) and works it's way down to the smallest (4-bit nibble).</p>
<p>Let's take a look at the conversion formula. For BCD to Binary we used:</p><ul>
<li>bin_byte <- (bcd_byte - ((bcd_byte / 16) x (16 - 10))</li>
<li>bin_byte <- (bcd_byte - ((bcd_byte >> 4) x 6)</li>
</ul>
<p>So after swapping the conversion (to / from) radix constants we see:</p><ul>
<li>bcd_byte <-(bin_byte - ((bin_byte / 10) x (10 - 16))</li>
<li>bcd_byte <-(bin_byte - ((bin_byte / 10) x (-6))</li>
<li>bcd_byte <-(bin_byte + ((bin_byte / 10) x 6)</li>
</ul>
<p>The effect is to divide vector elements of 4*2N bits by 10**N and return the quotient in the high half of the element (in 4*N bits), and the remainder of this divide in the low half of the element (in 4*N bits), Where N is a power of 2<sup>n</sup> and <em>n</em> ranges from 0 to 4 (5 steps again).</p>
<dl class="section note"><dt>Note</dt><dd>So why doesn't PVECLIB provide these steps as operations. For example: divide a vector unsigned __int128 by 10<sup>16</sup> and return the quotient in the high doubleword and the remainder in the low doubleword of a vector unsigned long? Because if the input quadword is not less than 10<sup>32</sup> the result is undefined (the quotient will overflow).</dd></dl>
<p>This is good news and bad news. It is good that the correction subtract became a simple add. This allows the uses of multiply sum instruction (where PowerISA has such instructions for the element size). The bad news is that the radix divisor is not a power of two. And since the PowerISA does not have vector integer divide instructions, we use the multiplicative inverse. So in effect, each step of the binary to BCD conversion requires, two multiplies and an add.</p>
<p>So let's look at the first and last step of the conversion (the two extremes). The first step (after verifying that the quadword value is less than 10<sup>32<</sup>-1) looks like this: </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#aab57aa00d4c2c17bc2eee01b50523a5a">vec_rdxcf10e32q</a> (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Compute the high digit correction factor. For binary 10**32 to</span></div>
<div class="line"> <span class="comment">// 10**16, this is 0x10000000000000000 - 10000000000000000</span></div>
<div class="line"> <span class="comment">// = 18436744073709551616.</span></div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> c = <a class="code" href="vec__common__ppc_8h.html#a9ed8c282b57705c960542ed869de3325">CONST_VINT128_DW</a> (0, 18436744073709551616UL);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Magic numbers for multiplicative inverse to divide by 10**16</span></div>
<div class="line"> <span class="comment">// are 76624777043294442917917351357515459181, no corrective add,</span></div>
<div class="line"> <span class="comment">// and shift right 51 bits.</span></div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> mul_invs_ten16 = (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a>) <a class="code" href="vec__common__ppc_8h.html#a9ed8c282b57705c960542ed869de3325">CONST_VINT128_DW</a>(</div>
<div class="line"> 0x39a5652fb1137856UL, 0xd30baf9a1e626a6dUL);</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> shift_ten16 = 51;</div>
<div class="line"> </div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> result;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> x, high_digit;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// high_digit = vra / 10000000000000000;</span></div>
<div class="line"> high_digit = <a class="code" href="vec__int128__ppc_8h.html#ad6be9c8f02e43c39a659d6bbc9c3a2d2">vec_mulhuq</a> (vra, mul_invs_ten16);</div>
<div class="line"> high_digit = <a class="code" href="vec__int128__ppc_8h.html#ac05c640c6a42770cb95466ff4a2d903c">vec_srqi</a> (high_digit, shift_ten16);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// multiply high_digit by the radix difference c and add vra</span></div>
<div class="line"> <span class="comment">// This separates the high/low 16 digits into doublewords.</span></div>
<div class="line"><span class="preprocessor">#ifdef _ARCH_PWR9</span></div>
<div class="line"> <span class="comment">// 0 in the high dword of const c reduces vmsumudm to vmuloud</span></div>
<div class="line"> <span class="comment">// but with a qword add included.</span></div>
<div class="line"> result = (<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) <a class="code" href="vec__int128__ppc_8h.html#a1d183ebd232e5826be109cdaa421aeed">vec_msumudm</a> ((<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) high_digit, c, vra);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> x = <a class="code" href="vec__int128__ppc_8h.html#a208744996e7482604ad274b44999d6ce">vec_vmuloud</a> ((<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) high_digit, c);</div>
<div class="line"> result = (<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) <a class="code" href="vec__int128__ppc_8h.html#a539de2a4426a84102471306acc571ce8">vec_adduqm</a> (vra, x);</div>
<div class="line"><span class="preprocessor">#endif</span></div>
<div class="line"> <span class="keywordflow">return</span> result;</div>
<div class="line">}</div>
</div><!-- fragment --><p> The first multiply is an expensive (40 to 60 cycles) operation as it requires a full Multiply High Unsigned Quadword. The next operation requires a Multiply Odd Unsigned Doubleword then Add Unsigned Quadword Modulo. For POWER9 we can replace these two operations with a single Multiply Sum Unsigned Doubleword Modulo. The latency of this single step is in the same order at the complete BCD to Binary conversion (<a class="el" href="vec__bcd__ppc_8h.html#a29ae39efd0668fc35b5b6a33d2d46f9e" title="Vector Decimal Convert groups of 32 BCD digits to binary unsigned quadword.">vec_bcdctuq()</a>).</p>
<p>The conversion steps continue with doubleword to word, word to halfword, halfword to byte, byte to BCD (nibbles). The final step is simple by comparison to the first step. </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a226e0f45eb9c65e388ee86b3b80540e7">vec_rdxcf100b</a> (<a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> x6, c6, high_digit;</div>
<div class="line"> <span class="comment">// Let the compiler generate the multiplicative inverse code</span></div>
<div class="line"> high_digit = vra / 10;</div>
<div class="line"> <span class="comment">// This separates two digit values into BCD Nibbles.</span></div>
<div class="line"> <span class="comment">// multiply high_digit by the radix difference c and</span></div>
<div class="line"> x6 = high_digit * 6;</div>
<div class="line"> <span class="comment">// add bytes the high digit correction to the original</span></div>
<div class="line"> <span class="comment">// (radix 100) bytes in binary.</span></div>
<div class="line"> <span class="keywordflow">return</span> (vra + x6);</div>
<div class="line">}</div>
</div><!-- fragment --><p> The GCC vector extensions support dividing a vector char / short / int by a constant. So we can let the compiler generate the multiplicative inverse code for the last three steps. This is not supported (yet) for long and __int128 so the first two steps must explicitly code the multiplicative inverse.</p>
<p>Using GCC vector extensions for the following multiply and add works well in this case as it allows the compiler to perform strength reduction. It is not as useful in the other steps as the programmer knows more about the value ranges then the compiler can or should assume. We know the the quotient and corrective constant always fit into the lower half of the element. This allows the use of the half sized vector multiply odd unsigned while compiler will assume it needs to generate a multiply modulo for the full element size.</p>
<p>For example the third step (word to halfword) we can use Multiply Sum Unsigned Halfword Modulo to replace the multiply odd and add. This is similar to the multiply sum usage in the first step and it is a case not recognized by the compiler.</p>
<p>The full binary to BCD conversion requires all 5 steps to complete the operations and this adds up to 200+ cycles. So this is worth another look.</p>
<p>Initially using the DFP Facility for this binary to BCD conversion was rejected because:</p><ul>
<li>The DFP Facility only supports signed fixed doubleword conversions (no fixed quadword conversion)</li>
<li>Fixed binary to DFP conversions are expensive operations<ul>
<li>For POWER8, 32 cycles latency and 1 per 19 cycles throughput</li>
</ul>
</li>
<li>The DFP Facility does support DFP to BCD conversions for double and quadword<ul>
<li>For POWER8, 13 cycle latency and 1 per cycle throughput</li>
</ul>
</li>
</ul>
<p>Perhaps we can use the <a class="el" href="vec__bcd__ppc_8h.html#aab57aa00d4c2c17bc2eee01b50523a5a" title="Vector Decimal Convert radix 10**32 Binary quadword to pairs of radix 10**16 binary doublewords.">vec_rdxcf10e32q()</a> operation we defined above as the first step (factoring quadwords into the 16 digit doublewords). Then use the DFP Facility to convert binary doublewords to BCD. In this case we are not concerned with signed conversion as 10**16 fits in 54-bits binary and guarantees positive binary values. We still have to deal with the VR to/from FPR transfers but that mechanism is already defined and at a reasonable cost (2-4 cycles each way).</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#ad4222bd4b90a5248015fbea12cbc0a21">vec_BIN2BCD</a> (<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> val)</div>
<div class="line">{</div>
<div class="line"><span class="preprocessor">#ifdef _ARCH_PWR6</span></div>
<div class="line"> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a> t;</div>
<div class="line"> _Decimal128 x, y, z;</div>
<div class="line"> <span class="comment">// unpack the vector into a FPRp</span></div>
<div class="line"> z = <a class="code" href="vec__bcd__ppc_8h.html#a9c19a6744e6f0b5fde60a0f36289e468">vec_unpack_Decimal128</a> ((<a class="code" href="vec__common__ppc_8h.html#ae5cccc22e004bddbb80a51117c448675">vf64_t</a>) val);</div>
<div class="line"> <span class="comment">// Convert 2 long int values into 2 _Decimal64 values</span></div>
<div class="line"> <span class="comment">// Then convert each _Decimal64 value into 16-digit BCD</span></div>
<div class="line"> __asm__(</div>
<div class="line"> <span class="stringliteral">"dcffix %1,%2;\n"</span></div>
<div class="line"> <span class="stringliteral">"dcffix %L1,%L2;\n"</span></div>
<div class="line"> <span class="stringliteral">"ddedpd 0,%0,%1;\n"</span></div>
<div class="line"> <span class="stringliteral">"ddedpd 0,%L0,%L1;\n"</span></div>
<div class="line"> : <span class="stringliteral">"=d"</span> (x),</div>
<div class="line"> <span class="stringliteral">"=&d"</span> (y)</div>
<div class="line"> : <span class="stringliteral">"d"</span> (z)</div>
<div class="line"> : );</div>
<div class="line"> <span class="comment">// Pack the FPRp back into a vector</span></div>
<div class="line"> t = (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#ae3ce6a47849278477fe4ea35cff5ca12">vec_pack_Decimal128</a> (x);</div>
<div class="line"> <span class="keywordflow">return</span> (t);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> <span class="comment">// no solution before P6</span></div>
<div class="line"><span class="preprocessor">#endif</span></div>
<div class="line"><span class="preprocessor">}</span></div>
</div><!-- fragment --><p> If we assume that the second Decimal Convert From Fixed (dcffix) is independent and issues 19 cycles after the first, we get 32+19 = 51 cycles to complete. Then another 13+1 cycles to convert back to BCD. Add a few cycles for the unpack and pack operations and we estimate 69 cycles for POWER8 and 58 cycles for POWER9. The totals for <a class="el" href="vec__bcd__ppc_8h.html#aab57aa00d4c2c17bc2eee01b50523a5a" title="Vector Decimal Convert radix 10**32 Binary quadword to pairs of radix 10**16 binary doublewords.">vec_rdxcf10e32q()</a> plus <a class="el" href="vec__bcd__ppc_8h.html#ad4222bd4b90a5248015fbea12cbc0a21" title="Convert vector unsigned doubleword binary values to Vector unsigned 16-digit BCD values.">vec_BIN2BCD()</a> come to 154-164 for POWER8 and 114-124 for POWER9. This is a 30-60% improvement over the previous (all vector) attempt. So the final unsigned binary to BCD conversion looks like this: </p><div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a7b8b5371d537cd878ffb37337e93ba14">vec_bcdcfuq</a> (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> vra)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a> d10e;</div>
<div class="line"> d10e =<a class="code" href="vec__bcd__ppc_8h.html#aab57aa00d4c2c17bc2eee01b50523a5a">vec_rdxcf10e32q</a> (vra);</div>
<div class="line"><span class="preprocessor">#ifdef _ARCH_PWR7</span></div>
<div class="line"> <span class="keywordflow">return</span> (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#ad4222bd4b90a5248015fbea12cbc0a21">vec_BIN2BCD</a> (d10e);</div>
<div class="line"><span class="preprocessor">#else</span></div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aed458e4755a6589049b936cf9f24f6f8">vui8_t</a> d100;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#afb47075b07673afbf78f8c60298f3712">vui16_t</a> d10k;</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#a2ff4a776536870e01b7c9e454586544b">vui32_t</a> d100m;</div>
<div class="line"> d100m = <a class="code" href="vec__bcd__ppc_8h.html#aa1f71d7219b9d4a975c74a84fd55bbda">vec_rdxcf10E16d</a> (d10e);</div>
<div class="line"> d10k = <a class="code" href="vec__bcd__ppc_8h.html#aa356ff16b5b295a8a392ebba48b8a590">vec_rdxcf100mw</a> (d100m);</div>
<div class="line"> d100 = <a class="code" href="vec__bcd__ppc_8h.html#a72f2f0f36250358a499d809c6779432b">vec_rdxcf10kh</a> (d10k);</div>
<div class="line"> <span class="keywordflow">return</span> (<a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a>) <a class="code" href="vec__bcd__ppc_8h.html#a226e0f45eb9c65e388ee86b3b80540e7">vec_rdxcf100b</a> (d10e);</div>
<div class="line"><span class="preprocessor">#endif</span></div>
<div class="line"><span class="preprocessor">}</span></div>
</div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>This process can be extended to 256, 512, 1024-bits, etc by widening the first 5 steps appropriately and adding steps using extended quadword multiply and add operations from <a class="el" href="vec__int128__ppc_8h.html" title="Header package containing a collection of 128-bit computation functions implemented with PowerISA VMX...">vec_int128_ppc.h</a> (<a class="el" href="vec__int128__ppc_8h.html#int128_examples_0_1_3_1">Quadword Long Division</a>).</dd></dl>
<h3><a class="anchor" id="bcd128_convert_0_2_3"></a>
Multiple precision BCD to/from Binary conversion</h3>
<p>The simplest case is converting a vector unsigned __int128 to BCD. This requires up to 39 digits across two vectors. This can either be split into 8 and 31 digits for signed conversion or 7 and 32 for unsigned. Signed conversion is preferred where extended BCD result will be input to additional BCD arithmetic. Unsigned is preferred for conversion to Zoned characters for decimal display.</p>
<p>From <a class="el" href="vec__int128__ppc_8h.html#int128_examples_0_1_2">Converting Vector __int128 values to BCD</a> we see the divide / modulo quadword by constant operations which can used to factor binary quadwords into high and low digit groups for conversion. For example: </p><div class="fragment"><div class="line">q = <a class="code" href="vec__int128__ppc_8h.html#ae2b45341cc9cc918198bb69da0552098">vec_divuq_10e32</a> (a);</div>
<div class="line">r = <a class="code" href="vec__int128__ppc_8h.html#aff4f1d8a707289d2271eafad4aeb1e82">vec_moduq_10e32</a> (a, q);</div>
<div class="line"><span class="comment">// high 7 digits</span></div>
<div class="line">dh = <a class="code" href="vec__bcd__ppc_8h.html#a7b8b5371d537cd878ffb37337e93ba14">vec_bcdcfuq</a> (q);</div>
<div class="line"><span class="comment">// lower 32 digits</span></div>
<div class="line">dl = <a class="code" href="vec__bcd__ppc_8h.html#a7b8b5371d537cd878ffb37337e93ba14">vec_bcdcfuq</a> (r);</div>
<div class="line"> </div>
<div class="line">printf (<span class="stringliteral">"%07lld%016lld%016lld"</span>, (<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) dh[<a class="code" href="vec__common__ppc_8h.html#a9d8b8de825b673b53cd50458dfc6efa8">VEC_DW_L</a>],</div>
<div class="line"> (<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) dl[<a class="code" href="vec__common__ppc_8h.html#adb2bc7bad8fc5c335244ac6f877f3c8f">VEC_DW_H</a>], (<a class="code" href="vec__common__ppc_8h.html#a52a773b6353c69a546bdc2e8686a50ec">vui64_t</a>) dl[<a class="code" href="vec__common__ppc_8h.html#a9d8b8de825b673b53cd50458dfc6efa8">VEC_DW_L</a>]);</div>
</div><!-- fragment --><h4><a class="anchor" id="bcd128_convert_0_2_3_0"></a>
Multiple precision BCD from Binary conversion</h4>
<p>The general multiple precision binary to BCD conversion requires quadword long division as described in <a class="el" href="vec__int128__ppc_8h.html#int128_examples_0_1_3_1">Quadword Long Division</a>. After each long division the remainder is in a range for conversion to BCD. In the example below the remainder is converted to 32 digit BCD as the last step.</p>
<div class="fragment"><div class="line"><span class="comment">// Convert extended quadword binary to BCD 32-digits at a time.</span></div>
<div class="line"><a class="code" href="vec__bcd__ppc_8h.html#a3bf3bca0987b1225b4c33bfdf0c5c532">vBCD_t</a></div>
<div class="line">example_longbcdcf_10e32 (<a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> *q, <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> *d, <span class="keywordtype">long</span> <span class="keywordtype">int</span> _N)</div>
<div class="line">{</div>
<div class="line"> <a class="code" href="vec__common__ppc_8h.html#aaf7a8e92d8ba681dac3d2ec3259c0820">vui128_t</a> dn, qh, ql, rh;</div>
<div class="line"> <span class="keywordtype">long</span> <span class="keywordtype">int</span> i;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// init step for the top digits</span></div>
<div class="line"> dn = d[0];</div>
<div class="line"> qh = <a class="code" href="vec__int128__ppc_8h.html#ae2b45341cc9cc918198bb69da0552098">vec_divuq_10e32</a> (dn);</div>
<div class="line"> rh = <a class="code" href="vec__int128__ppc_8h.html#aff4f1d8a707289d2271eafad4aeb1e82">vec_moduq_10e32</a> (dn, qh);</div>
<div class="line"> q[0] = qh;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// now we know the remainder is less than the divisor.</span></div>
<div class="line"> <span class="keywordflow">for</span> (i=1; i<_N; i++)</div>
<div class="line"> {</div>
<div class="line"> dn = d[i];</div>
<div class="line"> ql = <a class="code" href="vec__int128__ppc_8h.html#a917acd42e775f4bb323ba2104c52d7cb">vec_divudq_10e32</a> (&qh, rh, dn);</div>
<div class="line"> rh = <a class="code" href="vec__int128__ppc_8h.html#a2ccbd77900956c01a51b88e672e593c6">vec_modudq_10e32</a> (rh, dn, &ql);</div>
<div class="line"> q[i] = ql;</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// convert to BCD and return the remainder for this step</span></div>
<div class="line"> <span class="keywordflow">return</span> <a class="code" href="vec__bcd__ppc_8h.html#a7b8b5371d537cd878ffb37337e93ba14">vec_bcdcfuq</a> (rh);</div>
<div class="line">}</div>
</div><!-- fragment --><p> Each call to example_longbcdcf_10e32 () produces the next 32-digit group. Repeated calls where the previous iterations quotient is passed as the dividend to the next step, produce additional 32-digit groups. This continues until the quotient is less then the divisor (in this case 10<sup>32</sup>). This final quadword quotient provides the highest order 32-digit group for the conversion. The digit groups are produced in order from lowest to highest significance.</p>