The shift operations in C are
| Instruction | Description | Function |
|---|---|---|
| ROTR | Rotate Word Right | Rd = Rt[sa-1:0] | Rt[31:sa] |
| ROTRV | Rotate Word Right Variable | Rd = Rt[Rs-1:0] | Rt[31:Rs] |
| SLL | Shift Left Logical | Rd = Rt << sa |
| SLLV | Shift Left Logical Variable | Rd = Rt << Rs[4:0] |
| SRA | Shift Right Arithmetic | Rd = (int)Rt >> sa |
| SRAV | Shift Right Arithmetic Variable | Rd = (int)Rt >> Rs[4:0] |
| SRL | Shift Right Logical | Rd = (uns)Rt >> sa |
| SRLV | Shift Right Logical Variable | Rd = (uns)Rt >> Rs[4:0] |
C Source: shift.zip
01: #define PIC32
02: #if defined(PIC32)
03: #include <p32xxxx.h>
04: // comment the following line to enable debug output
05: #define UART2_IO
06: #include "db_utils.h"
07: #else // Microsoft C
08: #include <stdio.h>
09: #define DBPRINTF printf
10: #define DBPUTS(s)
11: #endif
12:
13: int main()
14: {
15: unsigned int na, ns, nv;
16: na = 0x8000F731;
17: DBPRINTF("na = 0x%x\n",na);
18:
19: // logical shift left
20: nv = na<<3;
21: DBPRINTF("na<<3 = 0x%x\n",nv);
22: // logical shift right
23: nv = na>>3;
24: DBPRINTF("na>>3 = 0x%x\n",nv);
25: // aritmetic shift right
26: nv = ((signed)na)>>3;
27: DBPRINTF("((signed)na)>>3 = 0x%x\n",nv);
28:
29: // rotate right
30: nv = (na>>4)|(na<<28);
31: DBPRINTF("rot right 4 = 0x%x\n",nv);
32:
33: // rotate left
34: nv = (na<<4)|(na>>28);
35: DBPRINTF("rot left 4 = 0x%x\n",nv);
36:
37: // use variable as shift amount
38: ns = 5;
39: DBPRINTF("Use variable as shift amount\n ns = %d\n",ns);
40:
41: nv = na>>ns;
42: DBPRINTF("na>>ns = 0x%x\n",nv);
43:
44: nv = na<<ns;
45: DBPRINTF("na<<ns = 0x%x\n",nv);
46:
47: ns = 8;
48: // rotate right
49: nv = (na>>ns)|(na<<(32-ns));
50: DBPRINTF("rot right 8 = 0x%x\n",nv);
51:
52: // rotate left
53: nv = (na<<ns)|(na>>(32-ns));
54: DBPRINTF("rot left 8 = 0x%x\n",nv);
55:
56: DBPUTS("Program terminated. Click HALT and then RESET to stop the microcontroller. \n");
57: return 0;
58: }
Comment out the PIC32 definition in line 1 and you can run this program with Microsoft C. The results are below
na = 0x8000f731 na<<3 = 0x7b988 na>>3 = 0x10001ee6 ((signed)na)>>3 = 0xf0001ee6 rot right 4 = 0x18000f73 rot left 4 = 0xf7318 Use variable as shift amount ns = 5 na>>ns = 0x40007b9 na<<ns = 0x1ee620 rot right 8 = 0x318000f7 rot left 8 = 0xf73180
Note that for lines 30 and 34 the compiler substitutes the single rotate instruction. Note further in line 34 that the compiler rotates right (32 - n) when asked to rotate left by n.
--- C:\pic32\test\shift1.c ---------------------------------------------------------------------
1: #define PIC32
2: #if defined(PIC32)
3: #include <p32xxxx.h>
4: // comment the following line to enable debug output
5: #define UART2_IO
6: #include "db_utils.h"
7: #else // Microsoft C
8: #include <stdio.h>
9: #define DBPRINTF printf
10: #define DBPUTS(s)
11: #endif
12:
13: int main()
14: {
9D000018 27BDFFE8 addiu sp,sp,-24
9D00001C AFBE0010 sw s8,16(sp)
9D000020 03A0F021 addu s8,sp,zero
15: unsigned int na, ns, nv;
16: na = 0x8000F731;
9D000024 3C028000 lui v0,0x8000
9D000028 3442F731 ori v0,v0,0xf731
9D00002C AFC20000 sw v0,0(s8)
17: DBPRINTF("na = 0x%x\n",na);
18:
19: // logical shift left
20: nv = na<<3;
9D000030 8FC20000 lw v0,0(s8)
9D000034 000210C0 sll v0,v0,0x3
9D000038 AFC20008 sw v0,8(s8)
21: DBPRINTF("na<<3 = 0x%x\n",nv);
22: // logical shift right
23: nv = na>>3;
9D00003C 8FC20000 lw v0,0(s8)
9D000040 000210C2 srl v0,v0,0x3
9D000044 AFC20008 sw v0,8(s8)
24: DBPRINTF("na>>3 = 0x%x\n",nv);
25: // aritmetic shift right
26: nv = ((signed)na)>>3;
9D000048 8FC20000 lw v0,0(s8)
9D00004C 000210C3 sra v0,v0,0x3
9D000050 AFC20008 sw v0,8(s8)
27: DBPRINTF("((signed)na)>>3 = 0x%x\n",nv);
28:
29: // rotate right
30: nv = (na>>4)|(na<<28);
9D000054 8FC20000 lw v0,0(s8)
9D000058 00221102 rotr v0,v0,0x4
9D00005C AFC20008 sw v0,8(s8)
31: DBPRINTF("rot right 4 = 0x%x\n",nv);
32:
33: // rotate left
34: nv = (na<<4)|(na>>28);
9D000060 8FC20000 lw v0,0(s8)
9D000064 00221702 rotr v0,v0,0x1c
9D000068 AFC20008 sw v0,8(s8)
35: DBPRINTF("rot left 4 = 0x%x\n",nv);
36:
37: // use variable as shift amount
38: ns = 5;
9D00006C 24020005 addiu v0,zero,5
9D000070 AFC20004 sw v0,4(s8)
39: DBPRINTF("Use variable as shift amount\n ns = %d\n",ns);
40:
41: nv = na>>ns;
9D000074 8FC30000 lw v1,0(s8)
9D000078 8FC20004 lw v0,4(s8)
9D00007C 00431006 srlv v0,v1,v0
9D000080 AFC20008 sw v0,8(s8)
42: DBPRINTF("na>>ns = 0x%x\n",nv);
43:
44: nv = na<<ns;
9D000084 8FC30000 lw v1,0(s8)
9D000088 8FC20004 lw v0,4(s8)
9D00008C 00431004 sllv v0,v1,v0
9D000090 AFC20008 sw v0,8(s8)
45: DBPRINTF("na<<ns = 0x%x\n",nv);
46:
47: ns = 8;
9D000094 24020008 addiu v0,zero,8
9D000098 AFC20004 sw v0,4(s8)
48: // rotate right
49: nv = (na>>ns)|(na<<(32-ns));
9D00009C 8FC30000 lw v1,0(s8)
9D0000A0 8FC20004 lw v0,4(s8)
9D0000A4 00431046 rotrv v0,v1,v0
9D0000A8 AFC20008 sw v0,8(s8)
50: DBPRINTF("rot right 8 = 0x%x\n",nv);
51:
52: // rotate left
53: nv = (na<<ns)|(na>>(32-ns));
9D0000AC 8FC30000 lw v1,0(s8)
9D0000B0 8FC20004 lw v0,4(s8)
9D0000B4 00021023 subu v0,zero,v0
9D0000B8 00431046 rotrv v0,v1,v0
9D0000BC AFC20008 sw v0,8(s8)
54: DBPRINTF("rot left 8 = 0x%x\n",nv);
55:
56: DBPUTS("Program terminated. Click HALT and then RESET to stop the microcontroller. \n");
57: return 0;
9D0000C0 00001021 addu v0,zero,zero
58: }
9D0000C4 03C0E821 addu sp,s8,zero
9D0000C8 8FBE0010 lw s8,16(sp)
9D0000CC 27BD0018 addiu sp,sp,24
9D0000D0 03E00008 jr ra
9D0000D4 00000000 nop
Maintained by John Loomis, updated Sat Aug 09 11:32:24 2008