Sender: rich AT phekda DOT freeserve DOT co DOT uk Message-ID: <394FDC74.E8712E7F@phekda.freeserve.co.uk> Date: Tue, 20 Jun 2000 22:04:52 +0100 From: Richard Dawe X-Mailer: Mozilla 4.51 [en] (X11; I; Linux 2.2.14 i586) X-Accept-Language: de,fr MIME-Version: 1.0 To: Eli Zaretskii CC: djgpp AT delorie DOT com, rich AT phekda DOT freeserve DOT co DOT uk Subject: Re: Inline asm: lcall & various binutils versions References: <39060495 DOT 8CA597B0 AT bigfoot DOT com> <39069F55 DOT 639FE192 AT is DOT elta DOT co DOT il> <39341DE2 DOT 20CA1843 AT bigfoot DOT com> <200005302109 DOT AAA27505 AT alpha DOT netvision DOT net DOT il> <394E733C DOT FE5BAB89 AT phekda DOT freeserve DOT co DOT uk> <200006201739 DOT UAA28575 AT mailgw1 DOT netvision DOT net DOT il> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com Hello. Eli Zaretskii wrote: > Thanks for looking into this. No worries - sorry it took a while. ;) It's a problem that affects quite a few things I think - DJGPP (as discussed on djgpp-workers), libsocket, libwin, probably others. > > The answer seems to be that there is no easy way. > > Gosh, I _hate_ incompatible changes that don't leave any escapes like > a command-line option to get the old behavior! Yes, it's a big PITA. =( > > 3. Detect which version of binutils is being used and adjust the code > > appropriately. Perhaps the most likely, but ugly in terms of code. :( > > This sounds like the lesser-evil solution. Yep, I left the best solution until last. 8) > Here's a starting point for Makefile magic to do that: > > BNU_VERSION := $(shell as --version | sed -n 's/^GNU assembler //p') > > (This is only a starting point, since you will need to define > BNU_MAJOR, BNU_MINOR and such likes, given BNU_VERSION.) > > Then use "gcc -DBNU_MINOR=..." to get this info into the > preprocessor. How about this: ---Start Makefile--- # # Makefile for bnuver # SHELL = /bin/sh GAS_VERSION := $(shell as --version | sed -n 's/^GNU assembler //p') GAS_MAJOR := $(shell echo $(GAS_VERSION) \ | sed -n 's/^\([0-9]*\).*/\1/p') GAS_MINOR := $(shell echo $(GAS_VERSION) \ | sed -n 's/^[0-9]*\.\([0-9]*\).*/\1/p') GAS_MINORMINOR := $(shell echo $(GAS_VERSION) \ | sed -n 's/^[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/p') CFLAGS += -save-temps CFLAGS += -DGAS_MAJOR=$(GAS_MAJOR) CFLAGS += -DGAS_MINOR=$(GAS_MINOR) CFLAGS += -DGAS_MINORMINOR=$(GAS_MINORMINOR) default: display-flags asmifdef display-flags: @echo gas version $(GAS_VERSION) '->' \ $(GAS_MAJOR) $(GAS_MINOR) $(GAS_MINORMINOR) @echo 'CFLAGS =' $(CFLAGS) ---End Makefile--- ---Start asmifdef--- int main (int argc, char *argv[]) { __asm__ ("nop \r\n" #if GAS_MAJOR >= 2 && GAS_MINOR > 8 "nop \r\n" #endif /* IFDEFTEST */ "nop \r\n"); } ---End asmifdef--- I tested this with binutils 2.9.5.0.22 with sed 3.02 on Linux (where as says '2.9.5' as the version) and it appears to work. I used GAS_* here, because it could be different to the version of binutils, plus it's the thing we're actually concerned with. I think there's enough granularity in version number to go round there. ;) Is this satisfactory? My sed knowledge is limited (*), but this seems to do the trick. (*) I always try to use Perl regexps and it fails. :( I'll use this to fix up libsocket, libwin with this sometime. It took me a while to work out how to put #ifdefs in inline assembly. Eli, you probably knew this already, but: You have to rely on C's string concatenation. [ If you put '#ifdef' in the inline assembly, then it becomes an assembly comment and does nothing. ;) I couldn't see a way to propagate -DSOMETHING into the assembly so that '.ifdef SOMETHING' could be used. ] This feels like less of a hack than relying on gas to generate the right code in spite of a warning. Bye, -- Richard Dawe [ mailto:richdawe AT bigfoot DOT com | http://www.bigfoot.com/~richdawe/ ]