Description
The pulseIn function in Arduino/hardware/arduino/cores/arduino/wiring_pulse.c assumes that the loop compiles into 21 clock cycles (note the documentation disagrees and assumes 20). This seems to be true with avr-gcc 4.3.2 but not with avr-gcc 4.8.2.
avr-gcc 4.3.2 produces the following for the loop:
1528: 0f c0 rjmp .+30 ; 0x1548 <pulseIn+0xde> [2 cycles]
; loop starts here
152a: da 01 movw r26, r20 ; [1 cycle]
152c: c9 01 movw r24, r18 ; [1 cycle]
152e: 8e 0d add r24, r14 ; [1 cycle]
1530: 9f 1d adc r25, r15 ; [1 cycle]
1532: a0 1f adc r26, r16 ; [1 cycle]
1534: b1 1f adc r27, r17 ; [1 cycle]
1536: 8a 15 cp r24, r10 ; [1 cycle]
1538: 9b 05 cpc r25, r11 ; [1 cycle]
153a: ac 05 cpc r26, r12 ; [1 cycle]
153c: bd 05 cpc r27, r13 ; [1 cycle]
153e: f1 f0 breq .+60 ; 0x157c <pulseIn+0x112> [1 cycle - usually not taken]
1540: 2f 5f subi r18, 0xFF ; 255 [1 cycle]
1542: 3f 4f sbci r19, 0xFF ; 255 [1 cycle]
1544: 4f 4f sbci r20, 0xFF ; 255 [1 cycle]
1546: 5f 4f sbci r21, 0xFF ; 255 [1 cycle]
1548: 88 81 ld r24, Y ; [2 cycles]
154a: 88 21 and r24, r8 ; [1 cycle]
154c: 89 15 cp r24, r9 ; [1 cycle]
154e: 69 f3 breq .-38 ; 0x152a <pulseIn+0xc0> [2 cycles as usually taken]
which by my count is 21 cycles long which matches the assumption in the code.
avr-gcc 4.3.2 produces the following for the loop:
12b4: 68 81 ld r22, Y ; [2 cycles]
12b6: 60 23 and r22, r16 ; [1 cycle]
12b8: 61 13 cpse r22, r17 ; [2 cycles - usually skips next instruction]
12ba: 0a c0 rjmp .+20 ; 0x12d0 <pulseIn+0xd6> [usually skipped]
12bc: 28 17 cp r18, r24 ; [1 cycle]
12be: 39 07 cpc r19, r25 ; [1 cycle]
12c0: 4a 07 cpc r20, r26 ; [1 cycle]
12c2: 5b 07 cpc r21, r27 ; [1 cycle]
12c4: a9 f0 breq .+42 ; 0x12f0 <pulseIn+0xf6> [1 cycle - usually not taken]
12c6: 2f 5f subi r18, 0xFF ; 255 [1 cycle]
12c8: 3f 4f sbci r19, 0xFF ; 255 [1 cycle]
12ca: 4f 4f sbci r20, 0xFF ; 255 [1 cycle]
12cc: 5f 4f sbci r21, 0xFF ; 255 [1 cycle]
12ce: f2 cf rjmp .-28 ; 0x12b4 <pulseIn+0xba> [2 cycles]
Which by my count is only 16. This would account for pulse readings being around 30% higher than expected (as we are seeing and as is reported at http://forum.arduino.cc/index.php/topic,247507.0.html )
Note that in the process of raising this bug (but after I had done all the investigation!) I found the following thread discussing possible fixes: https://groups.google.com/a/arduino.cc/forum/#!topic/developers/5Po5BuY7UhA
This thread points out that this implementation is also very fragile in the face of interrupts.