You could subtract the value of '\n' from each byte, bitwise-or the result with its negated value, right shift the sign bit into the least significant position, and push that into an accumulator.
Basically, it is possible to reduce a byte into a one or a zero if it does or does not match a value using only bitwise instructions. I don't know if the way I just described uses the fewest instructions, but you can definitely do it without branching.
In fact, you can do this to test any integer comparison. Start by subtracting the arguments to the comparison operator, and then use one of these "squash" functions for the comparison operator in question (assuming 32 bit signed integers are being compared):
Should compile down to no branches (not even cmov) by summing the value of the flag register directly. Would be a it hard to stop without taking a branch though. Would you consider function pointer calls a branch? If that's too easy, what about taking a segfault?
Even if you do the branchiest thing possible in the source, no bitwise or "looks cmov-y" stuff, all compilers that matter will do this without a branch with optimization on:
I just want to gently push back on the notion that the source level branchy-ness is tightly tied to the generated assembly level branchiness.
Sometimes, it is - but it is a long topic to characterize when. For simple things like counters based on a condition, you'll almost always get branch-free. Same for assignment/return value based on a condition, where the possibilities don't involve lots of asymmetric work (or a asymmetric memory access).
Basically, it is possible to reduce a byte into a one or a zero if it does or does not match a value using only bitwise instructions. I don't know if the way I just described uses the fewest instructions, but you can definitely do it without branching.
In fact, you can do this to test any integer comparison. Start by subtracting the arguments to the comparison operator, and then use one of these "squash" functions for the comparison operator in question (assuming 32 bit signed integers are being compared):
== : ~(c | -c) >>> 31
!= : (c | -c) >>> 31
> : -c >>> 31
>= : ~c >>> 31
< : c >>> 31
<= : ~-c >>> 31