怀疑sourcery G++ Lite版arm-none-eabi-gcc编译错误指令

怀疑sourcery G++ Lite版arm-none-eabi-gcc编译错误指令
以下是在Sourcery G++ Lite版 arm-none-eabi-gcc编译arm920t CPU的情况:

typedef struct {
    int count;
} atomic_t;

typedef struct {
    char c1;
// atomic_t i1;
    int i1;
} __attribute__((__packed__)) str_t;

volatile str_t Gstr ;

int main(void)
{
    Gstr.c1 = 1;
    Gstr.i1 = 0x12345678;
// Gstr.i1.count = 0x12345678;
    while (1);
    return 0;
}

    Gstr.i1 = 0x12345678;
    801c: e59f3024 ldr r3, [pc, #36] ; 8048 <main+0x48>
    8020: e5932000 ldr r2, [r3]
    8024: e20210ff and r1, r2, #255 ; 0xff
    8028: e59f201c ldr r2, [pc, #28] ; 804c <main+0x4c>
    802c: e1812002 orr r2, r1, r2
    8030: e5832000 str r2, [r3]
    8034: e5932004 ldr r2, [r3, #4]
    8038: e3c220ff bic r2, r2, #255 ; 0xff
    803c: e3822012 orr r2, r2, #18
    8040: e5832004 str r2, [r3, #4]
// Gstr.i1.count = 0x12345678;
    while (1);
    8044: eafffffe b 8044 <main+0x44>
    8048: 00010068 .word 0x00010068
    804c: 34567800 .word 0x34567800

以上汇编是预料范围内的,由于int i1被packed后处于非4字节对齐的地址空间,因此对i1 = 0x12345678 的操作无法通过一个ldr完成,必须分为两部分操作,即非原子操作(无论O0~O3都是要分两部分操作)。ldr指令是要求操作地址必须四字节对齐的。

typedef struct {
    int count;
} atomic_t;

typedef struct {
    char c1;
    atomic_t i1;
// int i1;
} __attribute__((__packed__)) str_t;

volatile str_t Gstr ;

int main(void)
{
    Gstr.c1 = 1;
// Gstr.i1 = 0x12345678;
    Gstr.i1.count = 0x12345678;
    while (1);
    return 0;
}
    Gstr.i1.count = 0x12345678;
    801c: e59f2014 ldr r2, [pc, #20] ; 8038 <main+0x38>
    8020: e5923001 ldr r3, [r2, #1]
    8024: e3a01000 mov r1, #0
    8028: e59f300c ldr r3, [pc, #12] ; 803c <main+0x3c>
    802c: e1813003 orr r3, r1, r3
    8030: e5823001 str r3, [r2, #1]
    while (1);
    8034: eafffffe b 8034 <main+0x34>
    8038: 00010058 .word 0x00010058
    803c: 12345678 .word 0x12345678

这里出现了奇怪的现象,当结构体内再使用一个结构体后,编译结果居然有非四字节对齐的ldr指令:   8020: e5923001 ldr r3, [r2, #1]  如果支持ldr的非对齐内存操作的话,那么无论变量是否对齐int型的赋值都是原子的,既然如此为什么当定义int时O3级别的编译依旧是分两部分操作呢?从操作数上看,这种直接一步操作的操作数明显更少效率更高啊?
后来在编译选项上加-fpack-struct全局pack后这种方式编译结果也和int方式一样分两部分进行了。所以怀疑编译器编译错误指令。
编译器是Sourcery G++ Lite arm-none-eabi-gcc 是不是Lite版本的问题?

你可能感兴趣的:(怀疑sourcery G++ Lite版arm-none-eabi-gcc编译错误指令)