1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static inline real_t DESCALE(unsigned val, int shift)
{
    int out;
    asm volatile(
        "lsrs %[out], %[val], %[shift]\n\t"
        "rsb %[shift], %[shift], #0\n\t"
        "adc %[out], %[val], lsl %[shift]"
        : [out]   "=&r" (out),
          [shift] "+r" (shift)
        : [val] "r" (val)
    );
    return out;
}

static inline real_t DESCALE(unsigned val, int shift)
{
    int out;
    if (shift > 0)
        out = (val + (1 << (shift - 1))) >> shift;
    else
        out = val << -shift;
    return out;
}