diff options
Diffstat (limited to 'results/classifier/gemma3:27b/instruction/1806243')
| -rw-r--r-- | results/classifier/gemma3:27b/instruction/1806243 | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/results/classifier/gemma3:27b/instruction/1806243 b/results/classifier/gemma3:27b/instruction/1806243 new file mode 100644 index 000000000..d3250c600 --- /dev/null +++ b/results/classifier/gemma3:27b/instruction/1806243 @@ -0,0 +1,87 @@ + + + +ARM conditional branch after if-then instruction not working + +Hello + +There seems to be an issue with QEMU when debugging if-then condition blocks from the thumb2 instruction set. The following snippet runs fine during normal execution, but keeps hanging at the conditional branch when debugging. The jump at the branch should only be executed as long as $r0 is lower than $r1. Problem is that once both are equal, the execution is not continued past the branch and the program counter never gets popped. + +2000407a: push {lr} +2000407c: movs r0, r6 +2000407e: ldmia r7!, {r1, r6} +20004080: push {r0, r1} +20004082: str.w r6, [r7, #-4]! +20004086: ldr r6, [sp, #0] +20004088: pop {r0, r1} +2000408a: adds r0, #1 +2000408c: cmp r0, r1 +2000408e: itt lt +20004090: pushlt {r0, r1} +20004092: blt.w 0x20004082 ; unpredictable <IT:lt> // <-- GDB hangs here +20004096: pop {pc} + +I have tried to reproduce the problem with inline assembly but for some reason the following example just worked: + +void f() { + static uint8_t stack[256]{}; + stack[255] = 4; + + asm volatile("\n\t" + "push {lr}" + "\n\t" + + // pre-conditions + "movs r7, %[stack]" + "\n\t" + "movs r6, #1" + "\n\t" + + "movs r0, r6" + "\n\t" + "ldmia r7!, {r1, r6}" + "\n\t" + "push {r0, r1}" + "\n\t" + "1:" + "\n\t" + "str.w r6, [r7, #-4]!" + "\n\t" + "ldr r6, [sp, #0]" + "\n\t" + "pop {r0, r1}" + "\n\t" + "adds r0, #1" + "\n\t" + "cmp r0, r1" + "\n\t" + "itt lt" + "\n\t" + "pushlt {r0, r1}" + "\n\t" + + // Original instruction + //"blt.w 0x20004082" // ; unpredictable <IT:lt> + + // Trying to fake it + "blt.w 1b" + "\n\t" + + "pop {pc}" + "\n\t" + : + : [stack] "r"(&stack[255])); +} + +The only real major difference I see to the other code snipped is that the inline assembly is running from flash memory where as the original code runs in ram? Maybe that's a clue somehow? + +Quickly reading through already reported ARM bugs I think this might be related: +https://bugs.launchpad.net/qemu/+bug/1364501 +At least the symptoms sound identical. + + +The versions I'm running are: +QEMU 3.0.0 +arm-none-eabi-gdb 8.2 + +I've also captured some trace output for single stepping from the pushlt to the blt.w instruction with the trace arguments unimp, guest_errors, op, int, exec. \ No newline at end of file |