2013-09-03 1 views
1

이 부스 매크로는 powerpc 아치에서 컴파일하려고 할 때 경고를 발생시킵니다. 매크로가 호출되는 각 라인에서 인라인 어셈블리의 "matching constraint"는 무엇을 의미합니까?

#define INNERMUL asm(\ 
    " mullw 16,%3,%4  \n\t" \ 
    " mulhwu 17,%3,%4  \n\t" \ 
    " addc  16,16,%0  \n\t" \ 
    " addze 17,17   \n\t" \ 
    " lwz  18,%1   \n\t" \ 
    " addc  16,16,18  \n\t" \ 
    " addze %0,17   \n\t" \ 
    " stw  16,%1   \n\t" \ 
:"=r"(cy),"=m"(_c[0]):"0"(cy),"r"(mu),"r"(tmpm[0]),"1"(_c[0]):"16", "17", "18","%cc"); ++tmpm; 

#define PROPCARRY \ 
asm(\ 
    " lwz  16,%1   \n\t" \ 
    " addc  16,16,%0  \n\t" \ 
    " stw  16,%1   \n\t" \ 
    " xor  %0,%0,%0  \n\t" \ 
    " addze %0,%0   \n\t" \ 
:"=r"(cy),"=m"(_c[0]):"0"(cy),"1"(_c[0]):"16","%cc"); 

, 나는 컴파일러에 의해이 경고를 얻을 :

../../src/math/mont.c:650: warning: matching constraint does not allow a register 

모든 일이 뜻하고, 어떤 방법으로 코드에 영향을 미치는 것을 말해 줄 수 있을까? 그리고 저는 정말로 어셈블러에 익숙하지 않았기 때문에 아마도 어떤 사람이 나를 도울 수 있었을 것입니다. 특별히 나의 경우에 경고를 일으키는 것이 무엇입니까?

내 시스템은 32 비트 내가 사용 gcc4.8.2에 FreeBSD의입니다

편집 :

다음

문제없이 실행되고 x86에서 컴파일 해당 x86_64에 코드입니다 :

#define INNERMUL \ 
asm(\ 
    "movq %5,%%rax \n\t" \ 
    "mulq %4  \n\t" \ 
    "addq %1,%%rax \n\t" \ 
    "adcq $0,%%rdx \n\t" \ 
    "addq %%rax,%0 \n\t" \ 
    "adcq $0,%%rdx \n\t" \ 
    "movq %%rdx,%1 \n\t" \ 
:"=g"(_c[LO]), "=r"(cy) \ 
:"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \ 
: "%rax", "%rdx", "%cc") 

#define PROPCARRY \ 
asm(\ 
    "addq %1,%0 \n\t" \ 
    "setb %%al  \n\t" \ 
    "movzbq %%al,%1 \n\t" \ 
:"=g"(_c[LO]), "=r"(cy) \ 
:"0"(_c[LO]), "1"(cy) \ 
: "%rax", "%cc") 

아마도 powerpc의 코드 동작이 무엇인지 분명하게 알 수 있습니다.

+0

PowerPC를 모르겠지만 인수 0을 레지스터로 요청하고 있습니다. '% 0'을 오퍼랜드로 사용하는 모든 연산을 레지스터 피연산자가 허용합니까? –

+0

@KerrekSB이 경우에는 C 경고가 아닌 어셈블러 오류가 발생합니다. C 컴파일러는 asm이 의미가 있는지 확인하지 않습니다. –

+0

제가 x86 어셈블리를 많이했기 때문에''% rax "'와'"% cc "'는 유효한 clobber 식별자가 아니므로 컴파일러는이를 무시할 것입니다. 올바른 방법은' "rax", "cc"' –

답변

3

두 경우 모두 입력/출력 변수에 cy_c[0]이 있습니다. 일치하는 제약 조건을 사용하여 결과를 출력 및 입력으로 올바르게 지정했습니다. 이것은 "1"이 확장 된 asm (레지스터 번호)에서 모호한 의미를 가지고 있기 때문에 PPC에만 해당 될 수 있습니다. 나는 x86에서만 작동합니다.

당신은 경고 (그것과 연관 될 수있는 버그) 한 번만 "=" 대신 "+" 출력 정량을 사용하여 입력/출력 변수로 변수를 지정하여 제거 할 수

:

#define INNERMUL asm(\ 
    " mullw 16,%2,%3  \n\t" \ 
    " mulhwu 17,%2,%3  \n\t" \ 
    " addc  16,16,%0  \n\t" \ 
    " addze 17,17   \n\t" \ 
    " lwz  18,%1   \n\t" \ 
    " addc  16,16,18  \n\t" \ 
    " addze %0,17   \n\t" \ 
    " stw  16,%1   \n\t" \ 
:"+r"(cy) \ 
,"+m"(_c[0]) \ 
:"r"(mu) \ 
,"r"(tmpm[0]) \ 
:"16", "17", "18","cc"); ++tmpm; 

#define PROPCARRY \ 
asm(\ 
    " lwz  16,%1   \n\t" \ 
    " addc  16,16,%0  \n\t" \ 
    " stw  16,%1   \n\t" \ 
    " xor  %0,%0,%0  \n\t" \ 
    " addze %0,%0   \n\t" \ 
:"+r"(cy) \ 
,"+m"(_c[0]) \ 
: \ 
:"16","cc"); 

편집 : GCC 확장 ASM 설명서에서 :

또한

Extended asm supports input-output or read-write operands. Use the constraint character ‘+’ to indicate such an operand and list it with the output operands.

내가 "%cc" 어떠했는지 확실하지 않다 홍보 일반적으로 그렇게하지 유효한 클러버 식별자 effix는 "%"입니다. x86에서 적절한 식별자는 "cc"입니다.

+0

이것은 cc에 대해 특별히 말하고있는 것을 조금 혼란스럽게합니다. 내 eddit을보세요. 어쩌면 둘 다 더 명확하게 나타납니다. – dhein

+0

@Zaibis' "1"'은 x86에 대한 유효한 저장 제한이 아닙니다. 따라서 컴파일러가 일치하는 제약 조건으로 모호하지 않게 해석됩니다. 적절한 레지스터 이름은'r1' 또는'rax'입니다. 내가 PPC 레지스터에서 알 수있는 것은 번호 식별자 뿐이다. 이 경우 컴파일러는''1 "'제약 - 즉 경고를 해석하는 방법을 모른다. '% cc'는 x86에 대한 유효한 clobber가 아닙니다. clobber 식별자는 x86 확장자 asm에서 결코 접두어로 '%'를 사용하지 않습니다. 나는 PPC에 대해서도 같은 것을 가정 할 것이지만, 이것을 테스트하기 위해 PPC 머신을 가지고 있지 않기 때문에 확신 할 수 없다. –

+0

'= '를'+'로 바꾸는 힌트를 시도했지만 경고는 여전히 동일합니다. – dhein

관련 문제