This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bug in the simulator?

Issue

The POPNE (or LDMNEIA) instruction seems to be executed in the simulator even if the Zero flag is set.

C Compiler: V4.1.0.567
CPU DLL: V4.14

How to reproduce

Create a new project with the following options:

Device -> NXP (founded by Philips) -> LPC2129
C/C++ -> Optimization: level 3 (-O3), check "Optimize for Time"

C code (part of an original project):

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define MAX_CMD_LEN     32
#define MAX_CMD_ARGS    3

static const char * command;
static const char * args[MAX_CMD_ARGS];
static unsigned num_args;

static void cmd_read(void);

static const struct cmd_info {
        const char * name;
        void (* func)(void);
}
commands[] = {
        /* other commands ... */
        { "read", cmd_read },
        { 0 }
};

static void parse_cmd_buff(void) {

        /* here we pretend we are parsing something ... */

        command = "read";
        args[0] = "eeprom";
        args[1] = "0";
        args[2] = "128";
        num_args = 3;
}


static void read_eeprom(uint32_t * addr, size_t len) {


}

static void cmd_read(void) {
        static void read_eeprom(uint32_t * addr, size_t len);
        uint32_t addr;
        size_t len;

        /* This condition is true, so read_eeprom() must get called.
           But it doesn't. See below for details. */
        if (!strcmp(args[0], "eeprom") && num_args == 3 &&
                sscanf(args[1], "%i", &addr) &&   sscanf(args[2], "%i", &len))

                read_eeprom(&addr, len);
}

static int interactive_mode(void) {
        const struct cmd_info * cmd;

        for (;;) {

                parse_cmd_buff();

                for (cmd = commands; cmd->name; cmd++)
                        if (!strcmp(cmd->name, command))
                                break;

                if (cmd->name)
                        cmd->func();
                else
                        /* printf("*** bad command: %s\n", command) */;

        }
}


int main() {

        /* ... */

        interactive_mode();

        return 0;

}

Here's the listing of cmd_read().

;;;38     static void cmd_read(void) {
000000  e92d4010          PUSH     {r4,lr}
;;;39           static void read_eeprom(uint32_t * addr, size_t len);
;;;40           uint32_t addr;
;;;41           size_t len;
;;;42
;;;43           if (!strcmp(args[0], "eeprom") && num_args == 3 &&
000004  e59f4070          LDR      r4,|L1.124| ; R4 = args
000008  e24dd008          SUB      sp,sp,#8              ;38
00000c  e5940000          LDR      r0,[r4,#0]  ; args[0]
000010  e28f1068          ADR      r1,|L1.128|
000014  ebfffffe          BL       strcmp
000018  e3500000          CMP      r0,#0 ; Z = 1
;;;44                   sscanf(args[1], "%i", &addr) &&   sscanf(args[2], "%i", &len))
;;;45
;;;46                   read_eeprom(&addr, len);
;;;47     }
00001c  128dd008          ADDNE    sp,sp,#8
000020  18bd4010          POPNE    {r4,lr}   ; This instruction gets executed even
                                                ; though Z = 1. This results in R4
                                                ; being clobbered and args[1] pointing
                                                ; to the wrong place in the subsequent
                                                ; call to sscanf().
000024  112fff1e          BXNE     lr
000028  e59f0058          LDR      r0,|L1.136|
00002c  e5900004          LDR      r0,[r0,#4]            ;43  ; num_args
000030  e3500003          CMP      r0,#3                 ;43
000034  128dd008          ADDNE    sp,sp,#8
000038  18bd4010          POPNE    {r4,lr}
00003c  112fff1e          BXNE     lr
000040  e5940004          LDR      r0,[r4,#4]            ;43  ; args
000044  e1a0200d          MOV      r2,sp                 ;43
000048  e28f103c          ADR      r1,|L1.140|
00004c  ebfffffe          BL       __0sscanf
000050  e3500000          CMP      r0,#0                 ;43
000054  028dd008          ADDEQ    sp,sp,#8
000058  08bd4010          POPEQ    {r4,lr}
00005c  012fff1e          BXEQ     lr
000060  e5940008          LDR      r0,[r4,#8]            ;43  ; args
000064  e28d2004          ADD      r2,sp,#4              ;43
000068  e28f101c          ADR      r1,|L1.140|
00006c  ebfffffe          BL       __0sscanf
000070  e28dd008          ADD      sp,sp,#8
000074  e8bd4010          POP      {r4,lr}
000078  e12fff1e          BX       lr
                  |L1.124|
                          DCD      ||.bss||
                  |L1.128|
000080  65657072          DCB      "eeprom",0
000084  6f6d00
000087  00                DCB      0
                  |L1.136|
                          DCD      ||.data||
                  |L1.140|
00008c  256900            DCB      "%i",0
00008f  00                DCB      0
                          ENDP

0