This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler: uint64_t truncation when shifting by > 32 positions

Tool/software: TI C/C++ Compiler

when compiled with TI compiler 16.9.6 in -Os mode the mbedTLS SHA-512 implementation produces incorrect results.

test code below is the excerpt that misbehaves - in particular, it looks like 64-bit shifts by more than 32 positions are not handled correctly.

#define GET_UINT64_BE(n,b,i)                      \
{                                                 \
    (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
        | ( (uint64_t) (b)[(i) + 1] << 48 )       \
        | ( (uint64_t) (b)[(i) + 2] << 40 )       \
        | ( (uint64_t) (b)[(i) + 3] << 32 )       \
        | ( (uint64_t) (b)[(i) + 4] << 24 )       \
        | ( (uint64_t) (b)[(i) + 5] << 16 )       \
        | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
        | ( (uint64_t) (b)[(i) + 7]       );      \
}

static void test64(void) {
  uint64_t w[2] = {0, 0};
  int i;
  static const uint8_t td[16] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  };
  for (i = 0; i < 2; i++) {
    GET_UINT64_BE(w[i], td, i << 3);
  }
  for (i = 0; i < sizeof(w); i++) {
    printf("%02x ", ((uint8_t *) w)[i]);
  }
  printf("\n");
}

when run, it produces the following output:

07 06 05 04 03 00 00 00 0f 0e 0d 0c 0b 00 00 00

note that top 3 bytes in the uint64_ts are zeroes, so it looks like shifts by 40, 48 and 56 result in 0 in the | operator above.

this is the assembler code generated by the compiler:

0103eaf4 <test64>:
 103eaf4:       b5f0            push    {r4, r5, r6, r7, lr}
 103eaf6:       2100            movs    r1, #0
 103eaf8:       2210            movs    r2, #16
 103eafa:       f1ad 0d14       sub.w   sp, sp, #20
 103eafe:       4668            mov     r0, sp
 103eb00:       f005 fc3e       bl      1044380 <memset>
 103eb04:       4c24            ldr     r4, [pc, #144]  ; (103eb98 <test64+0xa4>)
 103eb06:       466d            mov     r5, sp
 103eb08:       2300            movs    r3, #0
 103eb0a:       2702            movs    r7, #2
 103eb0c:       78e6            ldrb    r6, [r4, #3]
 103eb0e:       78a0            ldrb    r0, [r4, #2]
 103eb10:       17f1            asrs    r1, r6, #31
 103eb12:       4318            orrs    r0, r3
 103eb14:       0202            lsls    r2, r0, #8
 103eb16:       ea46 0003       orr.w   r0, r6, r3
 103eb1a:       4311            orrs    r1, r2
 103eb1c:       0e02            lsrs    r2, r0, #24
 103eb1e:       0206            lsls    r6, r0, #8
 103eb20:       7920            ldrb    r0, [r4, #4]
 103eb22:       0209            lsls    r1, r1, #8
 103eb24:       4311            orrs    r1, r2
 103eb26:       17c2            asrs    r2, r0, #31
 103eb28:       430a            orrs    r2, r1
 103eb2a:       4330            orrs    r0, r6
 103eb2c:       0211            lsls    r1, r2, #8
 103eb2e:       0206            lsls    r6, r0, #8
 103eb30:       0e02            lsrs    r2, r0, #24
 103eb32:       7960            ldrb    r0, [r4, #5]
 103eb34:       4311            orrs    r1, r2
 103eb36:       17c2            asrs    r2, r0, #31
 103eb38:       430a            orrs    r2, r1
 103eb3a:       4330            orrs    r0, r6
 103eb3c:       0211            lsls    r1, r2, #8
 103eb3e:       0206            lsls    r6, r0, #8
 103eb40:       0e02            lsrs    r2, r0, #24
 103eb42:       79a0            ldrb    r0, [r4, #6]
 103eb44:       4311            orrs    r1, r2
 103eb46:       17c2            asrs    r2, r0, #31
 103eb48:       430a            orrs    r2, r1
 103eb4a:       4330            orrs    r0, r6
 103eb4c:       0211            lsls    r1, r2, #8
 103eb4e:       0206            lsls    r6, r0, #8
 103eb50:       0e02            lsrs    r2, r0, #24
 103eb52:       79e0            ldrb    r0, [r4, #7]
 103eb54:       1e7f            subs    r7, r7, #1
 103eb56:       ea41 0102       orr.w   r1, r1, r2
 103eb5a:       ea4f 72e0       mov.w   r2, r0, asr #31
 103eb5e:       f104 0408       add.w   r4, r4, #8
 103eb62:       ea42 0101       orr.w   r1, r2, r1
 103eb66:       ea40 0006       orr.w   r0, r0, r6
 103eb6a:       c503            stmia   r5!, {r0, r1}
 103eb6c:       d1ce            bne.n   103eb0c <test64+0x18>
 103eb6e:       2410            movs    r4, #16
 103eb70:       466d            mov     r5, sp
 103eb72:       f815 1b01       ldrb.w  r1, [r5], #1
 103eb76:       a005            add     r0, pc, #20     ; (adr r0, 103eb8c <test64+0x98>)
 103eb78:       f006 ffd0       bl      1045b1c <printf>
 103eb7c:       1e64            subs    r4, r4, #1
 103eb7e:       d1f8            bne.n   103eb72 <test64+0x7e>
 103eb80:       a004            add     r0, pc, #16     ; (adr r0, 103eb94 <test64+0xa0>)
 103eb82:       f006 ffcb       bl      1045b1c <printf>
 103eb86:       b005            add     sp, #20
 103eb88:       bdf0            pop     {r4, r5, r6, r7, pc}
 103eb8a:       46c0            nop                     ; (mov r8, r8)
 103eb8c:       78323025        .word   0x78323025
 103eb90:       46c00020        .word   0x46c00020
 103eb94:       46c0000a        .word   0x46c0000a
 103eb98:       01059282        .word   0x01059282