我正在研究一个32位体系结构,其中int64_t仅用最新版本的编译器(软件仿真)定义。由于我们没有完全升级到上一个编译器,所以我想用union来管理64位整数,并定义基本的算术操作。
我写的是:

typedef union _int64_u {
    int64_t  int64;
    int64_32 int32;
} int64_u;

typedef struct _int64_32 {
    int32_t hi;
    int32_t lo;
}

我想澄清以下几点:
这种定义(零件和类型)的命名标准是什么?
这个解决方案正确吗?
下面是add和sub函数的示例:
#pragma inline
#pragma always_inline
int64_u int64_sub(int64_u x, int64_u y)
{
    int64_u n;
    asm("%0 = %1 - %2;"
            : "=d" (n.int32.lo)
            : "d"  (x.int32.lo), "d" (y.int32.lo));
    asm("%0 = %1 - %2 + CI - 1;"
            : "=d" (n.int32.hi)
            : "d"  (x.int32.hi), "d" (y.int32.hi));
    return n;
}

#pragma inline
#pragma always_inline
int64_u int64_add(int64_u x, int64_u y)
{
    int64_u n;
    asm("%0 = %1 + %2;"
            : "=d" (n.int32.lo)
            : "d"  (x.int32.lo), "d" (y.int32.lo));
    asm("%0 = %1 + %2 + CI;"
            : "=d" (n.int32.hi)
            : "d"  (x.int32.hi), "d" (y.int32.hi));
    return n;
}

最佳答案

%0 = %1 + %2;不是我所知道的任何体系结构中的汇编指令。你甚至不需要用汇编来做这样的加减运算
此外,由于旧编译器没有64位类型,因此不需要声明联合,也不能这样做,因为以前没有声明过int64_t。你可以把整个东西作为一个结构来访问。

#if COMPILER_VERSION <= SOME_VERSION
typedef INT64_T {
    uint32_t h, l;
} uint64_t;

uint64_t add(uint64_t x, uint64_t y)
{
    uint64_t z;
    z.l = x.l + y.l;
    z.h = x.h + y.h + (z.l < x.l);
    return z;
}

// ...

#endif

现代编译器会认识到这一点,并在有它们的体系结构中变成add/adc对,因此没有比较和/或分支。

关于c - 使用int32_t访问int64_t的高低部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28828771/

10-11 22:50
查看更多