godbolt.org: compile with ARM GCC 9.2.1 or similar for either Linux or None: ----------------------------------- use normal code to limit value: ----------------------------------- inline int minmax(int a, int x, int b) { return x >= a ? x <= b ? x : b : a; } extern int getc(); int main() { int a = getc(); return minmax(0,a,0xffff); } Linux -O2: => main: push {r3, lr} bl getc() usat r0, #16, r0 <-- they have an opcode for this pop {r3, pc} None -march=armv6-m -mcpu=cortex-m0plus -mthumb -O2 => main: push {r4, lr} bl getc() movs r3, #128 lsls r3, r3, #9 cmp r0, r3 blt .L2 ldr r0, .L5 .L3: pop {r4, pc} .L2: mvns r3, r0 asrs r3, r3, #31 ands r0, r3 b .L3 .L5: .word 65535 --------------------------------- use RP2040 Interpolator to clamp value: ----------------------------------- #define port1 0xd0000020 #define port2 0xd0000010 extern int getc(); int main() { int a = getc(); *(int*)port1 = a; return *(int*)port2; } None -march=armv6-m -mcpu=cortex-m0plus -mthumb -O2 => main: push {r4, lr} bl getc() ldr r3, .L2 str r0, [r3] ldr r3, .L2+4 ldr r0, [r3] pop {r4, pc} .L2: .word -805306336 .word -805306352 --------------------------------- Kio's method for clamping to uint16 V1 --------------------------------- extern int getc(); int main() { int a = getc(); if ((unsigned short)a != (unsigned int)a) { a = a<0 ? 0 : 0xffff; } return a; } None -march=armv6-m -mcpu=cortex-m0plus -mthumb -O2 => main: push {r4, lr} bl getc() movs r3, r0 lsls r0, r0, #16 lsrs r0, r0, #16 cmp r3, r0 beq .L1 mvns r3, r3 asrs r3, r3, #31 uxth r0, r3 .L1: pop {r4, pc} --------------------------------- Kio's method for clamping to uint16 V2 --------------------------------- extern int getc(); int main() { int a = getc(); if (((unsigned int)a)>>16) { a = a<0 ? 0 : 0xffff; } return a; } None -march=armv6-m -mcpu=cortex-m0plus -mthumb -O2 => main: push {r4, lr} bl getc() lsrs r3, r0, #16 beq .L1 ldr r3, .L8 asrs r0, r0, #31 ands r0, r3 ldr r3, .L8+4 mov ip, r3 add r0, r0, ip .L1: pop {r4, pc} .L8: .word -65535 .word 65535 --------------------------------- Kio's method for clamping to uint16 V2 + UNLIKELY --------------------------------- #define UNLIKELY(x) __builtin_expect((x),false) extern int getc(); int main() { int a = getc(); if (UNLIKELY(((unsigned int)a)>>16)) { a = a<0 ? 0 : 0xffff; } return a; } None -march=armv6-m -mcpu=cortex-m0plus -mthumb -O2 => main: push {r4, lr} bl getc() lsrs r3, r0, #16 bne .L8 .L1: pop {r4, pc} .L8: ldr r3, .L9 asrs r0, r0, #31 ands r0, r3 ldr r3, .L9+4 mov ip, r3 add r0, r0, ip b .L1 .L9: .word -65535 .word 65535