Welcome, Guest. Please login or register.

Author Topic: GCC asm() warning suppression options?  (Read 9517 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #14 on: June 28, 2009, 01:26:55 AM »
Quote from: Trev;513645
Yeah, I'm not doing so well with the ranges today.

I'm just happy to have some miggy coding time at all. Perverting C++ (in ANSI mode) with inline assembler always felt good :lol: If you think this is bad, you should see the divide by zero exception trick ;)

All I need now is to find an -fno-worry-about-asm-immediate-sizes option...
« Last Edit: June 28, 2009, 01:31:37 AM by Karlos »
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #15 on: June 28, 2009, 01:38:45 AM »
Quote from: Trev;513644

EDIT: For extra credit, let's do , too, i.e. rotRight32(-1) rotates left 1 bit. You could then generalize it as rotate(), where the sign of the operand determines the direction. Anyway....


LOL, not exactly in keeping with operators <> though, eh?
int p; // A
 

Offline x303

Re: GCC asm() warning suppression options?
« Reply #16 on: June 28, 2009, 01:53:33 AM »
Shouldn't you do something like this ???

__inline static unsigned long SWAP32(unsigned long a )
{
   unsigned long b;

   __asm__ ("lwbrx %0,0,%1"
           :"=r"(b)
           :"r"(&a), "m"(a));

return b;

}

x303 :D :D :D
« Last Edit: June 28, 2009, 01:57:03 AM by x303 »
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #17 on: June 28, 2009, 01:55:44 AM »
Quote from: x303;513653
Couldn't you do something like this ???

__inline static unsigned long SWAP32(unsigned long a )
{
   unsigned long b;

   __asm__ ("lwbrx %0,0,%1"
           :"=r"(b)
           :"r"(&a), "m"(a));

   return b;

}

x303 :D :D :D

For PowerPC, yeah, this is for M68K :)

BTW, these aren't byteswap functions, they are bitwise rotate functions. I have inlined asm for byteswapping anyway ;)
int p; // A
 

Offline Trev

  • Zero
  • Hero Member
  • *****
  • Join Date: May 2003
  • Posts: 1550
  • Country: 00
    • Show only replies by Trev
Re: GCC asm() warning suppression options?
« Reply #18 on: June 28, 2009, 01:57:20 AM »
@x303

On PowerPC, yes, but Karlos is talking 680x0.
 

Offline x303

Re: GCC asm() warning suppression options?
« Reply #19 on: June 28, 2009, 01:57:42 AM »
Try:

__inline static unsigned long SWAP32(unsigned long a)
{

   __asm__ ("rol.w #8,%0;swap %0;rol.w #8,%0"
            :"=d"(a):"0"(a));

   return(a);
}

x303 :D :D :D
 

Offline Trev

  • Zero
  • Hero Member
  • *****
  • Join Date: May 2003
  • Posts: 1550
  • Country: 00
    • Show only replies by Trev
Re: GCC asm() warning suppression options?
« Reply #20 on: June 28, 2009, 02:00:07 AM »
That's still not a rotation function. ;-) I don't think he's trying to do endian conversions.
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #21 on: June 28, 2009, 02:00:57 AM »
Quote from: x303;513656
Try:

__inline static unsigned long SWAP32(unsigned long a)
{

   __asm__ ("rol.w #8,%0;swap %0;rol.w #8,%0"
            :"=d"(a):"0"(a));

   return(a);
}

x303 :D :D :D


Sorry, you're missing the point. It isn't a byteswapping function, it's just a vanilla rotate. My 32-bit byteswap function looks pretty much like yours:

Code: [Select]

namespace Machine {
  // ...
  inline uint32 swap32(uint32 val)
  {
    asm(
      &quot;rol.w #8, %0\n\t&quot;
      &quot;swap %0\n\t&quot;
      &quot;rol.w #8, %0&quot;
      : &quot;=d&quot;(val)
      : &quot;0&quot;(val)
      : &quot;cc&quot;
    );
    return val;
  }
int p; // A
 

Offline Trev

  • Zero
  • Hero Member
  • *****
  • Join Date: May 2003
  • Posts: 1550
  • Country: 00
    • Show only replies by Trev
Re: GCC asm() warning suppression options?
« Reply #22 on: June 28, 2009, 02:22:51 AM »
Looks like gcc 2.95 falls through to a default warning("asm operand %d probably doesn't match constraints", i) for constraints that it doesn't know how to test.
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #23 on: June 28, 2009, 02:25:08 AM »
Quote from: Trev;513665
Looks like gcc 2.95 falls through to a default warning("asm operand %d probably doesn't match constraints", i) for constraints that it doesn't know how to test.

Yeah, they were hedging their bets there, eh? I need to install a higher version or use a cross compiler. 2.95 has a whole host of issues I have workarounds for that aren't actually needed on higher versions anyway.
int p; // A
 

Offline Trev

