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/ru/circular-shifts.3mpu b/man/ru/circular-shifts.3mpu
new file mode 100644
index 0000000..63a71f0
--- /dev/null
+++ b/man/ru/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 \- операции циклического сдвига на один бит
+.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
+Для операций циклического сдвига на один бит входным операндом служит переменная размером
+\fBnb\fP байт, находящаяся по адресу \fBa\fP, результат помещается в переменную того же размера,
+расположенную по адресу \fBc\fP. Пространства, занимаемые входной и выходной переменной в памяти
+могут пересекаться, как частично, так и полностью, что не влияет на правильность получаемого
+результата. Содержимое переменной, расположенной по адресу \fBa\fP останется неизменным,
+после выполнения операции, если занимаемое ей пространство не пересекается с пространством,
+занимаемым переменной \fBc\fP.
+.PP
+При выполнениии операций циклического сдвига, флаг переноса \fBC\fP всегда содержит значение
+последнего выдвинутого бита. Существуют следующие виды операций циклического сдвига:
+.PP
+.RS 3
+    ROL \- циклический сдвиг влево на один бит.
+.RE
+.RS 3
+    ROR \- циклический сдвиг вправо на один бит.
+.RE
+.RS 3
+    RCL \- циклический сдвиг влево на один бит с участием флага переноса.
+.RE
+.RS 3
+    RCR \- циклический сдвиг вправо на один бит с участием флага переноса.
+.RE
+.PP
+Следующие таблицы иллюстрируют выполнение операций \fBirol\fP, \fBiror\fP.
+.nf
+.sp
+      ┌────────────────┬───┬───────────────────┬────────────┐
+      │ ROL(<<):       │ C │ значение операнда │ заполнение │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ до операции    │   │      10110111     │   sign(1)  │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ после операции │ 1 │      01101111     │            │
+      └────────────────┴───┴───────────────────┴────────────┘
+
+      ┌────────────────┬────────────┬───────────────────┬───┐
+      │ ROR(>>):       │ заполнение │ значение операнда │ C │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ до операции    │ low bit(1) │      10110111     │   │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ после операции │            │      11011011     │ 1 │
+      └────────────────┴────────────┴───────────────────┴───┘
+.fi
+.sp
+Операции \fBirol\fP и \fBiror\fP (аналогично с командами сдвига \fBisal\fP, \fBisar\fP, \fBishl\fP,
+\fBishr\fP) действуют на флаг переполнения \fBO\fP контролируя изменение знака операнда. Так же
+выставляются флаги четности \fBP\fP, знака \fBS\fP и нуля \fBZ\fP. Флаг переноса из младшей тетрады
+\fBA\fP не определяется и просто сбрасывается в 0.
+.PP
+В операциях \fBircl\fP и \fBircr\fP в сдвиге участвует флаг переноса \fBC\fP. Выдвигаемый из операнда
+бит, заносится во флаг переноса \fBC\fP после того, как предыдущее значение \fBC\fP поступит в
+освободившуюся позицию.
+.nf
+.sp
+      ┌────────────────┬───┬───────────────────┬────────────┐
+      │ RCL(<<):       │ C │ значение операнда │ заполнение │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ до операции    │ 0 │      10110111     │    C(0)    │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ после операции │ 1 │      01101110     │            │
+      └────────────────┴───┴───────────────────┴────────────┘
+
+      ┌────────────────┬────────────┬───────────────────┬───┐
+      │ RCR(>>):       │ заполнение │ значение операнда │ C │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ до операции    │    C(0)    │      10110111     │ 0 │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ после операции │            │      01011011     │ 1 │
+      └────────────────┴────────────┴───────────────────┴───┘
+.fi
+.sp
+Операции \fBircl\fP, \fBircr\fP воздействуют на флаги переноса \fBC\fP и переполнения \fBO\fP
+аналогично всем предыдущим операциям. Флаг переноса из младшей тетрады \fBA\fP не определяется
+и просто сбрасывается в 0.
+.PP
+Выставление флагов четности \fBP\fP и нуля \fBZ\fP операциями \fBircl\fP, \fBircr\fP несколько
+отличается от предыдущих типов операций. Это относится и к флагу знака \fBS\fP. Так как операции
+\fBircl\fP, \fBircr\fP могут использоваться для сдвигов нескольких слов совместно с другими
+командами сдвига и, как правило, завершают такие составные операции, хотелось бы, после их
+завершения, иметь состояние флагов \fBP\fP и \fBZ\fP соответствующим, не только последнему
+сдвигаемому слову, а целиком всей сдвигаемой комбинации слов.
+.PP
+Для этого операция \fBircr\fP выставляет свои флаги (\fBP\fP, \fBS\fP), а операция \fBircl\fP не
+определяет свои флаги (\fBP\fP, \fBS\fP) и не изменяет их предыдущих значений. Флаг нуля \fBZ\fP
+обеими операциями (\fBircl\fP, \fBircr\fP) выставляется по \fBЛогическому И\fP (\fBAND\fP)
+с предыдущим значением флага \fBZ\fP, то есть:
+.nf
+.sp
+      ┌────────────────┬────────────────┬────────────────┐
+      │                │   Значение Z,  │                │
+      │   Предыдущее   │   полученное   │ Результирующее │
+      │   значение Z   │  в результате  │   значение Z   │
+      │                │    операции    │                │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       1        │       0        │       0        │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       1        │       1        │       1        │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       0        │       0        │       0        │
+      ├────────────────┼──────────—─——──┼────────────────┤
+      │       0        │       1        │       0        │
+      └────────────────┴─────────—————──┴────────────────┘
+
+.fi
+.sp
+Таким образом, если все слова, участвующие в комбинации сдвигов, дали нулевой результат, то и флаг
+\fBZ\fP останется в значении \fBИСТИНА\fP, иначе, если хотя\-бы одно слово дало ненулевой результат,
+флаг \fBZ\fP останется в состоянии \fBЛОЖЬ\fP.
+.SS Примеры операций:
+\fBСдвиг пары слов вправо\fP:
+.PP
+\fBisar\fP(11111101), \fBircr\fP(10011010); после \fBisar\fP результат = 11111110,
+\fBC\fP=1, \fBO\fP=0, \fBP\fP=1, \fBZ\fP=0; после \fBircr\fP результат = 11001101,
+\fBC\fP=0, \fBO\fP=0, \fBP\fP=0, \fBZ\fP=0. Общий результат: 1111111011001101.
+Состояние флагов после операции \fBircr\fP гарантированно принадлежит ко всей
+комбинации двух слов (размером по 8 бит каждое).
+.sp
+\fBСдвиг пары слов влево\fP:
+.PP
+\fBircl\fP(00111000), isal(10111111); после \fBisal\fP результат = 01111110,
+\fBC\fP=1, \fBO\fP=1, \fBP\fP=1, \fBZ\fP=0; после \fBircl\fP результат = 01110001,
+\fBC\fP=0, \fBO\fP=0, \fBP\fP=1, \fBZ\fP=0. Общий результат: 0111000101111110.
+Состояние флагов после операции \fBisal\fP гарантированно принадлежит ко всей
+комбинации двух слов (размером по 8 бит каждое). Заметим, что флаг \fBP\fP
+выставлен операцией \fBisal\fP и не изменялся операцией \fBircl\fP, флаг
+\fBZ\fP получен по \fBAND\fP между \fBZ\fP от \fBisal\fP и \fBZ\fP
+от \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).
+