Welcome, Guest. Please login or register.

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

Description:

0 Members and 1 Guest are viewing this topic.

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #14 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: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #15 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 KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #16 on: June 28, 2009, 07:41:46 PM »
IIRC, d0-d7 and a0-a7 are understood as register specifications for M68K backend with asm(). I'll see if "d 0" works.

To be fair, I can live with the warning as it always seems to generate the correct code. It was just a bit annoying.
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #17 on: June 28, 2009, 07:50:41 PM »
Quote from: Trev;513751
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.


Actually, the revised version essentially treats everything as modulo . I could remove it :)

Quote
For fun, though, I still think a general purpose rotation template is a cool idea. ;-)


Feel free to use the code for inspiration :lol: It wouldn't be difficult to make it take a signed shift. Don't forget to throw in a dynamic version (for variable shifts too), though here checking for the sign of the shift exposes the runtime weakness in the plan. The check would probably take more cycles than the operation performed.

Quote
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.


Well, inventing new operators has a lot of hidden traps. You only have to look at the post/pre increment/decrement operators to see how gnarly that could get.

The thing is, rotate is a commonly supported CPU operation. I can't see why C wouldn't have an operator for it originally.
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #18 on: June 28, 2009, 10:09:17 PM »
Thanks to the power of templated inline assembler, it doesn't matter how bad the m68k optimizer is, you've basically taken matters into your own hands :lol:

The things we do for cycles, eh?
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #19 on: June 29, 2009, 11:29:10 PM »
I use make -j=4 on my quad core and never had any problems with it :)

-edit-

Quote
So, we'll see if newer GCCs are any better at optimizing rotatations.

You're building gcc 4.4 for an m68k backend just to check this? That's hardcore :D

Blimey, time to hit the sack :-/
« Last Edit: June 29, 2009, 11:40:11 PM by Karlos »
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #20 on: June 30, 2009, 10:13:03 AM »
Quote
It's even decided that a register based rotate right is faster than an immediate rotate left, I guess. Or maybe not. I can't get it to produce a rotate left. I guess gcc isn't an ambiturner.

Hmm, unusual. I'm pretty sure an immediate left shift of 1 place ought to be faster than a register based shift right of 31 since you spare yourself the cost of the additional move.l #31, d1. It also reduces register pressure too, which could make all the difference in real code.

Probably in the test code here there's no need for it to do that.

-edit-

Incidentally, you might want to compile that test code with -fomit-frame-pointer ;)
« Last Edit: June 30, 2009, 10:20:15 AM by Karlos »
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #21 on: June 30, 2009, 02:34:52 PM »
Quote from: Piru;513958
Code: [Select]
if [ -a /proc/cpuinfo ]; then
    export CONCURRENCY_LEVEL=$(($(grep -c processor /proc/cpuinfo) * 2 + 1))
    export MAKEOPTS=&quot;-j${CONCURRENCY_LEVEL}&quot;
fi

Why wouldn't it be robust?


Perhaps the Makefiles are subtly flawed? There could be bits that have to be compiled before others that may not be guaranteed with concurrent jobs?

Just guessing here.
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #22 on: June 30, 2009, 04:59:04 PM »
Quote from: Trev;513971
You have to trust that your target makefile is essentially thread-safe, i.e. all dependencies are properly documented for synchronization, no race conditions exist in similar commands used by different rules, etc.

That's basically what I was trying to suggest. I've not built anything as large as gcc and the toolchain with multiple concurrent jobs, but I can imagine concurrency issues can exist.

-edit-

Quote
Yeah, I'm really not sure why, since ror.l #n,Dn and ror.l Dx,Dn execute in the same number of cycles assuming n == Dx. Barring outside influences, the only reason to use a register is for a shift >8 or <24 (>8 in the opposite direction), as you've done in your template. Right?

Well, you could probably do it with two successive rotates, but I figured that the register method might be better than a pair of rotates. Having said that, I didn't test the latter. You'd swap a move for a rotate but you'd gain a free register overall.

I'll have to look into that.
« Last Edit: June 30, 2009, 05:02:21 PM by Karlos »
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #23 on: June 30, 2009, 07:05:52 PM »
Quote from: Trev;513983
I'm leaning towards trusting the compiler. One can always hand optimize code, but writing specializations for all possible cases? Tedium. ;-)


