test_caller_bcd: addg6s sketch
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_bcd.py
1 import itertools
2 import re
3 from nmigen import Module, Signal
4 from nmigen.back.pysim import Simulator, Settle
5 from nmutil.formaltest import FHDLTestCase
6 import unittest
7 from openpower.decoder.isa.caller import ISACaller
8 from openpower.decoder.power_decoder import create_pdecode
9 from openpower.decoder.power_decoder2 import (PowerDecode2)
10 from openpower.simulator.program import Program
11 from openpower.decoder.isa.caller import ISACaller, inject
12 from openpower.decoder.selectable_int import SelectableInt
13 from openpower.decoder.orderedset import OrderedSet
14 from openpower.decoder.isa.all import ISA
15
16
17 # addg6s product limitations
18 ADDG6S_PRODUCT_LIMIT = 16
19
20
21 # PowerISA Version 3.0C Book 1 App. B, Table 129
22 DPD_TO_BCD_TABLE = """
23 0 1 2 3 4 5 6 7 8 9 A B C D E F
24 00_ 000 001 002 003 004 005 006 007 008 009 080 081 800 801 880 881
25 01_ 010 011 012 013 014 015 016 017 018 019 090 091 810 811 890 891
26 02_ 020 021 022 023 024 025 026 027 028 029 082 083 820 821 808 809
27 03_ 030 031 032 033 034 035 036 037 038 039 092 093 830 831 818 819
28 04_ 040 041 042 043 044 045 046 047 048 049 084 085 840 841 088 089
29 05_ 050 051 052 053 054 055 056 057 058 059 094 095 850 851 098 099
30 06_ 060 061 062 063 064 065 066 067 068 069 086 087 860 861 888 889
31 07_ 070 071 072 073 074 075 076 077 078 079 096 097 870 871 898 899
32 08_ 100 101 102 103 104 105 106 107 108 109 180 181 900 901 980 981
33 09_ 110 111 112 113 114 115 116 117 118 119 190 191 910 911 990 991
34 0A_ 120 121 122 123 124 125 126 127 128 129 182 183 920 921 908 909
35 0B_ 130 131 132 133 134 135 136 137 138 139 192 193 930 931 918 919
36 0C_ 140 141 142 143 144 145 146 147 148 149 184 185 940 941 188 189
37 0D_ 150 151 152 153 154 155 156 157 158 159 194 195 950 951 198 199
38 0E_ 160 161 162 163 164 165 166 167 168 169 186 187 960 961 988 989
39 0F_ 170 171 172 173 174 175 176 177 178 179 196 197 970 971 998 999
40 10_ 200 201 202 203 204 205 206 207 208 209 280 281 802 803 882 883
41 11_ 210 211 212 213 214 215 216 217 218 219 290 291 812 813 892 893
42 12_ 220 221 222 223 224 225 226 227 228 229 282 283 822 823 828 829
43 13_ 230 231 232 233 234 235 236 237 238 239 292 293 832 833 838 839
44 14_ 240 241 242 243 244 245 246 247 248 249 284 285 842 843 288 289
45 15_ 250 251 252 253 254 255 256 257 258 259 294 295 852 853 298 299
46 16_ 260 261 262 263 264 265 266 267 268 269 286 287 862 863 (888) (889)
47 17_ 270 271 272 273 274 275 276 277 278 279 296 297 872 873 (898) (899)
48 18_ 300 301 302 303 304 305 306 307 308 309 380 381 902 903 982 983
49 19_ 310 311 312 313 314 315 316 317 318 319 390 391 912 913 992 993
50 1A_ 320 321 322 323 324 325 326 327 328 329 382 383 922 923 928 929
51 1B_ 330 331 332 333 334 335 336 337 338 339 392 393 932 933 938 939
52 1C_ 340 341 342 343 344 345 346 347 348 349 384 385 942 943 388 389
53 1D_ 350 351 352 353 354 355 356 357 358 359 394 395 952 953 398 399
54 1E_ 360 361 362 363 364 365 366 367 368 369 386 387 962 963 (988) (989)
55 1F_ 370 371 372 373 374 375 376 377 378 379 396 397 972 973 (998) (999)
56 20_ 400 401 402 403 404 405 406 407 408 409 480 481 804 805 884 885
57 21_ 410 411 412 413 414 415 416 417 418 419 490 491 814 815 894 895
58 22_ 420 421 422 423 424 425 426 427 428 429 482 483 824 825 848 849
59 23_ 430 431 432 433 434 435 436 437 438 439 492 493 834 835 858 859
60 24_ 440 441 442 443 444 445 446 447 448 449 484 485 844 845 488 489
61 25_ 450 451 452 453 454 455 456 457 458 459 494 495 854 855 498 499
62 26_ 460 461 462 463 464 465 466 467 468 469 486 487 864 865 (888) (889)
63 27_ 470 471 472 473 474 475 476 477 478 479 496 497 874 875 (898) (899)
64 28_ 500 501 502 503 504 505 506 507 508 509 580 581 904 905 984 985
65 29_ 510 511 512 513 514 515 516 517 518 519 590 591 914 915 994 995
66 2A_ 520 521 522 523 524 525 526 527 528 529 582 583 924 925 948 949
67 2B_ 530 531 532 533 534 535 536 537 538 539 592 593 934 935 958 959
68 2C_ 540 541 542 543 544 545 546 547 548 549 584 585 944 945 588 589
69 2D_ 550 551 552 553 554 555 556 557 558 559 594 595 954 955 598 599
70 2E_ 560 561 562 563 564 565 566 567 568 569 586 587 964 965 (988) (989)
71 2F_ 570 571 572 573 574 575 576 577 578 579 596 597 974 975 (998) (999)
72 30_ 600 601 602 603 604 605 606 607 608 609 680 681 806 807 886 887
73 31_ 610 611 612 613 614 615 616 617 618 619 690 691 816 817 896 897
74 32_ 620 621 622 623 624 625 626 627 628 629 682 683 826 827 868 869
75 33_ 630 631 632 633 634 635 636 637 638 639 692 693 836 837 878 879
76 34_ 640 641 642 643 644 645 646 647 648 649 684 685 846 847 688 689
77 35_ 650 651 652 653 654 655 656 657 658 659 694 695 856 857 698 699
78 36_ 660 661 662 663 664 665 666 667 668 669 686 687 866 867 (888) (889)
79 37_ 670 671 672 673 674 675 676 677 678 679 696 697 876 877 (898) (899)
80 38_ 700 701 702 703 704 705 706 707 708 709 780 781 906 907 986 987
81 39_ 710 711 712 713 714 715 716 717 718 719 790 791 916 917 996 997
82 3A_ 720 721 722 723 724 725 726 727 728 729 782 783 926 927 968 969
83 3B_ 730 731 732 733 734 735 736 737 738 739 792 793 936 937 978 979
84 3C_ 740 741 742 743 744 745 746 747 748 749 784 785 946 947 788 789
85 3D_ 750 751 752 753 754 755 756 757 758 759 794 795 956 957 798 799
86 3E_ 760 761 762 763 764 765 766 767 768 769 786 787 966 967 (988) (989)
87 3F_ 770 771 772 773 774 775 776 777 778 779 796 797 976 977 (998) (999)
88 """
89 DPD_TO_BCD_PATTERN = (r"^([0-9A-F]{2})_\s+" +
90 r"\s+".join([r"\(?(\d{3})\)?"] * 16) +
91 r"$")
92 DPD_TO_BCD_REGEX = re.compile(DPD_TO_BCD_PATTERN, re.M)
93
94
95 BCD_TO_DPD_TABLE = """
96 0 1 2 3 4 5 6 7 8 9
97 00_ 000 001 002 003 004 005 006 007 008 009
98 01_ 010 011 012 013 014 015 016 017 018 019
99 02_ 020 021 022 023 024 025 026 027 028 029
100 03_ 030 031 032 033 034 035 036 037 038 039
101 04_ 040 041 042 043 044 045 046 047 048 049
102 05_ 050 051 052 053 054 055 056 057 058 059
103 06_ 060 061 062 063 064 065 066 067 068 069
104 07_ 070 071 072 073 074 075 076 077 078 079
105 08_ 00A 00B 02A 02B 04A 04B 06A 06B 04E 04F
106 09_ 01A 01B 03A 03B 05A 05B 07A 07B 05E 05F
107 10_ 080 081 082 083 084 085 086 087 088 089
108 11_ 090 091 092 093 094 095 096 097 098 099
109 12_ 0A0 0A1 0A2 0A3 0A4 0A5 0A6 0A7 0A8 0A9
110 13_ 0B0 0B1 0B2 0B3 0B4 0B5 0B6 0B7 0B8 0B9
111 14_ 0C0 0C1 0C2 0C3 0C4 0C5 0C6 0C7 0C8 0C9
112 15_ 0D0 0D1 0D2 0D3 0D4 0D5 0D6 0D7 0D8 0D9
113 16_ 0E0 0E1 0E2 0E3 0E4 0E5 0E6 0E7 0E8 0E9
114 17_ 0F0 0F1 0F2 0F3 0F4 0F5 0F6 0F7 0F8 0F9
115 18_ 08A 08B 0AA 0AB 0CA 0CB 0EA 0EB 0CE 0CF
116 19_ 09A 09B 0BA 0BB 0DA 0DB 0FA 0FB 0DE 0DF
117 20_ 100 101 102 103 104 105 106 107 108 109
118 21_ 110 111 112 113 114 115 116 117 118 119
119 22_ 120 121 122 123 124 125 126 127 128 129
120 23_ 130 131 132 133 134 135 136 137 138 139
121 24_ 140 141 142 143 144 145 146 147 148 149
122 25_ 150 151 152 153 154 155 156 157 158 159
123 26_ 160 161 162 163 164 165 166 167 168 169
124 27_ 170 171 172 173 174 175 176 177 178 179
125 28_ 10A 10B 12A 12B 14A 14B 16A 16B 14E 14F
126 29_ 11A 11B 13A 13B 15A 15B 17A 17B 15E 15F
127 30_ 180 181 182 183 184 185 186 187 188 189
128 31_ 190 191 192 193 194 195 196 197 198 199
129 32_ 1A0 1A1 1A2 1A3 1A4 1A5 1A6 1A7 1A8 1A9
130 33_ 1B0 1B1 1B2 1B3 1B4 1B5 1B6 1B7 1B8 1B9
131 34_ 1C0 1C1 1C2 1C3 1C4 1C5 1C6 1C7 1C8 1C9
132 35_ 1D0 1D1 1D2 1D3 1D4 1D5 1D6 1D7 1D8 1D9
133 36_ 1E0 1E1 1E2 1E3 1E4 1E5 1E6 1E7 1E8 1E9
134 37_ 1F0 1F1 1F2 1F3 1F4 1F5 1F6 1F7 1F8 1F9
135 38_ 18A 18B 1AA 1AB 1CA 1CB 1EA 1EB 1CE 1CF
136 39_ 19A 19B 1BA 1BB 1DA 1DB 1FA 1FB 1DE 1DF
137 40_ 200 201 202 203 204 205 206 207 208 209
138 41_ 210 211 212 213 214 215 216 217 218 219
139 42_ 220 221 222 223 224 225 226 227 228 229
140 43_ 230 231 232 233 234 235 236 237 238 239
141 44_ 240 241 242 243 244 245 246 247 248 249
142 45_ 250 251 252 253 254 255 256 257 258 259
143 46_ 260 261 262 263 264 265 266 267 268 269
144 47_ 270 271 272 273 274 275 276 277 278 279
145 48_ 20A 20B 22A 22B 24A 24B 26A 26B 24E 24F
146 49_ 21A 21B 23A 23B 25A 25B 27A 27B 25E 25F
147 50_ 280 281 282 283 284 285 286 287 288 289
148 51_ 290 291 292 293 294 295 296 297 298 299
149 52_ 2A0 2A1 2A2 2A3 2A4 2A5 2A6 2A7 2A8 2A9
150 53_ 2B0 2B1 2B2 2B3 2B4 2B5 2B6 2B7 2B8 2B9
151 54_ 2C0 2C1 2C2 2C3 2C4 2C5 2C6 2C7 2C8 2C9
152 55_ 2D0 2D1 2D2 2D3 2D4 2D5 2D6 2D7 2D8 2D9
153 56_ 2E0 2E1 2E2 2E3 2E4 2E5 2E6 2E7 2E8 2E9
154 57_ 2F0 2F1 2F2 2F3 2F4 2F5 2F6 2F7 2F8 2F9
155 58_ 28A 28B 2AA 2AB 2CA 2CB 2EA 2EB 2CE 2CF
156 59_ 29A 29B 2BA 2BB 2DA 2DB 2FA 2FB 2DE 2DF
157 60_ 300 301 302 303 304 305 306 307 308 309
158 61_ 310 311 312 313 314 315 316 317 318 319
159 62_ 320 321 322 323 324 325 326 327 328 329
160 63_ 330 331 332 333 334 335 336 337 338 339
161 64_ 340 341 342 343 344 345 346 347 348 349
162 65_ 350 351 352 353 354 355 356 357 358 359
163 66_ 360 361 362 363 364 365 366 367 368 369
164 67_ 370 371 372 373 374 375 376 377 378 379
165 68_ 30A 30B 32A 32B 34A 34B 36A 36B 34E 34F
166 69_ 31A 31B 33A 33B 35A 35B 37A 37B 35E 35F
167 70_ 380 381 382 383 384 385 386 387 388 389
168 71_ 390 391 392 393 394 395 396 397 398 399
169 72_ 3A0 3A1 3A2 3A3 3A4 3A5 3A6 3A7 3A8 3A9
170 73_ 3B0 3B1 3B2 3B3 3B4 3B5 3B6 3B7 3B8 3B9
171 74_ 3C0 3C1 3C2 3C3 3C4 3C5 3C6 3C7 3C8 3C9
172 75_ 3D0 3D1 3D2 3D3 3D4 3D5 3D6 3D7 3D8 3D9
173 76_ 3E0 3E1 3E2 3E3 3E4 3E5 3E6 3E7 3E8 3E9
174 77_ 3F0 3F1 3F2 3F3 3F4 3F5 3F6 3F7 3F8 3F9
175 78_ 38A 38B 3AA 3AB 3CA 3CB 3EA 3EB 3CE 3CF
176 79_ 39A 39B 3BA 3BB 3DA 3DB 3FA 3FB 3DE 3DF
177 80_ 00C 00D 10C 10D 20C 20D 30C 30D 02E 02F
178 81_ 01C 01D 11C 11D 21C 21D 31C 31D 03E 03F
179 82_ 02C 02D 12C 12D 22C 22D 32C 32D 12E 12F
180 83_ 03C 03D 13C 13D 23C 23D 33C 33D 13E 13F
181 84_ 04C 04D 14C 14D 24C 24D 34C 34D 22E 22F
182 85_ 05C 05D 15C 15D 25C 25D 35C 35D 23E 23F
183 86_ 06C 06D 16C 16D 26C 26D 36C 36D 32E 32F
184 87_ 07C 07D 17C 17D 27C 27D 37C 37D 33E 33F
185 88_ 00E 00F 10E 10F 20E 20F 30E 30F 06E 06F
186 89_ 01E 01F 11E 11F 21E 21F 31E 31F 07E 07F
187 90_ 08C 08D 18C 18D 28C 28D 38C 38D 0AE 0AF
188 91_ 09C 09D 19C 19D 29C 29D 39C 39D 0BE 0BF
189 92_ 0AC 0AD 1AC 1AD 2AC 2AD 3AC 3AD 1AE 1AF
190 93_ 0BC 0BD 1BC 1BD 2BC 2BD 3BC 3BD 1BE 1BF
191 94_ 0CC 0CD 1CC 1CD 2CC 2CD 3CC 3CD 2AE 2AF
192 95_ 0DC 0DD 1DC 1DD 2DC 2DD 3DC 3DD 2BE 2BF
193 96_ 0EC 0ED 1EC 1ED 2EC 2ED 3EC 3ED 3AE 3AF
194 97_ 0FC 0FD 1FC 1FD 2FC 2FD 3FC 3FD 3BE 3BF
195 98_ 08E 08F 18E 18F 28E 28F 38E 38F 0EE 0EF
196 99_ 09E 09F 19E 19F 29E 29F 39E 39F 0FE 0FF
197 """
198 BCD_TO_DPD_PATTERN = (r"^(\d{2})_\s" +
199 r"\s".join([r"([0-9A-F]{3})"] * 10) +
200 r"$")
201 BCD_TO_DPD_REGEX = re.compile(BCD_TO_DPD_PATTERN, re.M)
202
203
204 def run_tst(generator, initial_regs, initial_sprs=None, svstate=0, mmu=False,
205 initial_cr=0, mem=None,
206 initial_fprs=None,
207 pdecode2=None):
208 if initial_sprs is None:
209 initial_sprs = {}
210 m = Module()
211 comb = m.d.comb
212 instruction = Signal(32)
213
214 if pdecode2 is None:
215 pdecode = create_pdecode(include_fp=initial_fprs is not None)
216 pdecode2 = PowerDecode2(pdecode)
217
218 gen = list(generator.generate_instructions())
219 insncode = generator.assembly.splitlines()
220 instructions = list(zip(gen, insncode))
221
222 m.submodules.pdecode2 = pdecode2
223 simulator = ISA(pdecode2, initial_regs, initial_sprs, initial_cr,
224 initial_insns=gen, respect_pc=True,
225 initial_svstate=svstate,
226 initial_mem=mem,
227 fpregfile=initial_fprs,
228 disassembly=insncode,
229 bigendian=0,
230 mmu=mmu)
231 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
232 sim = Simulator(m)
233
234 def process():
235
236 print ("GPRs")
237 simulator.gpr.dump()
238 print ("FPRs")
239 simulator.fpr.dump()
240
241 yield pdecode2.dec.bigendian.eq(0) # little / big?
242 pc = simulator.pc.CIA.value
243 index = pc//4
244 while index < len(instructions):
245 print("instr pc", pc)
246 try:
247 yield from simulator.setup_one()
248 except KeyError: # indicates instruction not in imem: stop
249 break
250 yield Settle()
251
252 ins, code = instructions[index]
253 print(" 0x{:X}".format(ins & 0xffffffff))
254 opname = code.split(' ')[0]
255 print(code, opname)
256
257 # ask the decoder to decode this binary data (endian'd)
258 yield from simulator.execute_one()
259 pc = simulator.pc.CIA.value
260 index = pc//4
261
262 sim.add_process(process)
263 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
264 traces=[]):
265 sim.run()
266 return simulator
267
268
269 def testgen(mapping):
270 zeros = [0] * 32
271 length = len(mapping)
272 iregs_whole = list(mapping.keys())
273 oregs_whole = list(mapping.values())
274 for base in range(0, length, 32):
275 iregs = (iregs_whole[base:base + 32] + zeros)[:32]
276 oregs = (oregs_whole[base:base + 32] + zeros)[:32]
277 yield (iregs, oregs)
278
279
280 class BCDTestCase(FHDLTestCase):
281 def __init__(self, *args, **kwargs):
282 super().__init__(*args, **kwargs)
283 pdecode = create_pdecode(include_fp=True)
284 self.pdecode2 = PowerDecode2(pdecode)
285
286 def run_tst(self, instr, mapping):
287 lst = [f"{instr} {reg}, {reg}" for reg in range(32)]
288 for (iregs, oregs) in testgen(mapping):
289 with self.subTest():
290 with Program(lst, bigendian=False) as program:
291 sim = self.run_tst_program(program, iregs)
292 gprs = [sim.gpr(gpr) for gpr in range(32)]
293 for gpr in range(32):
294 self.assertEqual(sim.gpr(gpr),
295 SelectableInt(oregs[gpr], 64))
296
297 def test_cdtbcd(self):
298 mapping = {}
299 for match in DPD_TO_BCD_REGEX.findall(DPD_TO_BCD_TABLE):
300 for digit in range(0x10):
301 dpd = int((match[0] + f"{digit:X}"), 16)
302 bcd = ((int(match[1 + digit][0]) << 8) |
303 (int(match[1 + digit][1]) << 4) |
304 (int(match[1 + digit][2]) << 0))
305 mapping[dpd] = bcd
306 self.run_tst("cdtbcd", mapping)
307
308 def test_cbcdtd(self):
309 mapping = {}
310 for match in BCD_TO_DPD_REGEX.findall(BCD_TO_DPD_TABLE):
311 for digit in range(10):
312 bcd = ((int(match[0][0]) << 8) |
313 (int(match[0][1]) << 4) |
314 (int(digit) << 0))
315 dpd = int(match[1 + digit], 16)
316 mapping[bcd] = dpd
317 self.run_tst("cbcdtd", mapping)
318
319 def test_addg6s(self):
320 def half_adder(a, b):
321 (a, b) = map(bool, [a, b])
322 carry = a & b
323 sum = a ^ b
324 return (int(sum), int(carry))
325
326 def full_adder(a, b, c):
327 (a, b, c) = map(bool, [a, b, c])
328 (sum0, carry0) = half_adder(a, b)
329 (sum, carry1) = half_adder(sum0, c)
330 carry = (carry0 | carry1)
331 return (int(sum), int(carry))
332
333 def full_adder64(a, b):
334 sum = [0] * 64
335 carry = [0] * 64
336 (sum[0], carry[0]) = half_adder(a[0], b[0])
337 for bit in range(1, 64, 1):
338 (sum[bit], carry[bit]) = full_adder(a[bit], b[bit], carry[bit - 1])
339 return (sum + [carry[63]])
340
341 def addg6s(a, b):
342 BIT = lambda value, bit: int(bool((value >> bit) & 1))
343 a = list(reversed(list(map(lambda bit: BIT(a, bit), range(63, -1, -1)))))
344 b = list(reversed(list(map(lambda bit: BIT(b, bit), range(63, -1, -1)))))
345 sum = full_adder64(a, b)
346
347 a_in = lambda bit: a[bit]
348 b_in = lambda bit: b[bit]
349 sum_with_carry = lambda bit: sum[bit]
350
351 addg6s = [0] * 64
352 for i in range(15):
353 lo = i * 4
354 hi = (i + 1) * 4
355 if (a_in(hi) ^ b_in(hi) ^ (sum_with_carry(hi) == 0)):
356 addg6s[lo + 3] = 0
357 addg6s[lo + 2] = 1
358 addg6s[lo + 1] = 1
359 addg6s[lo + 0] = 0
360 if sum_with_carry(64) == 0:
361 addg6s[63] = 0
362 addg6s[62] = 1
363 addg6s[61] = 1
364 addg6s[60] = 0
365 return int("".join(map(str, reversed(addg6s))), 2)
366
367 cond = lambda item: item[0] < ADDG6S_PRODUCT_LIMIT
368 bcd = map(lambda digit: f"{digit:04b}", range(10))
369 product = enumerate(itertools.product(bcd, repeat=16))
370 sequences = (seq for (_, seq) in itertools.takewhile(cond, product))
371 numbers = [int("".join(seq), 2) for seq in sequences]
372 iregs = [0] * 32
373 for a in numbers:
374 for b in numbers:
375 rv = addg6s(a, b)
376 with self.subTest():
377 iregs[2] = b
378 iregs[1] = a
379 lst = ["addg6s 0, 1, 2"]
380 with Program(lst, bigendian=False) as program:
381 sim = self.run_tst_program(program, iregs)
382 self.assertEqual(sim.gpr(0), SelectableInt(rv, 64))
383
384 def run_tst_program(self, prog, initial_regs=[0] * 32):
385 simulator = run_tst(prog, initial_regs, pdecode2=self.pdecode2)
386 simulator.gpr.dump()
387 return simulator
388
389
390 if __name__ == "__main__":
391 unittest.main()