【发布时间】:2013-03-13 13:08:31
【问题描述】:
我在编译下面的代码 sn-p 时遇到了一些问题。
#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 指令的描述。它说的是这样的:-
添加 xmm1, xmm2/m128 将压缩的单精度浮点值从 xmm2/m128 添加到 xmm1。
所以,源可以是内存地址或 xmm 寄存器,但目标必须是 xmm 寄存器。我想我的约束有点同意这一点。 谁能指出我这里可能存在的问题?
谢谢。
【问题讨论】:
-
“'asm' 中的不可能约束”听起来不像是汇编指令格式错误,而是您的约束格式错误。
-
请参阅gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html,了解 gcc 如何声明矢量类型(或包括
并使用 __m128d 或其他类型之一)。