Shift Instructions

shiftdirRegisterImmediate
logicalleftsllslli
logicalrightsrlsrli
arithmeticrightsrasrai
rotateleftrolroli
rotaterightrorrori

pseudo-instruction

Both register and immediate shifts are R-Format instructions:

sll
rC = rA << (rB[4:0])

sllirC = rA << (sh)rB is zero for slli

Logical vs. Arithmetic

v<<n shifts v right by n bits.

If v is unsigned, a right shift is logical. If v is signed, a right shift is arithmetic and the sign bit is shifted in from the left (sign-extension)

Rotate

Note that the following constructions are compiled to a single rotate instruction:

44:         // rotate right
45:         nv = (na>>ns)|(na<<(32-ns));
48:         // rotate left
49:         nv = (na<<ns)|(na>>(32-ns));

C Source

Download: cprog2.zip.


01: //#define DBUG
02: #if defined(DBUG)
03:         #include "sys/alt_stdio.h"
04:         #define DBPRINTF alt_printf
05: #else
06:     #define DBPRINTF
07: #endif
08: 
09: int main()
10: {
11:         unsigned int na, ns, nv;
12:         na = 0x8000F731;
13:         DBPRINTF("na = 0x%x\n",na);
14: 
15:         // logical shift left
16:         nv = na<<3;
17:         DBPRINTF("na<<3 = 0x%x\n",nv);
18:         // logical shift right
19:         nv = na>>3;
20:         DBPRINTF("na>>3 = 0x%x\n",nv);
21:         // arithmetic shift right
22:         nv = ((signed)na)>>3;
23:         DBPRINTF("((signed)na)>>3 = 0x%x\n",nv);
24: 
25:         // rotate right
26:         nv = (na>>4)|(na<<28);
27:         DBPRINTF("rot right 4 = 0x%x\n",nv);
28: 
29:         // rotate left
30:         nv = (na<<4)|(na>>28);
31:         DBPRINTF("rot left 4 = 0x%x\n",nv);
32: 
33:         // use variable as shift amount
34:         ns = 5;
35:         DBPRINTF("Use variable as shift amount\n ns = %d\n",ns);
36: 
37:         nv = na>>ns;
38:         DBPRINTF("na>>ns = 0x%x\n",nv);
39: 
40:         nv = na<<ns;
41:         DBPRINTF("na<<ns = 0x%x\n",nv);
42: 
43:         ns = 8;
44:         // rotate right
45:         nv = (na>>ns)|(na<<(32-ns));
46:         DBPRINTF("rot right 8 = 0x%x\n",nv);
47: 
48:         // rotate left
49:         nv = (na<<ns)|(na>>(32-ns));
50:         DBPRINTF("rot left 8 = 0x%x\n",nv);
51: 
52:         /* Event loop never exits. */
53:         while (1);
54:         return 0;
55: }


Disassembly

0000806c <main>:
    #define DBPRINTF
#endif

int main()
{
    806c:    defffc04     addi    sp,sp,-16
    8070:    df000315     stw    fp,12(sp)
    8074:    d839883a     mov    fp,sp
    unsigned int na, ns, nv;
    na = 0x8000F731;
    8078:    00a00074     movhi    r2,32769
    807c:    10bdcc44     addi    r2,r2,-2255
    8080:    e0800015     stw    r2,0(fp)
    DBPRINTF("na = 0x%x\n",na);

    // logical shift left
    nv = na<<3;
    8084:    e0800017     ldw    r2,0(fp)
    8088:    100490fa     slli    r2,r2,3
    808c:    e0800215     stw    r2,8(fp)
    DBPRINTF("na<<3 = 0x%x\n",nv);
    // logical shift right
    nv = na>>3;
    8090:    e0800017     ldw    r2,0(fp)
    8094:    1004d0fa     srli    r2,r2,3
    8098:    e0800215     stw    r2,8(fp)
    DBPRINTF("na>>3 = 0x%x\n",nv);
    // arithmetic shift right
    nv = ((signed)na)>>3;
    809c:    e0800017     ldw    r2,0(fp)
    80a0:    1005d0fa     srai    r2,r2,3
    80a4:    e0800215     stw    r2,8(fp)
    DBPRINTF("((signed)na)>>3 = 0x%x\n",nv);

    // rotate right
    nv = (na>>4)|(na<<28);
    80a8:    e0800017     ldw    r2,0(fp)
    80ac:    1004173a     roli    r2,r2,28
    80b0:    e0800215     stw    r2,8(fp)
    DBPRINTF("rot right 4 = 0x%x\n",nv);

    // rotate left
    nv = (na<<4)|(na>>28);
    80b4:    e0800017     ldw    r2,0(fp)
    80b8:    1004113a     roli    r2,r2,4
    80bc:    e0800215     stw    r2,8(fp)
    DBPRINTF("rot left 4 = 0x%x\n",nv);

    // use variable as shift amount
    ns = 5;
    80c0:    00800144     movi    r2,5
    80c4:    e0800115     stw    r2,4(fp)
    DBPRINTF("Use variable as shift amount\n ns = %d\n",ns);

    nv = na>>ns;
    80c8:    e0c00017     ldw    r3,0(fp)
    80cc:    e0800117     ldw    r2,4(fp)
    80d0:    1884d83a     srl    r2,r3,r2
    80d4:    e0800215     stw    r2,8(fp)
    DBPRINTF("na>>ns = 0x%x\n",nv);

    nv = na<<ns;
    80d8:    e0c00017     ldw    r3,0(fp)
    80dc:    e0800117     ldw    r2,4(fp)
    80e0:    1884983a     sll    r2,r3,r2
    80e4:    e0800215     stw    r2,8(fp)
    DBPRINTF("na<<ns = 0x%x\n",nv);

    ns = 8;
    80e8:    00800204     movi    r2,8
    80ec:    e0800115     stw    r2,4(fp)
    // rotate right
    nv = (na>>ns)|(na<<(32-ns));
    80f0:    e0c00017     ldw    r3,0(fp)
    80f4:    e0800117     ldw    r2,4(fp)
    80f8:    1884583a     ror    r2,r3,r2
    80fc:    e0800215     stw    r2,8(fp)
    DBPRINTF("rot right 8 = 0x%x\n",nv);

    // rotate left
    nv = (na<<ns)|(na>>(32-ns));
    8100:    e0c00017     ldw    r3,0(fp)
    8104:    e0800117     ldw    r2,4(fp)
    8108:    1884183a     rol    r2,r3,r2
    810c:    e0800215     stw    r2,8(fp)
    DBPRINTF("rot left 8 = 0x%x\n",nv);

    /* Event loop never exits. */
    while (1);
    8110:    003fff06     br    8110 <main+0xa4>


Maintained by John Loomis, updated Sun Sep 21 18:41:24 2008