以下のコードスニペットのコンパイル中に問題が発生します。
#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;
}
コンパイラは、このエラー「'asm'の不可能な制約」で文句を言います。これを確認するために、ADDPS命令の説明を確認しました。それはこのようなことを言います:-
ADDPS xmm1、xmm2 / m128 xmm2/m128からxmm1にパックされた単精度浮動小数点値を追加します。
したがって、ソースはメモリアドレスまたはxmmレジスタにすることができますが、宛先はxmmレジスタである必要があります。私の制約はそれに同意していると思います。誰かが私にここで起こりうる問題を指摘できますか?
ありがとう。