我在编译下面的代码片段时遇到了一些问题。
#include <iostream>
#include <cstdint>
using namespace std;
union mxcsr {
uint32_t v;
struct {
uint32_t ie : 1;
uint32_t de : 1;
uint32_t ze : 1;
uint32_t oe : 1;
uint32_t ue : 1;
uint32_t pe : 1;
uint32_t daz : 1;
uint32_t im : 1;
uint32_t dm : 1;
uint32_t zm : 1;
uint32_t om : 1;
uint32_t um : 1;
uint32_t pm : 1;
uint32_t rn : 1;
uint32_t rp : 1;
uint32_t fz : 1;
uint32_t rs0 : 15;
};
};
std::ostream& operator<<(std::ostream& ostr, mxcsr &m){
ostr << std::hex << std::showbase;
ostr << "mxcsr=" << m.v;
ostr << std::dec << std::noshowbase;
ostr << " [ie=" << m.ie << ",de=" << m.de
<< ",ze=" << m.ze << ",oe=" << m.oe << ",ue=" << m.ue
<< ",pe=" << m.pe << ",daz=" << m.daz << ",im=" << m.im
<< ",dm=" << m.dm << ",zm=" << m.zm << ",om=" << m.om
<< ",um=" << m.um << ",pm=" << m.pm << ",r-=" << m.rn
<< ",r+=" << m.rp << ",fz=" << m.fz << "] ";
return ostr;
}
typedef union __attribute__((aligned(16))) vec_t {
double f64[2];
float f32[4];
uint64_t u64[2];
uint32_t u32[4];
uint16_t u16[8];
uint8_t u8[16];
int64_t i64[2];
int32_t i32[4];
int16_t i16[8];
int8_t i8[16];
} vec_t;
float add_vec_32f(float ra, float rb, mxcsr &f){
vec_t va, vb;
va.f32[0] = ra; vb.f32[0] = rb;
asm("addps %[vb], %[va];"
"stmxcsr %[f];"
: [va] "+x" (va), [f] "=m" (f)
: [vb] "xm" (vb)
:
);
return va.f32[0];
}
int main()
{
mxcsr val;
float b = add_vec_32f(3.4, 5.6, val);
std::cout << "b=" << b << " val=" << val << std::endl;
return 0;
}
编译器抱怨这个错误"impossible constraint in 'asm'"。为了验证这一点,我浏览了 ADDPS 指令的描述。它说的是这样的:-
ADDPS xmm1, xmm2/m128 将压缩的单精度浮点值从 xmm2/m128 添加到 xmm1。
因此,源可以是内存地址或 xmm 寄存器,但目标必须是 xmm 寄存器。我想我的约束有点同意这一点。谁能指出我这里可能存在的问题?
谢谢。