## 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]) slli rC = 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

```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()
{
8070:    df000315     stw    fp,12(sp)
8074:    d839883a     mov    fp,sp
unsigned int na, ns, nv;
na = 0x8000F731;
8078:    00a00074     movhi    r2,32769
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