This inline-asm in ARMJITInfo.cpp's ARMCompilationCallback: // Return to the (newly modified) stub to invoke the real function. // The above twiddling of the saved return addresses allows us to // deallocate everything, including the LR the stub saved, all in one // pop instruction. "ldmia sp!, {r0, r1, r2, r3, lr, pc}\n" does not assemble as thumb2: llvm[3]: Compiling ARMJITInfo.cpp for Release-Asserts build /tmp/ccWGkQ6d.s: Assembler messages: /tmp/ccWGkQ6d.s:28: Error: LR and PC should not both be in register list -- `ldmia sp!,{r0,r1,r2,r3,lr,pc}' make[3]: *** [/home/nlewycky/llvm/lib/Target/ARM/Release-Asserts/ARMJITInfo.o] Error 1 with '-Os -mthumb' flags to gcc instead of -O2.
Based on the definition of LDMIA in the ARM architecture reference manual, ldmia is define as below. if W == `1' && Rn == `1101' then SEE POP; n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == `1'); if n == 15 || BitCount(registers) < 2 || (P == `1' && M == `1') then UNPREDICTABLE; if registers<15> == `1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; if wback && registers<n> == `1' then UNPREDICTABLE; Note that if both P and M is '1', the result is UNPREDICTABLE. In the inlined assembly below, both lr and pc are to be accessed. So it's not a valid assembly code. (In reply to comment #0) > This inline-asm in ARMJITInfo.cpp's ARMCompilationCallback: > > // Return to the (newly modified) stub to invoke the real function. > // The above twiddling of the saved return addresses allows us to > // deallocate everything, including the LR the stub saved, all in one > // pop instruction. > "ldmia sp!, {r0, r1, r2, r3, lr, pc}\n" > > does not assemble as thumb2: > > llvm[3]: Compiling ARMJITInfo.cpp for Release-Asserts build > /tmp/ccWGkQ6d.s: Assembler messages: > /tmp/ccWGkQ6d.s:28: Error: LR and PC should not both be in register list -- > `ldmia sp!,{r0,r1,r2,r3,lr,pc}' > make[3]: *** [/home/nlewycky/llvm/lib/Target/ARM/Release-Asserts/ARMJITInfo.o] > Error 1 > > with '-Os -mthumb' flags to gcc instead of -O2. >
Right -- my other mistake is that I was building in thumb1 instead of thumb2. I'll try thumb2 tomorrow but I don't really expect it to work any better than a build with thumb did.
Indeed, in thumb2 mode (passing -mthumb -mcpu=cortex-a8) I get the same assembler error.
I'm new to LLVM. At least in GCC, -mthumb can mean both T1 and T2; It depends on which cpu you select. For example: -mthumb -mcpu=cortex-a8: T2 -mthumb -mcpu=arm1156t2-s: T2 -mthumb -march=armv7-a: T2 -mthumb -march=armv6t2: T2 -mthumb -mcpu=arm926ej-s: T1 -mthumb -mcpu=arm1136jf-s: T1 -mthumb -march=armv5: T1 -mthumb -march=armv6: T1
Created attachment 4168 [details] patch, make two pops when __thumb__ are defined. Would making two pops for __thumb__ instead of one big one solve this issue?
fixed in svn r124694 *** This bug has been marked as a duplicate of bug 9081 ***