3c780c88 (kx 2024-12-29 12:21:01 +0300 1) .\" Copyright 2024 Andrew V.Kosteltsev (kx@radix-linux.su)
3c780c88 (kx 2024-12-29 12:21:01 +0300 2) .\"
3c780c88 (kx 2024-12-29 12:21:01 +0300 3) .\"
3c780c88 (kx 2024-12-29 12:21:01 +0300 4) .TH shifts 3 "December 27, 2024" "libmpu" "LibMPU Programmer's Manual"
3c780c88 (kx 2024-12-29 12:21:01 +0300 5) .SH NAME
3c780c88 (kx 2024-12-29 12:21:01 +0300 6) \fBishl\fP, \fBishr\fP, \fBisal\fP, \fBisar\fP \- one\-bit shifts
3c780c88 (kx 2024-12-29 12:21:01 +0300 7) .SH SYNOPSIS
3c780c88 (kx 2024-12-29 12:21:01 +0300 8) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 9) .B #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 10) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 11) .BI "void ishl( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 12) .BI "void ishr( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 13) .BI "void isal( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 14) .BI "void isar( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300 15) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 16) .SH DESCRIPTION
3c780c88 (kx 2024-12-29 12:21:01 +0300 17) For one\-bit shift operations, the input operand is a variable of size \fBnb\fP bytes located
3c780c88 (kx 2024-12-29 12:21:01 +0300 18) at address \fBa\fP, the result is placed in a variable of the same size located at address \fBc\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300 19) The spaces occupied by the input and output variable in memory may overlap, either partially or
3c780c88 (kx 2024-12-29 12:21:01 +0300 20) completely, which does not affect the correctness of the result obtained. The content of the
3c780c88 (kx 2024-12-29 12:21:01 +0300 21) variable located at address \fBa\fP will remain unchanged after the operation if the space
3c780c88 (kx 2024-12-29 12:21:01 +0300 22) occupied by it does not overlap with the space occupied by variable \fBc\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300 23) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 24) When performing shift operations, the carry flag \fBC\fP always contains the value of the last
af4d4942 (kx 2024-12-30 12:16:19 +0300 25) pushed outward bit. There are the following types of shift operations:
3c780c88 (kx 2024-12-29 12:21:01 +0300 26) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 27) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 28) SHL \- logical unsigned shift to the left by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300 29) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 30) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 31) SHR \- logical unsigned shift to the right by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300 32) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 33) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 34) SAL \- arithmetic shift to the left by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300 35) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 36) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300 37) SAR \- arithmetic shift to the right by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300 38) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300 39) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 40) The following tables illustrate the execution of the operations \fBishl\fP, \fBishr\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300 41) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 42) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 43) ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 44) │ SHL(<<): │ C │ operand value │ filling │
3c780c88 (kx 2024-12-29 12:21:01 +0300 45) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 46) │ before │ │ 10110111 │ 0 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 47) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 48) │ after │ 1 │ 01101110 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 49) └────────────────┴───┴───────────────────┴────────────┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 50)
3c780c88 (kx 2024-12-29 12:21:01 +0300 51) ┌────────────────┬────────────┬───────────────────┬───┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 52) │ SHR(>>): │ filling │ operand value │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300 53) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 54) │ before │ 0 │ 10110111 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 55) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 56) │ after │ │ 01011011 │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 57) └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 58) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 59) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 60) The tables show that any logical shift always results in a 0 being pushed into the vacated space.
3c780c88 (kx 2024-12-29 12:21:01 +0300 61) The overflow flag \fBO\fP is set if the operand has changed sign as a result of the operation.
3c780c88 (kx 2024-12-29 12:21:01 +0300 62) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 63) The left arithmetic shift operation \fBisal\fP operates in the same way as \fBishl\fP (0 is
3c780c88 (kx 2024-12-29 12:21:01 +0300 64) also moved to the empty space on the right). The right arithmetic shift operation works
3c780c88 (kx 2024-12-29 12:21:01 +0300 65) differently: the sign bit of the original operand is copied to the empty position on the left.
3c780c88 (kx 2024-12-29 12:21:01 +0300 66) The action of the \fBisal\fP and \fBisar\fP operations is shown in the following tables.
3c780c88 (kx 2024-12-29 12:21:01 +0300 67) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 68) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 69) ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 70) │ SAL(<<): │ C │ operand value │ filling │
3c780c88 (kx 2024-12-29 12:21:01 +0300 71) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 72) │ before │ │ 10110111 │ 0 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 73) ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 74) │ after │ 1 │ 01101110 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 75) └────────────────┴───┴───────────────────┴────────────┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 76)
3c780c88 (kx 2024-12-29 12:21:01 +0300 77) ┌────────────────┬────────────┬───────────────────┬───┐
3c780c88 (kx 2024-12-29 12:21:01 +0300 78) │ SAR(>>): │ filling │ operand value │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300 79) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 80) │ before │ sign(1) │ 10110111 │ │
3c780c88 (kx 2024-12-29 12:21:01 +0300 81) ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300 82) │ after │ │ 11011011 │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300 83) └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300 84) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 85) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 86) The overflow flag for the \fBisal\fP operation is set in the same way as for the \fBishl\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300 87) operation. When performing an \fBisar\fP operation, the operand cannot change its sign. Repeated
3c780c88 (kx 2024-12-29 12:21:01 +0300 88) shifting of \fBisar\fP may eventually cause a loss of value, and a positive number will be shifted
3c780c88 (kx 2024-12-29 12:21:01 +0300 89) to 0 and a negative number to -1. Therefore, the overflow flag \fBO\fP for the \fBisar\fP operation
3c780c88 (kx 2024-12-29 12:21:01 +0300 90) is reset to 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300 91) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 92) When performing \fBisal\fP, \fBisar\fP, \fBishl\fP, \fBishr\fP operations, the parity \fBP\fP,
3c780c88 (kx 2024-12-29 12:21:01 +0300 93) sign \fBS\fP and zero \fBZ\fP flags are also set. The carry flag from the lowest tetrad \fBA\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300 94) is not defined and is simply reset to 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300 95) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300 96) Left shift can be used to double numbers, and right shift can be used to divide by 2. These operations
3c780c88 (kx 2024-12-29 12:21:01 +0300 97) are much faster than multiplication and division operations. Dividing odd numbers (such as 5 or 7) in
3c780c88 (kx 2024-12-29 12:21:01 +0300 98) half forms smaller values (2 or 3, respectively) and sets the carry flag \fBC\fP to 1. In doing so,
3c780c88 (kx 2024-12-29 12:21:01 +0300 99) \fBC\fP actually contains the remainder of the division. This use of shift operations requires control
3c780c88 (kx 2024-12-29 12:21:01 +0300 100) of the overflow flag \fBO\fP. For simplicity, consider flag control on 4\-bit signed variables:
3c780c88 (kx 2024-12-29 12:21:01 +0300 101) .SS Examples with 4\-bit operands:
3c780c88 (kx 2024-12-29 12:21:01 +0300 102) \fBMultiplying by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 103) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 104) SAL(0111) = 7; result = 1110 = -2, mistake, there must be 14, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 105) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 106) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 107) \fBDividing by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 108) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 109) SHR(1000) = -8; result = 0100 = 4, mistake, there must be -4, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 110) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 111) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 112) \fBDividing by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 113) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 114) SAR(1000) = -8; result = 1100 = -4, exactly, CF = 0, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 115) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 116) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 117) \fBDividing by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 118) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 119) SAR(0111) = 7; result = 0011 = 3, remainder 1 (see carry flag C), exactly, CF = 1, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 120) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 121) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 122) .SH EXAMPLES
3c780c88 (kx 2024-12-29 12:21:01 +0300 123) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 124) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 125) #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 126) #include <stdio.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 127)
3c780c88 (kx 2024-12-29 12:21:01 +0300 128) int main( void )
3c780c88 (kx 2024-12-29 12:21:01 +0300 129) {
3c780c88 (kx 2024-12-29 12:21:01 +0300 130) int rc = 0;
3c780c88 (kx 2024-12-29 12:21:01 +0300 131)
3c780c88 (kx 2024-12-29 12:21:01 +0300 132) __mpu_init();
3c780c88 (kx 2024-12-29 12:21:01 +0300 133) __mpu_extra_warnings = 1;
3c780c88 (kx 2024-12-29 12:21:01 +0300 134)
3c780c88 (kx 2024-12-29 12:21:01 +0300 135) {
1ca800d6 (kx 2024-12-29 20:12:16 +0300 136) mpu_int8_t c, a;
3c780c88 (kx 2024-12-29 12:21:01 +0300 137) int nb = NB_I8;
3c780c88 (kx 2024-12-29 12:21:01 +0300 138) __mpu_char8_t sc[32], sa[32];
3c780c88 (kx 2024-12-29 12:21:01 +0300 139)
3c780c88 (kx 2024-12-29 12:21:01 +0300 140) iatoi( a, "0b10110111", nb ); /* evaluate the A variable */
3c780c88 (kx 2024-12-29 12:21:01 +0300 141)
3c780c88 (kx 2024-12-29 12:21:01 +0300 142) ishl( c, a, nb );
3c780c88 (kx 2024-12-29 12:21:01 +0300 143) iitoa( sa, a, RADIX_BIN, LOWERCASE, nb ); /* convert A value to ASCII string SA */
3c780c88 (kx 2024-12-29 12:21:01 +0300 144) iitoa( sc, c, RADIX_BIN, LOWERCASE, nb ); /* convert C value to ASCII string SC */
e3f8685d (kx 2024-12-30 18:22:24 +0300 145) printf( "a = %s;\\n", sa ); /* c = 0b10110111; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 146) printf( "c = %s;\\n", sc ); /* c = 0b01101110; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 147) printf( "carry = %d;\\n", __mpu_gtc() ); /* Carry Flag */
e3f8685d (kx 2024-12-30 18:22:24 +0300 148) printf( "overflow = %d;\\n", __mpu_gto() ); /* Overflow Flag */
3c780c88 (kx 2024-12-29 12:21:01 +0300 149) }
3c780c88 (kx 2024-12-29 12:21:01 +0300 150)
3c780c88 (kx 2024-12-29 12:21:01 +0300 151) __mpu_free_context();
3c780c88 (kx 2024-12-29 12:21:01 +0300 152)
3c780c88 (kx 2024-12-29 12:21:01 +0300 153) return( rc );
3c780c88 (kx 2024-12-29 12:21:01 +0300 154) }
3c780c88 (kx 2024-12-29 12:21:01 +0300 155) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 156) .SH SEE ALSO
3c780c88 (kx 2024-12-29 12:21:01 +0300 157) .BR iadd(3),
3c780c88 (kx 2024-12-29 12:21:01 +0300 158) .BR isub(3),
41c271da (kx 2025-01-05 15:42:39 +0300 159) .BR iadc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 160) .BR isbb(3),
41c271da (kx 2025-01-05 15:42:39 +0300 161) .BR irol(3),
41c271da (kx 2025-01-05 15:42:39 +0300 162) .BR iror(3),
41c271da (kx 2025-01-05 15:42:39 +0300 163) .BR ircl(3),
41c271da (kx 2025-01-05 15:42:39 +0300 164) .BR ircr(3),
41c271da (kx 2025-01-05 15:42:39 +0300 165) .BR ishln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 166) .BR ishrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 167) .BR isaln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 168) .BR isarn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 169) .BR iroln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 170) .BR irorn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 171) .BR ircln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 172) .BR ircrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 173) .BR ineg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 174) .BR inot(3),
41c271da (kx 2025-01-05 15:42:39 +0300 175) .BR iand(3),
41c271da (kx 2025-01-05 15:42:39 +0300 176) .BR itest(3),
41c271da (kx 2025-01-05 15:42:39 +0300 177) .BR icmp(3),
41c271da (kx 2025-01-05 15:42:39 +0300 178) .BR ior(3),
41c271da (kx 2025-01-05 15:42:39 +0300 179) .BR ixor(3),
41c271da (kx 2025-01-05 15:42:39 +0300 180) .BR iinc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 181) .BR idec(3),
41c271da (kx 2025-01-05 15:42:39 +0300 182) .BR ixchg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 183) .BR icpy(3),
41c271da (kx 2025-01-05 15:42:39 +0300 184) .BR icvt(3),
41c271da (kx 2025-01-05 15:42:39 +0300 185) .BR imul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 186) .BR ismul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 187) .BR idiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 188) .BR isdiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 189) .BR iatoi(3),
41c271da (kx 2025-01-05 15:42:39 +0300 190) .BR iatoui(3),
41c271da (kx 2025-01-05 15:42:39 +0300 191) .BR iitoa(3),
41c271da (kx 2025-01-05 15:42:39 +0300 192) .BR iuitoa(3).