https://bugs.libre-soc.org/show_bug.cgi?id=985
[libreriscv.git] / openpower / isa / fixedarith.mdwn
1 <!-- X Instructions here described in PowerISA Version 3.0 B Book 1 -->
2
3 <!-- Section 3.3.9 Fixed-point arithmetic instructions. Pages 67 - 83 -->
4
5 # Add Immediate
6
7 D-Form
8
9 * addi RT,RA,SI
10
11 Pseudo-code:
12
13 RT <- (RA|0) + EXTS(SI)
14
15 Special Registers Altered:
16
17 None
18
19 # Add Immediate Shifted
20
21 D-Form
22
23 * addis RT,RA,SI
24
25 Pseudo-code:
26
27 RT <- (RA|0) + EXTS(SI || [0]*16)
28
29 Special Registers Altered:
30
31 None
32
33 # Add PC Immediate Shifted
34
35 DX-Form
36
37 * addpcis RT,D
38
39 Pseudo-code:
40
41 D <- d0||d1||d2
42 RT <- NIA + EXTS(D || [0]*16)
43
44 Special Registers Altered:
45
46 None
47
48 # Add
49
50 XO-Form
51
52 * add RT,RA,RB (OE=0 Rc=0)
53 * add. RT,RA,RB (OE=0 Rc=1)
54 * addo RT,RA,RB (OE=1 Rc=0)
55 * addo. RT,RA,RB (OE=1 Rc=1)
56
57 Pseudo-code:
58
59 RT <- (RA) + (RB)
60
61 Special Registers Altered:
62
63 CR0 (if Rc=1)
64 SO OV OV32 (if OE=1)
65
66 # Subtract From
67
68 XO-Form
69
70 * subf RT,RA,RB (OE=0 Rc=0)
71 * subf. RT,RA,RB (OE=0 Rc=1)
72 * subfo RT,RA,RB (OE=1 Rc=0)
73 * subfo. RT,RA,RB (OE=1 Rc=1)
74
75 Pseudo-code:
76
77 RT <- ¬(RA) + (RB) + 1
78
79 Special Registers Altered:
80
81 CR0 (if Rc=1)
82 SO OV OV32 (if OE=1)
83
84 # Add Immediate Carrying
85
86 D-Form
87
88 * addic RT,RA,SI
89
90 Pseudo-code:
91
92 RT <- (RA) + EXTS(SI)
93
94 Special Registers Altered:
95
96 CA CA32
97
98 # Add Immediate Carrying and Record
99
100 D-Form
101
102 * addic. RT,RA,SI
103
104 Pseudo-code:
105
106 RT <- (RA) + EXTS(SI)
107
108 Special Registers Altered:
109
110 CR0 CA CA32
111
112 # Subtract From Immediate Carrying
113
114 D-Form
115
116 * subfic RT,RA,SI
117
118 Pseudo-code:
119
120 RT <- ¬(RA) + EXTS(SI) + 1
121
122 Special Registers Altered:
123
124 CA CA32
125
126 # Add Carrying
127
128 XO-Form
129
130 * addc RT,RA,RB (OE=0 Rc=0)
131 * addc. RT,RA,RB (OE=0 Rc=1)
132 * addco RT,RA,RB (OE=1 Rc=0)
133 * addco. RT,RA,RB (OE=1 Rc=1)
134
135 Pseudo-code:
136
137 RT <- (RA) + (RB)
138
139 Special Registers Altered:
140
141 CA CA32
142 CR0 (if Rc=1)
143 SO OV OV32 (if OE=1)
144
145 # Subtract From Carrying
146
147 XO-Form
148
149 * subfc RT,RA,RB (OE=0 Rc=0)
150 * subfc. RT,RA,RB (OE=0 Rc=1)
151 * subfco RT,RA,RB (OE=1 Rc=0)
152 * subfco. RT,RA,RB (OE=1 Rc=1)
153
154 Pseudo-code:
155
156 RT <- ¬(RA) + (RB) + 1
157
158 Special Registers Altered:
159
160 CA CA32
161 CR0 (if Rc=1)
162 SO OV OV32 (if OE=1)
163
164 # Add Extended
165
166 XO-Form
167
168 * adde RT,RA,RB (OE=0 Rc=0)
169 * adde. RT,RA,RB (OE=0 Rc=1)
170 * addeo RT,RA,RB (OE=1 Rc=0)
171 * addeo. RT,RA,RB (OE=1 Rc=1)
172
173 Pseudo-code:
174
175 RT <- (RA) + (RB) + CA
176
177 Special Registers Altered:
178
179 CA CA32
180 CR0 (if Rc=1)
181 SO OV OV32 (if OE=1)
182
183 # Subtract From Extended
184
185 XO-Form
186
187 * subfe RT,RA,RB (OE=0 Rc=0)
188 * subfe. RT,RA,RB (OE=0 Rc=1)
189 * subfeo RT,RA,RB (OE=1 Rc=0)
190 * subfeo. RT,RA,RB (OE=1 Rc=1)
191
192 Pseudo-code:
193
194 RT <- ¬(RA) + (RB) + CA
195
196 Special Registers Altered:
197
198 CA CA32
199 CR0 (if Rc=1)
200 SO OV OV32 (if OE=1)
201
202 # Add to Minus One Extended
203
204 XO-Form
205
206 * addme RT,RA (OE=0 Rc=0)
207 * addme. RT,RA (OE=0 Rc=1)
208 * addmeo RT,RA (OE=1 Rc=0)
209 * addmeo. RT,RA (OE=1 Rc=1)
210
211 Pseudo-code:
212
213 RT <- (RA) + CA - 1
214
215 Special Registers Altered:
216
217 CA CA32
218 CR0 (if Rc=1)
219 SO OV OV32 (if OE=1)
220
221 # Subtract From Minus One Extended
222
223 XO-Form
224
225 * subfme RT,RA (OE=0 Rc=0)
226 * subfme. RT,RA (OE=0 Rc=1)
227 * subfmeo RT,RA (OE=1 Rc=0)
228 * subfmeo. RT,RA (OE=1 Rc=1)
229
230 Pseudo-code:
231
232 RT <- ¬(RA) + CA - 1
233
234 Special Registers Altered:
235
236 CA CA32
237 CR0 (if Rc=1)
238 SO OV OV32 (if OE=1)
239
240 # Add Extended using alternate carry bit
241
242 Z23-Form
243
244 * addex RT,RA,RB,CY
245
246 Pseudo-code:
247
248 if CY=0 then RT <- (RA) + (RB) + OV
249
250 Special Registers Altered:
251
252 OV OV32 (if CY=0 )
253
254 # Subtract From Zero Extended
255
256 XO-Form
257
258 * subfze RT,RA (OE=0 Rc=0)
259 * subfze. RT,RA (OE=0 Rc=1)
260 * subfzeo RT,RA (OE=1 Rc=0)
261 * subfzeo. RT,RA (OE=1 Rc=1)
262
263 Pseudo-code:
264
265 RT <- ¬(RA) + CA
266
267 Special Registers Altered:
268
269 CA CA32
270 CR0 (if Rc=1)
271 SO OV OV32 (if OE=1)
272
273 # Add to Zero Extended
274
275 XO-Form
276
277 * addze RT,RA (OE=0 Rc=0)
278 * addze. RT,RA (OE=0 Rc=1)
279 * addzeo RT,RA (OE=1 Rc=0)
280 * addzeo. RT,RA (OE=1 Rc=1)
281
282 Pseudo-code:
283
284 RT <- (RA) + CA
285
286 Special Registers Altered:
287
288 CA CA32
289 CR0 (if Rc=1)
290 SO OV OV32 (if OE=1)
291
292 # Negate
293
294 XO-Form
295
296 * neg RT,RA (OE=0 Rc=0)
297 * neg. RT,RA (OE=0 Rc=1)
298 * nego RT,RA (OE=1 Rc=0)
299 * nego. RT,RA (OE=1 Rc=1)
300
301 Pseudo-code:
302
303 RT <- ¬(RA) + 1
304
305 Special Registers Altered:
306
307 CR0 (if Rc=1)
308 SO OV OV32 (if OE=1)
309
310 # Multiply Low Immediate
311
312 D-Form
313
314 * mulli RT,RA,SI
315
316 Pseudo-code:
317
318 prod[0:127] <- MULS((RA), EXTS(SI))
319 RT <- prod[64:127]
320
321 Special Registers Altered:
322
323 None
324
325 # Multiply High Word
326
327 XO-Form
328
329 * mulhw RT,RA,RB (Rc=0)
330 * mulhw. RT,RA,RB (Rc=1)
331
332 Pseudo-code:
333
334 prod[0:63] <- MULS((RA)[32:63], (RB)[32:63])
335 RT[32:63] <- prod[0:31]
336 RT[0:31] <- undefined(prod[0:31])
337
338 Special Registers Altered:
339
340 CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
341
342 # Multiply Low Word
343
344 XO-Form
345
346 * mullw RT,RA,RB (OE=0 Rc=0)
347 * mullw. RT,RA,RB (OE=0 Rc=1)
348 * mullwo RT,RA,RB (OE=1 Rc=0)
349 * mullwo. RT,RA,RB (OE=1 Rc=1)
350
351 Pseudo-code:
352
353 prod[0:63] <- MULS((RA)[32:63], (RB)[32:63])
354 RT <- prod
355 overflow <- ((prod[0:32] != [0]*33) &
356 (prod[0:32] != [1]*33))
357
358 Special Registers Altered:
359
360 CR0 (if Rc=1)
361 SO OV OV32 (if OE=1)
362
363 # Multiply High Word Unsigned
364
365 XO-Form
366
367 * mulhwu RT,RA,RB (Rc=0)
368 * mulhwu. RT,RA,RB (Rc=1)
369
370 Pseudo-code:
371
372 prod[0:63] <- (RA)[32:63] * (RB)[32:63]
373 RT[32:63] <- prod[0:31]
374 RT[0:31] <- undefined(prod[0:31])
375
376 Special Registers Altered:
377
378 CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
379
380 # Divide Word
381
382 XO-Form
383
384 * divw RT,RA,RB (OE=0 Rc=0)
385 * divw. RT,RA,RB (OE=0 Rc=1)
386 * divwo RT,RA,RB (OE=1 Rc=0)
387 * divwo. RT,RA,RB (OE=1 Rc=1)
388
389 Pseudo-code:
390
391 dividend[0:31] <- (RA)[32:63]
392 divisor[0:31] <- (RB) [32:63]
393 if (((dividend = 0x8000_0000) &
394 (divisor = [1]*32)) |
395 (divisor = [0]*32)) then
396 RT[0:63] <- undefined([0]*64)
397 overflow <- 1
398 else
399 RT[32:63] <- DIVS(dividend, divisor)
400 RT[0:31] <- undefined([0]*32)
401 overflow <- 0
402
403 Special Registers Altered:
404
405 CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
406 SO OV OV32 (if OE=1)
407
408 # Divide Word Unsigned
409
410 XO-Form
411
412 * divwu RT,RA,RB (OE=0 Rc=0)
413 * divwu. RT,RA,RB (OE=0 Rc=1)
414 * divwuo RT,RA,RB (OE=1 Rc=0)
415 * divwuo. RT,RA,RB (OE=1 Rc=1)
416
417 Pseudo-code:
418
419 dividend[0:31] <- (RA)[32:63]
420 divisor[0:31] <- (RB)[32:63]
421 if divisor != 0 then
422 RT[32:63] <- dividend / divisor
423 RT[0:31] <- undefined([0]*32)
424 overflow <- 0
425 else
426 RT[0:63] <- undefined([0]*64)
427 overflow <- 1
428
429 Special Registers Altered:
430
431 CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
432 SO OV OV32 (if OE=1)
433
434 # Divide Word Extended
435
436 XO-Form
437
438 * divwe RT,RA,RB (OE=0 Rc=0)
439 * divwe. RT,RA,RB (OE=0 Rc=1)
440 * divweo RT,RA,RB (OE=1 Rc=0)
441 * divweo. RT,RA,RB (OE=1 Rc=1)
442
443 Pseudo-code:
444
445 dividend[0:63] <- (RA)[32:63] || [0]*32
446 divisor[0:63] <- EXTS64((RB)[32:63])
447 if (((dividend = 0x8000_0000_0000_0000) &
448 (divisor = [1]*64)) |
449 (divisor = [0]*64)) then
450 overflow <- 1
451 else
452 result <- DIVS(dividend, divisor)
453 result32[0:63] <- EXTS64(result[32:63])
454 if (result32 = result) then
455 RT[32:63] <- result[32:63]
456 RT[0:31] <- undefined([0]*32)
457 overflow <- 0
458 else
459 overflow <- 1
460 if overflow = 1 then
461 RT[0:63] <- undefined([0]*64)
462
463 Special Registers Altered:
464
465 CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
466 SO OV OV32 (if OE=1)
467
468 # Divide Word Extended Unsigned
469
470 XO-Form
471
472 * divweu RT,RA,RB (OE=0 Rc=0)
473 * divweu. RT,RA,RB (OE=0 Rc=1)
474 * divweuo RT,RA,RB (OE=1 Rc=0)
475 * divweuo. RT,RA,RB (OE=1 Rc=1)
476
477 Pseudo-code:
478
479 dividend[0:63] <- (RA)[32:63] || [0]*32
480 divisor[0:63] <- [0]*32 || (RB)[32:63]
481 if (divisor = [0]*64) then
482 overflow <- 1
483 else
484 result <- dividend / divisor
485 if RA[32:63] <u RB[32:63] then
486 RT[32:63] <- result[32:63]
487 RT[0:31] <- undefined([0]*32)
488 overflow <- 0
489 else
490 overflow <- 1
491 if overflow = 1 then
492 RT[0:63] <- undefined([0]*64)
493
494 Special Registers Altered:
495
496 CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
497 SO OV OV32 (if OE=1)
498
499 # Modulo Signed Word
500
501 X-Form
502
503 * modsw RT,RA,RB
504
505 Pseudo-code:
506
507 dividend[0:31] <- (RA)[32:63]
508 divisor[0:31] <- (RB)[32:63]
509 if (((dividend = 0x8000_0000) &
510 (divisor = [1]*32)) |
511 (divisor = [0]*32)) then
512 RT[0:63] <- undefined([0]*64)
513 overflow <- 1
514 else
515 RT[0:63] <- EXTS64(MODS(dividend, divisor))
516 RT[0:31] <- undefined(RT[0:31])
517 overflow <- 0
518
519 Special Registers Altered:
520
521 None
522
523 # Modulo Unsigned Word
524
525 X-Form
526
527 * moduw RT,RA,RB
528
529 Pseudo-code:
530
531 dividend[0:31] <- (RA) [32:63]
532 divisor [0:31] <- (RB) [32:63]
533 if divisor = [0]*32 then
534 RT[0:63] <- undefined([0]*64)
535 overflow <- 1
536 else
537 RT[32:63] <- dividend % divisor
538 RT[0:31] <- undefined([0]*32)
539 overflow <- 0
540
541 Special Registers Altered:
542
543 None
544
545 # Deliver A Random Number
546
547 X-Form
548
549 * darn RT,L3
550
551 Pseudo-code:
552
553 RT <- random(L3)
554
555 Special Registers Altered:
556
557 none
558
559 # Multiply Low Doubleword
560
561 XO-Form
562
563 * mulld RT,RA,RB (OE=0 Rc=0)
564 * mulld. RT,RA,RB (OE=0 Rc=1)
565 * mulldo RT,RA,RB (OE=1 Rc=0)
566 * mulldo. RT,RA,RB (OE=1 Rc=1)
567
568 Pseudo-code:
569
570 prod[0:127] <- MULS((RA), (RB))
571 RT <- prod[64:127]
572 overflow <- ((prod[0:64] != [0]*65) &
573 (prod[0:64] != [1]*65))
574
575 Special Registers Altered:
576
577 CR0 (if Rc=1)
578 SO OV OV32 (if OE=1)
579
580 # Multiply High Doubleword
581
582 XO-Form
583
584 * mulhd RT,RA,RB (Rc=0)
585 * mulhd. RT,RA,RB (Rc=1)
586
587 Pseudo-code:
588
589 prod[0:127] <- MULS((RA), (RB))
590 RT <- prod[0:63]
591
592 Special Registers Altered:
593
594 CR0 (if Rc=1)
595
596 # Multiply High Doubleword Unsigned
597
598 XO-Form
599
600 * mulhdu RT,RA,RB (Rc=0)
601 * mulhdu. RT,RA,RB (Rc=1)
602
603 Pseudo-code:
604
605 prod[0:127] <- (RA) * (RB)
606 RT <- prod[0:63]
607
608 Special Registers Altered:
609
610 CR0 (if Rc=1)
611
612 # Multiply-Add High Doubleword VA-Form
613
614 VA-Form
615
616 * maddhd RT,RA.RB,RC
617
618 Pseudo-code:
619
620 prod[0:127] <- MULS((RA), (RB))
621 sum[0:127] <- prod + EXTS(RC)
622 RT <- sum[0:63]
623
624 Special Registers Altered:
625
626 None
627
628 # Multiply-Add High Doubleword Unsigned
629
630 VA-Form
631
632 * maddhdu RT,RA.RB,RC
633
634 Pseudo-code:
635
636 prod[0:127] <- (RA) * (RB)
637 sum[0:127] <- prod + EXTZ(RC)
638 RT <- sum[0:63]
639
640 Special Registers Altered:
641
642 None
643
644 # Multiply-Add Low Doubleword
645
646 VA-Form
647
648 * maddld RT,RA.RB,RC
649
650 Pseudo-code:
651
652 prod[0:127] <- MULS((RA), (RB))
653 sum[0:127] <- prod + EXTS(RC)
654 RT <- sum[64:127]
655
656 Special Registers Altered:
657
658 None
659
660 # Divide Doubleword
661
662 XO-Form
663
664 * divd RT,RA,RB (OE=0 Rc=0)
665 * divd. RT,RA,RB (OE=0 Rc=1)
666 * divdo RT,RA,RB (OE=1 Rc=0)
667 * divdo. RT,RA,RB (OE=1 Rc=1)
668
669 Pseudo-code:
670
671 dividend[0:63] <- (RA)
672 divisor[0:63] <- (RB)
673 if (((dividend = 0x8000_0000_0000_0000) &
674 (divisor = [1]*64)) |
675 (divisor = [0]*64)) then
676 RT[0:63] <- undefined([0]*64)
677 overflow <- 1
678 else
679 RT <- DIVS(dividend, divisor)
680 overflow <- 0
681
682 Special Registers Altered:
683
684 CR0 (if Rc=1)
685 SO OV OV32 (if OE=1)
686
687 # Divide Doubleword Unsigned
688
689 XO-Form
690
691 * divdu RT,RA,RB (OE=0 Rc=0)
692 * divdu. RT,RA,RB (OE=0 Rc=1)
693 * divduo RT,RA,RB (OE=1 Rc=0)
694 * divduo. RT,RA,RB (OE=1 Rc=1)
695
696 Pseudo-code:
697
698 dividend[0:63] <- (RA)
699 divisor[0:63] <- (RB)
700 if (divisor = [0]*64) then
701 RT[0:63] <- undefined([0]*64)
702 overflow <- 1
703 else
704 RT <- dividend / divisor
705 overflow <- 0
706
707 Special Registers Altered:
708
709 CR0 (if Rc=1)
710 SO OV OV32 (if OE=1)
711
712 # Divide Doubleword Extended
713
714 XO-Form
715
716 * divde RT,RA,RB (OE=0 Rc=0)
717 * divde. RT,RA,RB (OE=0 Rc=1)
718 * divdeo RT,RA,RB (OE=1 Rc=0)
719 * divdeo. RT,RA,RB (OE=1 Rc=1)
720
721 Pseudo-code:
722
723 dividend[0:127] <- (RA) || [0]*64
724 divisor[0:127] <- EXTS128((RB))
725 if (((dividend = 0x8000_0000_0000_0000_0000_0000_0000_0000) &
726 (divisor = [1]*128)) |
727 (divisor = [0]*128)) then
728 overflow <- 1
729 else
730 result <- DIVS(dividend, divisor)
731 result64[0:127] <- EXTS128(result[64:127])
732 if (result64 = result) then
733 RT <- result[64:127]
734 overflow <- 0
735 else
736 overflow <- 1
737 if overflow = 1 then
738 RT[0:63] <- undefined([0]*64)
739
740 Special Registers Altered:
741
742 CR0 (if Rc=1)
743 SO OV OV32 (if OE=1)
744
745 # Divide Doubleword Extended Unsigned
746
747 XO-Form
748
749 * divdeu RT,RA,RB (OE=0 Rc=0)
750 * divdeu. RT,RA,RB (OE=0 Rc=1)
751 * divdeuo RT,RA,RB (OE=1 Rc=0)
752 * divdeuo. RT,RA,RB (OE=1 Rc=1)
753
754 Pseudo-code:
755
756 dividend[0:127] <- (RA) || [0]*64
757 divisor[0:127] <- [0]*64 || (RB)
758 if divisor = [0]*128 then
759 overflow <- 1
760 else
761 result <- dividend / divisor
762 if (RA) <u (RB) then
763 RT <- result[64:127]
764 overflow <- 0
765 else
766 overflow <- 1
767 if overflow = 1 then
768 RT[0:63] <- undefined([0]*64)
769
770 Special Registers Altered:
771
772 CR0 (if Rc=1)
773 SO OV OV32 (if OE=1)
774
775 # Modulo Signed Doubleword
776
777 X-Form
778
779 * modsd RT,RA,RB
780
781 Pseudo-code:
782
783 dividend <- (RA)
784 divisor <- (RB)
785 if (((dividend = 0x8000_0000_0000_0000) &
786 (divisor = [1]*64)) |
787 (divisor = [0]*64)) then
788 RT[0:63] <- undefined([0]*64)
789 overflow <- 1
790 else
791 RT <- MODS(dividend, divisor)
792 overflow <- 0
793
794 Special Registers Altered:
795
796 None
797
798 # Modulo Unsigned Doubleword
799
800 X-Form
801
802 * modud RT,RA,RB
803
804 Pseudo-code:
805
806 dividend <- (RA)
807 divisor <- (RB)
808 if (divisor = [0]*64) then
809 RT[0:63] <- undefined([0]*64)
810 overflow <- 1
811 else
812 RT <- dividend % divisor
813 overflow <- 0
814
815 Special Registers Altered:
816
817 None
818
819 <!-- Checked March 2021 -->