| .\" 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 pushed outward 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 isub(3), |
| .BR iadc(3), |
| .BR isbb(3), |
| .BR ishl(3), |
| .BR ishr(3), |
| .BR isal(3), |
| .BR isar(3), |
| .BR ishln(3), |
| .BR ishrn(3), |
| .BR isaln(3), |
| .BR isarn(3), |
| .BR iroln(3), |
| .BR irorn(3), |
| .BR ircln(3), |
| .BR ircrn(3), |
| .BR ineg(3), |
| .BR inot(3), |
| .BR iand(3), |
| .BR itest(3), |
| .BR icmp(3), |
| .BR ior(3), |
| .BR ixor(3), |
| .BR iinc(3), |
| .BR idec(3), |
| .BR ixchg(3), |
| .BR icpy(3), |
| .BR icvt(3), |
| .BR imul(3), |
| .BR ismul(3), |
| .BR idiv(3), |
| .BR isdiv(3), |
| .BR iatoi(3), |
| .BR iatoui(3), |
| .BR iitoa(3), |
| .BR iuitoa(3). |
| |