  • Zero
  • Hero Member
  • *****
  • Join Date: May 2003
  • Posts: 1550
  • Country: 00
    • Show only replies by Trev
Re: GCC asm() warning suppression options?
« Reply #24 on: June 28, 2009, 02:40:43 AM »
And here's the snippet from gcc 2.95.3's recog.c in asm_operand_ok():

Code: [Select]

        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
          /* For best results, our caller should have given us the
             proper matching constraint, but we can't actually fail
             the check if they didn't.  Indicate that results are
             inconclusive.  */
          result = -1;
          break;


So, it automatically falls through on matching constraints. What happens if you change "0" to "d0" to tell it operand 0 goes into a data register? EDIT: The point being that matched input operands aren't checked against the constraints previously specified for the output operand.
« Last Edit: June 28, 2009, 02:46:44 AM by Trev »
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #25 on: June 28, 2009, 11:52:29 AM »
Quote from: Trev;513668
And here's the snippet from gcc 2.95.3's recog.c in asm_operand_ok():

Code: [Select]

        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
          /* For best results, our caller should have given us the
             proper matching constraint, but we can't actually fail
             the check if they didn't.  Indicate that results are
             inconclusive.  */
          result = -1;
          break;


So, it automatically falls through on matching constraints. What happens if you change "0" to "d0" to tell it operand 0 goes into a data register? EDIT: The point being that matched input operands aren't checked against the constraints previously specified for the output operand.


Well. I'll have a look but I was under the impression the "0" was the correct constraint here:

asm("rol.l %1, %0" : "=d"(val) : "I"(N), "0"(val) : "cc");

since you want the compiler to keep the output in the same register as the first input. Compare the above with the dynamic version:

Code: [Select]

inline uint32 rotRight32(uint32 bits, uint32 val)
{
  asm("ror.l %1, %0" : "=d"(val) : "d"(bits), "0"(val) : "cc");
  return val;
}


Using "d" rather than "d0" allows the compiler to choose which registers to use whenever the function is inlined. I figured this would be a lot better than forcing the use of any specific data register.
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #26 on: June 28, 2009, 12:03:58 PM »
As I expected, changing "0" to "d0", breaks, since there's nothing forcing the input into d0 in the first place:

Code: [Select]

movel #-1430532899,d4 <- 0xAABBCCDD
[B] movel d4,sp@- <- no rotate done for zero bits, this is fine[/B]
movel d4,sp@-
pea LC5
lea _printf,a2
jbsr a2@
addw #12,sp
[B]#APP
rol.l #4, d0 <- where is d0 initialised?
#NO_APP[/B]
movel d0,sp@-
movel d4,sp@-
pea LC5
jbsr a2@
addw #12,sp


Whatever was already in d0 gets shifted and the compiler has to work around ensuring d0 is preserved around my asm() calls, despite the fact it never initialises it with the test data (which it decided to put in d4 here).
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: GCC asm() warning suppression options?
« Reply #27 on: June 28, 2009, 12:19:34 PM »
@trev

Amazingly, I just tried the specialization route for the 0/16 case and it worked. When I originally worked on this I distinctly remember template specializations in general causing problems.

That said, I've gone back to the single function(s) and just made it handle all values of N:

Code: [Select]
 template<const uint32 N> inline uint32 rotRight32(uint32 val)
  {
    if (N&31) {
      // only rotate when modulus 32 > 0
      if ((N&31) < 9) {
        asm(&quot;ror.l %1, %0&quot; : &quot;=d&quot;(val) : &quot;I&quot;(N&31), &quot;0&quot;(val) : &quot;cc&quot;);
      }
      else if ((N&31)==16) {
        asm(&quot;swap %0&quot; : &quot;=d&quot;(val) : &quot;0&quot;(val) : &quot;cc&quot;);
      }
      else if ((N&31)>23) {
        // use opposite rotate for N > 23
        asm(&quot;rol.l %1, %0&quot; : &quot;=d&quot;(val) : &quot;I&quot;(32-(N&31)), &quot;0&quot;(val) : &quot;cc&quot;);
      }
      else {
        // use register rotate for all intermediate sizes
        asm(&quot;ror.l %1, %0&quot; : &quot;=d&quot;(val) : &quot;d&quot;(N&31), &quot;0&quot;(val) : &quot;cc&quot;);
      }
    }
    return val;
  }
« Last Edit: June 28, 2009, 12:44:05 PM by Karlos »
int p; // A
 

Offline Trev

  • Zero
  • Hero Member
  • *****
  • Join Date: May 2003
  • Posts: 1550
  • Country: 00
    • Show only replies by Trev
Re: GCC asm() warning suppression options?
« Reply #28 on: June 28, 2009, 07:33:01 PM »
Quote from: Karlos;513700
As I expected, changing "0" to "d0", breaks, since there's nothing forcing the input into d0 in the first place:

Hmmm, well the intent wasn't to tell it to use d0, but rather that it should use the data register that matches operand 0. (Incidentally, "r0" works correctly on x86, but there is, of course, no r0 register to work around.) Whitespace should be ignored, so a constraint of "d0" might produce the correct result and get rid of the warning; otherwise, I guess the warning is there to stay.
« Last Edit: June 28, 2009, 07:42:13 PM by Trev »
 

Offline Trev

  • Zero
  • Hero Member
  • *****
  • Join Date: May 2003
  • Posts: 1550
  • Country: 00
    • Show only replies by Trev
Re: GCC asm() warning suppression options?
« Reply #29 from previous page: June 28, 2009, 07:41:24 PM »
Quote from: Karlos;513702

That said, I've gone back to the single function(s) and just made it handle all values of N:


I think your solution is best anyway, as values equivalent to 0 and 16 won't be reduced by the specialized templates, and you won't get the expected result.

I also think your idea of letting N < 0 (if signed inputs are allowed) and N > 31 fail at compile time is a good idea if you're worried about source typos.

For fun, though, I still think a general purpose rotation template is a cool idea. ;-) It's too bad C++ won't let you create custom operators without using macros or some other magic. You could throw in <<<, >>>, ^<<, ^>>, or whatever you want. Actually, would it be that difficult to add those to gcc? I don't know. Nothing wrong with non-standard extensions as long as they're well documented.