我正在研究一个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/