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