The fact is, I needed rotate operations, so I wrote the functions (in pure C++) for 8/16 and 32-bit rotate.

After analysing the output (from older gcc) it was clear that the emitted code wasn't very good. So, I made the inline assembler implementations you saw one of in this thread. There's no question they produce better code now than when they were using shifts and ors ;)

Of course, if I use a better compiler, there's nothing stopping me turning off the inline assembler versions. It's  just a compilation directive to use the asm tuned or normal C ones.
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #24 on: June 30, 2009, 07:57:32 PM »
Quote from: Trev;514002
Oh, for sure. I was just thinking that for the newer compiler, the optimizer should be much better at dynamically optimizing for all possible scenarios than I would be at hand coding them. I'm no amigaksi, after all.


ROFL (+1)

Tell you what. Seeing as you've compiled a working 4.4 compiler, we could try some synthetic benchmarks. My template rotate versus a standard implementation based on shifting and or'ing that the compiler is left to optimize.

I'd actually be quite interested in the results :)
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #25 on: June 30, 2009, 10:39:51 PM »
Quote from: Trev;514024

But guess what! N==0 (or any value that reduces to 0) throws this:

Code: [Select]
warning: asm operand 1 probably doesn't match constraints

Bugger! It still compiles, still runs, and doesn't leave any dead code. Not sure how to get rid of the warning, though, if it's parsing code it shouldn't be parsing after templatization. Template misuse, maybe?

Boo! So you basically get the same warning I started this whole thread in aid of? :roflmao:

It's only taken us 50 posts to come full circle :D

-edit-

Template misuse? Are you suggesting that the use of high level metaprogramming devices like templates to emit conditionally selected hand generated code directly for the assembler stage might be outside the original scope? ;)

It isn't quite as cheeky as the processor trap -> C++ exception throw that I used. Frankly, I'm amazed that bugger worked at all. Inside the (asm) m68k trap handler (which you install into your exec Task structure), you poke the stack frame to change the return address to a function which does nothing other than throw an exception of a type suitably mapped to the nature of the trap. Saves having to check for divide by zero when you can just put a try/catch block around a bit of code and trap ZeroDivide ;)
« Last Edit: June 30, 2009, 10:53:04 PM by Karlos »
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #26 on: June 30, 2009, 10:47:04 PM »
Quote
Well, it's m68k-elf with no real back end. We could count cycles in a simulator, I suppose. :-)


Or I could write the function to be benchmarked, you can compile it and post the assembler output of the function and I'll put that source back into a test project?
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #27 on: June 30, 2009, 11:11:41 PM »
Quote from: Trev;514036
Or that. :-P


It will have to wait though, I have a date with the shower then bed. I'm wiped.
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #28 on: June 30, 2009, 11:34:56 PM »
Quote from: Trev;514038
Actually, that sounds like a quite valid use. Within the design of the operating system even. (Well, sort of. But manipulating stack frames is kind of at the core of exception handling, isn't it?)

Well, yes, but not quite like this. Normally C++ exceptions operate entirely in userland and unwind the stack of the process they were fired in (well, if you omit threadsafe.lib in old gcc, watch the fun when that assertion fails).

Here, we are actually in the supervisor state, altering the saved stack frame of the thread that performed the illegal op and altering the return address such that when the trap is complete, it returns to a completely different location. Right into our code that throws the exception.

The old thread about that is on here somewhere. Amazingly it really does work very well and I built it into my codebase. I'm currently figuring out how to accomplish the same thing inside a signal handler under posix, but it always seems as if the exception occurred inside main() rather than where it really happened.

-edit-

http://www.amiga.org/forums/showthread.php?t=25181 here
« Last Edit: June 30, 2009, 11:40:13 PM by Karlos »
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16878
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: GCC asm() warning suppression options?
« Reply #29 from previous page: July 01, 2009, 07:41:32 AM »
Quote from: Trev;514045
Were you ever able to simulate a null pointer exception, short of wrapping all pointers in a class and overloading the indirection operator?


No. Well, I didn't try too hard as I was never able to get mmu.library working on my system. Every time I'd install it, it would drop to bits.
int p; // A