English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 30 May 2014, 09:22   #1
Asman
68k
 
Asman's Avatar
 
Join Date: Sep 2005
Location: Somewhere
Posts: 829
VBCC code generation

Hi

For following code
Code:
define CIAADDR (UBYTE*)(0xbfe001)
UBYTE fire(void)
{
    return (!(*CIAADDR & 128));
}
vbcc generate following asm
Code:
	near	code
	near	a4,-2
	opt	0
	opt	NQLPSMRBT
	public	_fire
	cnop	0,4
_fire
	movem.l	l485,-(a7)
	moveq	#0,d0
	move.b	12574721,d0
	and.l	#128,d0
	bne	l38
	moveq	#1,d1
	bra	l39
l38
	moveq	#0,d1
l39
	move.b	d1,d0
l485	reg
l487	equ	0
	rts
Main question is: Is there possibility to generate better code for the above routine ? I mean about some magic switch or something in vbcc. I used following options: -S -O3 -c99 -sd -sc to generate above asm code.

I don't understand why and.l is used, I think that better will be and.b in this case. Is there a way to change this and.l --> and.b and then remove first moveq #0,d0 ?

Funny things happen when I'm trying to use __reg for same routine
Code:
    __reg("d1") UBYTE r = (!(*CIAADDR & (128)));

    return r;
then vbcc generated

Code:
	near	code
	near	a4,-2
	opt	0
	opt	NQLPSMRBT
	public	_fire
	cnop	0,4
_fire
	movem.l	l485,-(a7)
	moveq	#0,d0
	move.b	12574721,d0
	and.l	#128,d0
	bne	l38
	moveq	#1,d2
	bra	l39
l38
	moveq	#0,d2
l39
	move.b	d2,d0
l485	reg	d2
	movem.l	(a7)+,d2
l487	equ	4
	rts
And who eat my d1 register ?

Any comments and explanation are welcome.
Asman is offline  
Old 30 May 2014, 16:06   #2
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,200
Why did it do AND.L? Because you specifically (though implicitly) asked it to. The default type of an integer is int, which in turn is 32-bits. If you want 128 to represent an unsigned char value, try changing the notation of 128 to 128UC or '\0x80' using single quotes (just typing this from memory, I hope that's right). I know that on SAS/C when you wanted a long constant value instead of a 16-bit int, you had two options: Hit a switch on the compiler that defined all ints as 32 bits instead of 16, or put a capital L after your constant to indicate its type. Another way would be to cast the 128 to UBYTE, which should inline the conversion using constant folding.

*edit*
As another suggestion, try #include <stdbool.h> at the beginning of your code so you can return a bool value and cast that to a UBYTE. It might be able to optimize the branches to a SNE D0 and an AND.B #1, D0 eliminating the need for D1 altogether though it might not do this if you're not optimizing for an '060. Like this:
Code:
#include <stdbool.h>

/* definition of CIAADDR */

UBYTE fire() {
  return (*CIAADDR&(UBYTE)128==(UBYTE)128)&(UBYTE)1;
}

Last edited by Samurai_Crow; 30 May 2014 at 16:24. Reason: Added suggestion
Samurai_Crow is offline  
Old 31 May 2014, 09:36   #3
Asman
68k
 
Asman's Avatar
 
Join Date: Sep 2005
Location: Somewhere
Posts: 829
Thanks for answer Samurai Crow. But ... vbcc do not like your suggestion
I even tried with (to check if add.b will be generated)
Code:
	UBYTE c = 128;
	UBYTE r = *CIAADDR;

	return c & r;
and vbcc generate

Code:
	near	code
	near	a4,-2
	opt	0
	opt	NQLPSMRBT
	public	_fire
	cnop	0,4
_fire
	movem.l	l478,-(a7)
	move.b	12574721,d0
	and.l	#255,d0
	and.l	#128,d0
l478	reg
l480	equ	0
	rts
About stdbool.h, as I checked then I don't have such file in includes.

So it not big deal this and.l but I thought that is possible to optimize a bit generated output.

Edit:
There is always another way: back to pure asm
Asman is offline  
Old 15 August 2014, 12:04   #4
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 725
Hmm, old thread, but look at the gcc output

-m68000
Code:
_fire:
        moveb 12574721,d0
        extw d0
        extl d0
        notl d0
        addl d0,d0
        subxl d0,d0
        negl d0
        rts
and for >=68020
Code:
_fire:
        moveb 12574721,d0
        eorw #128,d0
        bfextu d0{#24:#1},d0
        rts
Now, I can't say I can follow the logic on the 68000 output, but the >=020 part is sort of cool ;-)
alkis is offline  
Old 15 August 2014, 13:12   #5
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by alkis View Post
Code:
_fire:
        moveb 12574721,d0
        eorw #128,d0
        bfextu d0{#24:#1},d0
        rts
Now, I can't say I can follow the logic on the 68000 output, but the >=020 part is sort of cool ;-)
It may be cool but it's not that great. It did really good combining the !& into xor but then it failed when it used the BFEXTU instruction. The best savings would come from inlining the function though.

Last edited by matthey; 15 August 2014 at 13:18.
matthey is offline  
Old 15 August 2014, 13:34   #6
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,052
Code:
_fire:
        moveb 12574721,d0
        add.b d0,d0
        subx.l d0,d0
        addq.l #1,d0
        rts
Don_Adan is offline  
Old 15 August 2014, 13:56   #7
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,552
Quote:
Originally Posted by Asman View Post
[/code]About stdbool.h, as I checked then I don't have such file in includes.
That's a C99 feature still missing in V0.9b. Will be part of V0.9d.

Quote:
So it not big deal this and.l but I thought that is possible to optimize a bit generated output.
The code generator likes to work with 32 bits on a 32-bit CPU. I guess this is because the propability that all 32 bits of an operation are needed later is quite big.

Quote:
There is always another way: back to pure asm
Or do it like this:
Code:
UBYTE asmfire(void)="\tbtst\t#7,$bfe001\n\tsne\td0";

UBYTE fire() {
  return asmfire();
}
phx is offline  
Old 15 August 2014, 16:57   #8
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,862
Quote:
Originally Posted by Asman View Post
There is always another way: back to pure asm
Indeed. On 68k machines it may not be such a bad idea to use assembly language, and besides, it's fun

Side note: Those C compilers sure write good code
Thorham is offline  
Old 16 August 2014, 11:48   #9
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 725
...And from gcc 4.6.4 (atari-mint target)

Code:
_fire:
        move.b 12574721,%d0
        not.b %d0
        lsr.b #7,%d0
        rts
alkis is offline  
Old 17 August 2014, 09:33   #10
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by alkis View Post
...And from gcc 4.6.4 (atari-mint target)

Code:
_fire:
        move.b 12574721,%d0
        not.b %d0
        lsr.b #7,%d0
        rts
Looks good. Maybe the rumors of GCC improving again are true. Makes me want to adapt the compiler to use vasm or add some kind of a system to convert elf 68k to Amiga hunk.
matthey is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
From gcc to vbcc. Cowcat Coders. General 9 06 June 2014 14:45
vbcc: no startup aragon Coders. C/C++ 2 16 February 2014 14:52
Mixed 68k / PPC code on VBCC. Cowcat Coders. General 10 01 August 2013 16:01
Compiling CLib37 with VBCC 0.9 tnt23 Coders. General 2 29 July 2013 10:28
VBCC 0.8j for Windows hitchhikr Coders. General 11 09 October 2008 00:58

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 17:02.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10286 seconds with 13 queries