Math Processor Unit Library

libmpu – library of arithmetic functions for integer, real, and complex numbers of increased digit capacity

16 Commits   0 Branches   2 Tags
author: kx <kx@radix-linux.su> 2024-12-29 20:12:16 +0300 committer: kx <kx@radix-linux.su> 2024-12-29 20:12:16 +0300 commit: 1ca800d6620d35f1d07f7c54ba20693de0af3f1c parent: 3c780c88a0a0e98f7bb1ceaf7843c4560d2e0ce4
Commit Summary:
man pages: Circular shift operations by one bit
Diffstat:
1 file changed, 190 insertions, 0 deletions
diff --git a/man/circular-shifts.3mpu b/man/circular-shifts.3mpu
new file mode 100644
index 0000000..6eaf96a
--- /dev/null
+++ b/man/circular-shifts.3mpu
@@ -0,0 +1,206 @@
+.\" Copyright 2024 Andrew V.Kosteltsev (kx@radix-linux.su)
+.\"
+.\"
+.TH circular\-shifts 3  "December 27, 2024" "libmpu" "LibMPU Programmer's Manual"
+.SH NAME
+\fBirol\fP, \fBiror\fP, \fBircl\fP, \fBircr\fP \- сyclic shift operations by one bit
+.SH SYNOPSIS
+.nf
+.B #include <libmpu.h>
+.PP
+.BI "void irol( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.BI "void iror( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.BI "void ircl( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.BI "void ircr( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.fi
+.SH DESCRIPTION
+For cyclic shift operations by one bit, the input operand is a variable of size \fBnb\fP
+bytes located at address \fBa\fP, the result is placed in a variable of the same size located
+at address \fBc\fP. The spaces occupied by the input and output variables may overlap partially
+or completely, which does not affect the correctness of the result. The content of the variable
+located at address \fBa\fP will remain unchanged after the operation if the space occupied by
+it does not overlap with the space occupied by variable \fBc\fP.
+.PP
+When performing cyclic shift operations, the carry flag \fBC\fP always contains the value of the
+last putted forward bit. The following types of cyclic shift operations are available:
+.PP
+.RS 3
+    ROL \- cyclic shift to the left by one bit.
+.RE
+.RS 3
+    ROR \- cyclic shift to the right by one bit.
+.RE
+.RS 3
+    RCL \- cyclic shift to the left by one bit involving the carry flag.
+.RE
+.RS 3
+    RCR \- cyclic shift to the right by one bit involving the carry flag.
+.RE
+.PP
+The following tables illustrate the execution of \fBirol\fP, \fBiror\fP operations.
+.nf
+.sp
+      ┌────────────────┬───┬───────────────────┬────────────┐
+      │ ROL(<<):       │ C │   operand value   │  filling   │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ before         │   │      10110111     │   sign(1)  │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ after          │ 1 │      01101111     │            │
+      └────────────────┴───┴───────────────────┴────────────┘
+
+      ┌────────────────┬────────────┬───────────────────┬───┐
+      │ ROR(>>):       │  filling   │   operand value   │ C │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ before         │ low bit(1) │      10110111     │   │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ after          │            │      11011011     │ 1 │
+      └────────────────┴────────────┴───────────────────┴───┘
+.fi
+.sp
+The \fBirol\fP and \fBiror\fP operations (similar to the shift commands \fBisal\fP, \fBisar\fP,
+\fBishl\fP, \fBishr\fP) act on the overflow flag \fBO\fP to control the sign change of the operand.
+The parity \fBP\fP, sign \fBS\fP, and zero \fBZ\fP flags are also set. The carry flag from the
+lowest tetrad \fBA\fP is not defined and is simply reset to 0.
+.PP
+In \fBircl\fP and \fBircr\fP operations, the carry flag \fBC\fP is involved in the shift.
+The bit to be shifted out of the operand is written to the carry flag \fBC\fP after the
+previous \fBC\fP value enters the vacant position.
+.nf
+.sp
+      ┌────────────────┬───┬───────────────────┬────────────┐
+      │ RCL(<<):       │ C │   operand value   │  filling   │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ before         │ 0 │      10110111     │    C(0)    │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ after          │ 1 │      01101110     │            │
+      └────────────────┴───┴───────────────────┴────────────┘
+
+      ┌────────────────┬────────────┬───────────────────┬───┐
+      │ RCR(>>):       │  filling   │   operand value   │ C │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ before         │    C(0)    │      10110111     │ 0 │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ after          │            │      01011011     │ 1 │
+      └────────────────┴────────────┴───────────────────┴───┘
+.fi
+.sp
+The \fBircl\fP, \fBircr\fP operations affect the carry \fBC\fP and overflow \fBO\fP flags
+in the same way as all previous operations. The carry flag from the lowest tetrad \fBA\fP
+is not defined and is simply reset to 0.
+.PP
+The setting of parity \fBP\fP and zero \fBZ\fP flags by \fBircl\fP, \fBircr\fP operations
+is somewhat different from the previous types of operations. This also applies to the sign
+flag \fBS\fP. Since \fBircl\fP, \fBircr\fP operations can be used to shift several words
+together with other shift commands and, as a rule, complete such compound operations,
+it would be desirable, after their completion, to have the state of the flags \fBP\fP
+and \fBZ\fP corresponding, not only to the last shifted word, but to the whole shifted
+combination of words.
+.PP
+For this purpose, the \fBircr\fP operation sets its flags (\fBP\fP, \fBS\fP), while the \fBircl\fP
+operation does not define its flags (\fBP\fP, \fBS\fP) and does not change their previous values.
+The zero flag \fBZ\fP by both operations (\fBircl\fP, \fBircr\fP) is set by \fBLogical AND\fP
+with the previous value of the \fBZ\fP flag, i.e.:
+.nf
+.sp
+      ┌────────────────┬────────────────┬────────────────┐
+      │                │    Z value,    │                │
+      │    Previous    │    obtained    │   Resulting    │
+      │    Z value     │ as a result of │    Z value     │
+      │                │    operation   │                │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       1        │       0        │       0        │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       1        │       1        │       1        │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       0        │       0        │       0        │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       0        │       1        │       0        │
+      └────────────────┴─────────—————──┴────────────────┘
+
+.fi
+.sp
+Thus, if all words involved in the combination of shifts, gave zero result, then the flag \fBZ\fP
+will remain in the value of \fBTRUE\fP, otherwise, if at least one word gave a non\-zero result,
+the flag \fBZ\fP will remain in the state of \fBFALSE\fP.
+.SS Examples of operations:
+\fBShift a pair of words to the right\fP:
+.PP
+\fBisar\fP(11111101), \fBircr\fP(10011010); after \fBisar\fP result = 11111110,
+\fBC\fP=1, \fBO\fP=0, \fBP\fP=1, \fBZ\fP=0; after \fBircr\fP result = 11001101,
+\fBC\fP=0, \fBO\fP=0, \fBP\fP=0, \fBZ\fP=0. Total result: 1111111011001101.
+The state of flags after \fBircr\fP operation is guaranteed to belong to
+the whole combination of two words (8 bits each).
+.sp
+\fBShift a pair of words to the left\fP:
+.PP
+\fBircl\fP(00111000), \fBisal\fP(10111111); after \fBisal\fP result = 01111110,
+\fBC\fP=1, \fBO\fP=1, \fBP\fP=1, \fBZ\fP=0; after \fBircl\fP result = 01110001,
+\fBC\fP=0, \fBO\fP=0, \fBP\fP=1, \fBZ\fP=0. Total result: 0111000101111110.
+The state of the flags after the \fBisal\fP operation is guaranteed to
+belong to the whole combination of two words (of size 8 bits each).
+Note that flag \fBP\fP is set by operation \fBisal\fP and not changed
+by operation \fBircl\fP, flag \fBZ\fP is obtained by \fBAND\fP between
+\fBZ\fP from \fBisal\fP and \fBZ\fP from \fBircl\fP.
+.sp
+.SH EXAMPLES
+.nf
+.sp
+#include <libmpu.h>
+#include <stdio.h>
+
+int main( void )
+{
+  int  rc = 0;
+
+  __mpu_init();
+  __mpu_extra_warnings = 1;
+
+  {
+    mpu_int8_t     c, d, a, b;
+    mpu_int16_t    z;
+    mpu_int       *pz = NULL;
+    __mpu_char8_t  s[32];
+
+    pz = (mpu_int *)&z;
+
+#if ( MPU_BYTE_ORDER_BIG_ENDIAN == 1 )
+    ++pz;
+#endif
+
+    iatoi( b, "0b10111111", NB_I8 );  /* low part  */
+    iatoi( a, "0b00111000", NB_I8 );  /* high part */
+
+    __mpu_clc(); /* clear Carry Flag */
+
+    isal( d, b, NB_I8 );
+    ircl( c, a, NB_I8 );
+
+    icpy( pz, d, NB_I8, NB_I8 ); /*  low part of Z */
+#if ( MPU_BYTE_ORDER_BIG_ENDIAN == 1 )
+    --pz;
+#else
+    ++pz;
+#endif
+    icpy( pz, c, NB_I8, NB_I8 ); /* high part of Z */
+
+    iitoa( s, z, RADIX_BIN, UPPERCASE, NB_I16 ); /* convert Z value to ASCII string S */
+    printf( "z = %s;\n", s ); /* z = 0B0111000101111110; */
+    printf( "carry    = %d;\n", __mpu_gtc() );  /* Carry Flag    */
+    printf( "overflow = %d;\n", __mpu_gto() );  /* Overflow Flag */
+  }
+
+  __mpu_free_context();
+
+  return( rc );
+}
+.fi
+.SH SEE ALSO
+.BR iadd(3),
+.BR iadc(3),
+.BR isub(3),
+.BR isbb(3),
+.BR ishl(3),
+.BR ishr(3),
+.BR isal(3),
+.BR isar(3).
+