Closed 4ntoine closed 7 years ago
wiring_pulse.S https://gist.github.com/4ntoine/ca7f60069e4bbd70a048
Can you assemble wiring_pulse.S
with
llvm-mc -arch=avr -filetype=obj -mcpu=atmega328p <in> -o <out>
And post the error. This will manually invoke the integrated assembler, and also give a better error.
wiring_pulse.S
:
.section .text
.global countPulseASM
countPulseASM:
.LM0:
.LFBB1:
push r12 ; ; 130 pushqi1/1 [length = 1]
push r13 ; ; 131 pushqi1/1 [length = 1]
push r14 ; ; 132 pushqi1/1 [length = 1]
push r15 ; ; 133 pushqi1/1 [length = 1]
push r16 ; ; 134 pushqi1/1 [length = 1]
push r17 ; ; 135 pushqi1/1 [length = 1]
/* prologue: function */
/* frame size = 0 */
/* stack size = 6 */
.L__stack_usage = 6
mov r30,r24 ; port, port ; 2 *movhi/1 [length = 2]
mov r31,r25 ; port, port
/* unsigned long width = 0;
*** // wait for any previous pulse to end
*** while ((*port & bit) == stateMask)
*/
.LM1:
rjmp .L2 ; ; 181 jump [length = 1]
.L4:
/* if (--maxloops == 0) */
.LM2:
subi r16,1 ; maxloops, ; 17 addsi3/2 [length = 4]
sbc r17, r1 ; maxloops
sbc r18, r1 ; maxloops
sbc r19, r1 ; maxloops
breq .L13 ; , ; 19 branch [length = 1]
.L2:
/* if (--maxloops == 0) */
.LM3:
ld r25,Z ; D.1554, *port_7(D) ; 22 movqi_insn/4 [length = 1]
and r25,r22 ; D.1554, bit ; 24 andqi3/1 [length = 1]
cp r25,r20 ; D.1554, stateMask ; 25 *cmpqi/2 [length = 1]
breq .L4 ; , ; 26 branch [length = 1]
rjmp .L6 ; ; 184 jump [length = 1]
.L7:
/* return 0;
***
*** // wait for the pulse to start
*** while ((*port & bit) != stateMask)
*** if (--maxloops == 0)
*/
.LM4:
subi r16,1 ; maxloops, ; 31 addsi3/2 [length = 4]
sbc r17, r1 ; maxloops
sbc r18, r1 ; maxloops
sbc r19, r1 ; maxloops
breq .L13 ; , ; 33 branch [length = 1]
.L6:
/* if (--maxloops == 0) */
.LM5:
ld r25,Z ; D.1554, *port_7(D) ; 41 movqi_insn/4 [length = 1]
and r25,r22 ; D.1554, bit ; 43 andqi3/1 [length = 1]
cpse r25,r20 ; D.1554, stateMask ; 44 enable_interrupt-3 [length = 1]
rjmp .L7 ;
mov r12, r1 ; width ; 7 *movsi/2 [length = 4]
mov r13, r1 ; width
mov r14, r1 ; width
mov r15, r1 ; width
rjmp .L9 ; ; 186 jump [length = 1]
.L10:
/* return 0;
***
*** // wait for the pulse to stop
*** while ((*port & bit) == stateMask) {
*** if (++width == maxloops)
*/
.LM6:
ldi r24,-1 ; , ; 50 addsi3/3 [length = 5]
sub r12,r24 ; width,
sbc r13,r24 ; width,
sbc r14,r24 ; width,
sbc r15,r24 ; width,
cp r16,r12 ; maxloops, width ; 51 *cmpsi/2 [length = 4]
cpc r17,r13 ; maxloops, width
cpc r18,r14 ; maxloops, width
cpc r19,r15 ; maxloops, width
breq .L13 ; , ; 52 branch [length = 1]
.L9:
/* if (++width == maxloops) */
.LM7:
ld r24,Z ; D.1554, *port_7(D) ; 60 movqi_insn/4 [length = 1]
and r24,r22 ; D.1554, bit ; 62 andqi3/1 [length = 1]
cp r24,r20 ; D.1554, stateMask ; 63 *cmpqi/2 [length = 1]
breq .L10 ; , ; 64 branch [length = 1]
/* return 0;
*** }
*** return width;
*/
.LM8:
mov r22,r12 ; D.1553, width ; 108 movqi_insn/1 [length = 1]
mov r23,r13 ; D.1553, width ; 109 movqi_insn/1 [length = 1]
mov r24,r14 ; D.1553, width ; 110 movqi_insn/1 [length = 1]
mov r25,r15 ; D.1553, width ; 111 movqi_insn/1 [length = 1]
/* epilogue start */
.LM9:
pop r17 ; ; 171 popqi [length = 1]
pop r16 ; ; 172 popqi [length = 1]
pop r15 ; ; 173 popqi [length = 1]
pop r14 ; ; 174 popqi [length = 1]
pop r13 ; ; 175 popqi [length = 1]
pop r12 ; ; 176 popqi [length = 1]
ret ; 177 return_from_epilogue [length = 1]
.L13:
.LM10:
ldi r22,0 ; D.1553 ; 120 movqi_insn/1 [length = 1]
ldi r23,0 ; D.1553 ; 121 movqi_insn/1 [length = 1]
ldi r24,0 ; D.1553 ; 122 movqi_insn/1 [length = 1]
ldi r25,0 ; D.1553 ; 123 movqi_insn/1 [length = 1]
/* epilogue start */
.LM11:
pop r17 ; ; 138 popqi [length = 1]
pop r16 ; ; 139 popqi [length = 1]
pop r15 ; ; 140 popqi [length = 1]
pop r14 ; ; 141 popqi [length = 1]
pop r13 ; ; 142 popqi [length = 1]
pop r12 ; ; 143 popqi [length = 1]
ret ; 144 return_from_epilogue [length = 1]
I'm also not sure if the LLVM assembler handles C/C++ style comments.
@4ntoine: Also, prefer posting stuff in markdown code blocks rather than gist links.
@dylanmckay agree but i expected it to be too large to add code blocks
not sure that i have correct command-line:
./llvm-mc -arch=avr -filetype=obj -mcpu=atmega328p /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_pulse.c -o /tmp/arduino_test1/wiring_pulse_avr-llvm.S
Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file /Users/asmirnov/Documents/dev/src/avr-llvm/llvm/include/llvm/Support/Casting.h, line 237.
0 llvm-mc 0x000000010594a9be llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 46
1 llvm-mc 0x000000010594c649 PrintStackTraceSignalHandler(void*) + 25
2 llvm-mc 0x0000000105948ca9 llvm::sys::RunSignalHandlers() + 425
3 llvm-mc 0x000000010594c989 SignalHandler(int) + 345
4 libsystem_platform.dylib 0x00007fff98cb7f1a _sigtramp + 26
5 llvm-mc 0x0000000105981dbf FirstTarget + 9063
6 llvm-mc 0x000000010594c66b raise + 27
7 llvm-mc 0x000000010594c722 abort + 18
8 llvm-mc 0x000000010594c701 __assert_rtn + 129
9 llvm-mc 0x0000000105839927 llvm::cast_retty<llvm::MCSectionMachO, llvm::MCSection*>::ret_type llvm::cast<llvm::MCSectionMachO, llvm::MCSection>(llvm::MCSection*) + 103
10 llvm-mc 0x0000000105836477 (anonymous namespace)::MCMachOStreamer::ChangeSection(llvm::MCSection*, llvm::MCExpr const*) + 87
11 llvm-mc 0x00000001058543b6 llvm::MCStreamer::SwitchSection(llvm::MCSection*, llvm::MCExpr const*) + 790
12 llvm-mc 0x000000010584fa00 llvm::MCStreamer::InitSections(bool) + 80
13 llvm-mc 0x0000000105874c2d (anonymous namespace)::AsmParser::Run(bool, bool) + 109
14 llvm-mc 0x000000010577f0b9 AssembleInput(char const*, llvm::Target const*, llvm::SourceMgr&, llvm::MCContext&, llvm::MCStreamer&, llvm::MCAsmInfo&, llvm::MCSubtargetInfo&, llvm::MCInstrInfo&, llvm::MCTargetOptions&) + 1065
15 llvm-mc 0x000000010577cd53 main + 20771
16 libdyld.dylib 0x00007fff966e85c9 start + 1
Stack dump:
0. Program arguments: ./llvm-mc -arch=avr -filetype=obj -mcpu=atmega328p /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_pulse.c -o /tmp/arduino_test1/wiring_pulse_avr-llvm.S
Illegal instruction: 4
wiring_pulse.c:
/*
wiring_pulse.c - pulseIn() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#include "wiring_private.h"
#include "pins_arduino.h"
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse.
*
* This function performs better with short pulses in noInterrupt() context
*/
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes approximately 16 clock cycles per iteration
unsigned long maxloops = microsecondsToClockCycles(timeout)/16;
unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);
// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
if (width)
return clockCyclesToMicroseconds(width * 16 + 16);
else
return 0;
}
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse.
*
* ATTENTION:
* this function relies on micros() so cannot be used in noInterrupt() context
*/
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long startMicros = micros();
// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask) {
if (micros() - startMicros > timeout)
return 0;
}
// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask) {
if (micros() - startMicros > timeout)
return 0;
}
unsigned long start = micros();
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (micros() - startMicros > timeout)
return 0;
}
return micros() - start;
}
llvm-mc
assembles assembly files (.S
), not .c
files. You will need to give it the pregenerated Arduino assembly file instead.
llvm-mc -arch=avr -filetype=obj -mcpu=atmega328p
/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_pulse.S -o /tmp/arduino_test1/wiring_pulse_avr-llvm.o
Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file /Users/asmirnov/Documents/dev/src/avr-llvm/llvm/include/llvm/Support/Casting.h, line 237.
0 llvm-mc 0x0000000109fbb9be llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 46
1 llvm-mc 0x0000000109fbd649 PrintStackTraceSignalHandler(void*) + 25
2 llvm-mc 0x0000000109fb9ca9 llvm::sys::RunSignalHandlers() + 425
3 llvm-mc 0x0000000109fbd989 SignalHandler(int) + 345
4 libsystem_platform.dylib 0x00007fff98cb7f1a _sigtramp + 26
5 llvm-mc 0x0000000109ff2dbf FirstTarget + 9063
6 llvm-mc 0x0000000109fbd66b raise + 27
7 llvm-mc 0x0000000109fbd722 abort + 18
8 llvm-mc 0x0000000109fbd701 __assert_rtn + 129
9 llvm-mc 0x0000000109eaa927 llvm::cast_retty<llvm::MCSectionMachO, llvm::MCSection*>::ret_type llvm::cast<llvm::MCSectionMachO, llvm::MCSection>(llvm::MCSection*) + 103
10 llvm-mc 0x0000000109ea7477 (anonymous namespace)::MCMachOStreamer::ChangeSection(llvm::MCSection*, llvm::MCExpr const*) + 87
11 llvm-mc 0x0000000109ec53b6 llvm::MCStreamer::SwitchSection(llvm::MCSection*, llvm::MCExpr const*) + 790
12 llvm-mc 0x0000000109ec0a00 llvm::MCStreamer::InitSections(bool) + 80
13 llvm-mc 0x0000000109ee5c2d (anonymous namespace)::AsmParser::Run(bool, bool) + 109
14 llvm-mc 0x0000000109df00b9 AssembleInput(char const*, llvm::Target const*, llvm::SourceMgr&, llvm::MCContext&, llvm::MCStreamer&, llvm::MCAsmInfo&, llvm::MCSubtargetInfo&, llvm::MCInstrInfo&, llvm::MCTargetOptions&) + 1065
15 llvm-mc 0x0000000109dedd53 main + 20771
16 libdyld.dylib 0x00007fff966e85c9 start + 1
Stack dump:
0. Program arguments: ./llvm-mc -arch=avr -filetype=obj -mcpu=atmega328p /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_pulse.S -o /tmp/arduino_test1/wiring_pulse_avr-llvm.o
Illegal instruction: 4
is it correct
I believe so.
This code now successfully compiles. This is no longer an issue.
having the same issue again:
MBA-Anton:bin asmirnov$ ./clang -c -g -x assembler-with-cpp -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-I/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino" "-I/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/variants/standard" "/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_pulse.S" -o "/tmp/arduino_test1/wiring_pulse.S.o" -I/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include --target=avr
Stack dump:
0. Program arguments: /Volumes/Transcend/dev/src/llvm-avr/build/bin/clang-4.0 -cc1as -triple avr -filetype obj -main-file-name wiring_pulse.S -target-cpu atmega328p -I /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino -I /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/variants/standard -I /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include -fdebug-compilation-dir /Volumes/Transcend/dev/src/llvm-avr/build/bin -dwarf-debug-producer clang version 4.0.0 (https://github.com/avr-llvm/clang.git c6fdb09fb9bc5cf5c4b52b2d6f39e6349e942f3b) (llvm/llvm.git 2597ce5275a3cc6027ce9756f9e39744be737545) -I /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino -I /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/variants/standard -I /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include -debug-info-kind=limited -dwarf-version=4 -mrelocation-model static -o /tmp/arduino_test1/wiring_pulse.S.o /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/wiring_pulse-fff5e7.s
clang-4.0: error: unable to execute command: Segmentation fault: 11
clang-4.0: error: clang integrated assembler command failed due to signal (use -v to see invocation)
clang version 4.0.0 (https://github.com/avr-llvm/clang.git c6fdb09fb9bc5cf5c4b52b2d6f39e6349e942f3b) (llvm/llvm.git 2597ce5275a3cc6027ce9756f9e39744be737545)
Target: avr
Thread model: posix
InstalledDir: /Volumes/Transcend/dev/src/llvm-avr/build/bin/.
clang-4.0: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-4.0: note: diagnostic msg:
********************
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-4.0: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/wiring_pulse-697e6e.S
clang-4.0: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/wiring_pulse-697e6e.sh
clang-4.0: note: diagnostic msg:
********************
I'm trying to assemble the assembly code I posted above, but it assembles fine.
Can you post either the LLVM IR or the AVR assembly @4ntoine?
Nevermind, I just noticed you posted a gist above.
Can you post the preprocessed C (by passing -E
to clang
) so I can replicate this exactly @4ntoine
Probably it's another issue that happens with the same file, consider opening new ticket
is new issue created instead of this issue fixed?
Nah, not yet. I wasn't able to compile the clang files that were linked.
If you submit LLVM IR files I can re-raise
On 8/12/2016 8:04 am, "Anton Smirnov" notifications@github.com wrote:
is new issue created instead of this issue fixed?
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/avr-llvm/llvm/issues/176#issuecomment-265540456, or mute the thread https://github.com/notifications/unsubscribe-auth/AHXUr0-KbfLLq3rqvq1076-hglE60uU5ks5rFwNQgaJpZM4HHf73 .
wiring_pulse.S is from Arduino 1.6.7 distrib (download from arduino.cc)
got crash: