8, 16, and 32 bit rotates in gcc 4.4.0:
static inline unsigned char _rotl8(unsigned char val, unsigned char shift)
{
shift &= 7;
val = (val>>(8 - shift)) | (val << shift);
return val;
}
static inline unsigned char _rotr8(unsigned char val, unsigned char shift)
{
shift &= 7;
val = (val<<(8 - shift)) | (val >> shift);
return val;
}
static inline unsigned short _rotl16(unsigned short val, unsigned char shift)
{
shift &= 15;
val = (val>>(16 - shift)) | (val << shift);
return val;
}
static inline unsigned short _rotr16(unsigned short val, unsigned char shift)
{
shift &= 15;
val = (val<<(16 - shift)) | (val >> shift);
return val;
}
static inline unsigned long _rotl32(unsigned long val, unsigned char shift)
{
shift &= 31;
val = (val>>(32 - shift)) | (val << shift);
return val;
}
static inline unsigned long _rotr32(unsigned long val, unsigned char shift)
{
shift &= 31;
val = (val<<(32 - shift)) | (val >> shift);
return val;
}
volatile unsigned char w = 1;
c: 1f7c 0001 0027 moveb #1,%sp@(39)
volatile unsigned char a = _rotl8(w, 1);
12: 102f 0027 moveb %sp@(39),%d0
16: 0280 0000 00ff andil #255,%d0
1c: 2200 movel %d0,%d1
1e: d281 addl %d1,%d1
20: ee80 asrl #7,%d0
22: 8001 orb %d1,%d0
24: 1f40 0026 moveb %d0,%sp@(38)
volatile unsigned char b = _rotr8(w, 1);
28: 102f 0027 moveb %sp@(39),%d0
2c: 0280 0000 00ff andil #255,%d0
32: 2200 movel %d0,%d1
34: e281 asrl #1,%d1
36: ef88 lsll #7,%d0
38: 8001 orb %d1,%d0
3a: 1f40 0025 moveb %d0,%sp@(37)
volatile unsigned short x = 1;
3e: 3f7c 0001 0022 movew #1,%sp@(34)
volatile unsigned short c = _rotl16(x, 1);
44: 302f 0022 movew %sp@(34),%d0
48: 0280 0000 ffff andil #65535,%d0
4e: 2200 movel %d0,%d1
50: d281 addl %d1,%d1
52: 740f moveq #15,%d2
54: e4a0 asrl %d2,%d0
56: 8041 orw %d1,%d0
58: 3f40 0020 movew %d0,%sp@(32)
volatile unsigned short d = _rotr16(x, 1);
5c: 302f 0022 movew %sp@(34),%d0
60: 0280 0000 ffff andil #65535,%d0
66: 2200 movel %d0,%d1
68: e281 asrl #1,%d1
6a: e5a8 lsll %d2,%d0
6c: 8041 orw %d1,%d0
6e: 3f40 001e movew %d0,%sp@(30)
volatile unsigned long y = 1;
72: 7001 moveq #1,%d0
74: 2f40 001a movel %d0,%sp@(26)
volatile unsigned long e = _rotl32(y, 1);
78: 202f 001a movel %sp@(26),%d0
7c: e398 roll #1,%d0
7e: 2f40 0016 movel %d0,%sp@(22)
volatile unsigned long f = _rotr32(y, 1);
82: 202f 001a movel %sp@(26),%d0
86: e298 rorl #1,%d0
88: 2f40 0012 movel %d0,%sp@(18)
volatile unsigned z = 1;
8c: 7401 moveq #1,%d2
8e: 2f42 000e movel %d2,%sp@(14)
volatile unsigned g = _rotl(z, 1);
92: 202f 000e movel %sp@(14),%d0
96: e398 roll #1,%d0
98: 2f40 000a movel %d0,%sp@(10)
volatile unsigned h = _rotr(z, 1);
9c: 202f 000e movel %sp@(14),%d0
a0: e298 rorl #1,%d0
a2: 2f40 0006 movel %d0,%sp@(6)
In the nonvolatile world (and in the compile-time templates), these examples are all reduced to integer constants.