Is it possible to run a parser through the assembler
output of Norcroft to replace floating point ops with
branches to FP emulation code and then recompile the
assembler?
If so, couldn't that be used to speed up large C
programs which use FP without having to replace all
the FP operations in the code with calls to a library?
Just a though...
Cheers,
Jon.
It could be done; I thought of this a year or so ago, but decided,
well, if I really invest huge amounts of effort in doing this, is
anyone *really* going to bother? And I decided not to :-(
If anyone wants to change my mind, maybe I'll give it a go after
all :-)
Neil
--
Neil A. Carson
Marketing Director Causality Limited (London, UK)
Tel/Fax: +44 (0)181 930 7408 Mobile: +44 (0)370 593183
Email: ne...@causality.com WWW: http://www.causality.com.
Would you believe I spent last saturday writing part of such a tool!
I make no guarantees I'll ever get around to finishing it though >8*)
> If so, couldn't that be used to speed up large C programs which use FP
> without having to replace all the FP operations in the code with calls
> to a library?
At best the FP lib saves a factor of about 6 I believe. Unless you want
to write some REALLY cunning code it will be tough to get anywhere near
this amount.
I need a factor of 3 for the project I have in mind, and its gonna be
touch and go.
Robin
--
Robin Watts, Email: <mailto:Robin...@wss.co.uk>
Warm Silence Software, WWW: <http://www.wss.co.uk/>
P.O.Box 28, Woodstock, Tel: 0585 487642 (or Home: 01608 737172)
Oxfordshire, OX20 1XX Fax: 01608 737172
Arizona: A company called "Guns For Hire" stages gunfights for Western
movies, etc. One day, they received a call from a 47 year old woman, who
wanted to have her husband killed. She got 4 and a half years in jail.
>In article <ant03200...@isiselec.demon.co.uk>, Jon Harrop
><URL:mailto:Jon.H...@isiselec.demon.co.uk> wrote:
>>
>>
>> Is it possible to run a parser through the assembler
>> output of Norcroft to replace floating point ops with
>> branches to FP emulation code and then recompile the
>> assembler?
>>
>> If so, couldn't that be used to speed up large C
>> programs which use FP without having to replace all
>> the FP operations in the code with calls to a library?
>>
>It could be done; I thought of this a year or so ago, but decided,
>well, if I really invest huge amounts of effort in doing this, is
>anyone *really* going to bother? And I decided not to :-(
>If anyone wants to change my mind, maybe I'll give it a go after
>all :-)
Go for it !
Maybe just a new verion of the stubs library or so is sufficient ..
just replacing the Copro codes with BL won't work though ...
(remember that a BL changes R14 ... )
So replacing just one opcode with another simply can't be done .. : (
Anyway if you have some bright idea about what might work , let me
know !
Bye ,
Jan Rinze.
>Is it possible to run a parser through the assembler
>output of Norcroft to replace floating point ops with
>branches to FP emulation code and then recompile the
>assembler?
I thought about doing a similar thing in order to get my C++ code to
compile into a module (cfront generates code that cannot be placed by the
C compiler in a module). I think that you would find that you hit the
same problem that I did. Namely, when you compile -S to get the
assembler version, you LOSE all relocations. This would certainly
affect module code, although I am uncertain whether this would affect
application code too.
--
Stewart Brodie, Electronics & Computer Science, Southampton University.
http://www.ecs.soton.ac.uk/~snb94r/
What's the problem compiling C++ code into a module using cfront? I can't
remember the compilation flags, but I've successfully managed it in the past,
and have been happily using such modules for quite a long time now. The only
problem is with the initialisation of static objects which can be a bit
tricky.
--
Dan Ellis, http://www.apltd.co.uk/
Software Engineer, http://www.pod51.demon.co.uk/
Applied Photophysics Ltd. mailto:del...@apltd.demon.co.uk
Correct. You may need to create a stub for *every* single FP instr.
But that's not the only problem: you either want to writeout all
possible combinations of the register specifiers, which is too large,
or decode them, which takes too much time. All in all you never gain
anything substantial.
But... it has already been done:
> Anyway if you have some bright idea about what might work , let me
> know !
Well, our compiler actually supports inline FP code by calls to a
library. The library is 3 times as fast as the FPE.
Bytemarks are +- Int 3.00 / FP 0.11 for a 233 MHz SA.
I'm working on an optimized version, which will be about 3 times faster.
Wilco
-------------------==== Posted via Deja News ====-----------------------
http://www.dejanews.com/ Search, Read, Post to Usenet
> What's the problem compiling C++ code into a module using cfront? I
> can't remember the compilation flags, but I've successfully managed it
> in the past, and have been happily using such modules for quite a long
> time now. The only problem is with the initialisation of static objects
> which can be a bit tricky.
The virtual function table is the problem. It's static data
with pointers in, which can't be under -zM.
Tom
--
Tom Hughes (t...@compton.demon.co.uk)
http://www.compton.demon.co.uk/
...I spent most of my money on beer and women - the rest I just wasted.
> What's the problem compiling C++ code into a module using cfront? I can't
> remember the compilation flags, but I've successfully managed it in the past,
> and have been happily using such modules for quite a long time now. The only
> problem is with the initialisation of static objects which can be a bit
> tricky.
Did you hack your code or avoid virtual functions (the main things that
cause the problem)? C++ isn't much "fun" without virtual functions.
--
\_________________
\ http://www.tcp.co.uk/~tonyh/
The Curling Pages \ The home of WinEd, Bombz and NewsFind for RISC OS
> Anyway the whole idea of writing modules in anything other than assembler
> seems somewhat of an anathema to me anyway - they're so close to the system
> that even writing in just c you're not sure exactly what's going on half the
> time (although I suppose if you spend sufficient time doing so it'll become
> second nature).
I think it's a good idea for some stuff, eg networking, then you can use
existing libraries etc. The Internet module and drivers obviously have
to be modules, but I think by using C they managed to base it on BSD
code. Writing Internet clients and servers as modules has distinct
advantages as well, because it can allow transfers to continue in the
background while the desktop is busy.
>What's the problem compiling C++ code into a module using cfront? I can't
>remember the compilation flags, but I've successfully managed it in the past,
>and have been happily using such modules for quite a long time now. The only
>problem is with the initialisation of static objects which can be a bit
>tricky.
"a bit tricky"?
Impossible without some severe hacking around because the C compiler
refuses to allow static initialisers containing pointers to code when
invoked with -zM.
You might not think that having static objects containing pointers to
function was common - except that's just how cfront stores its vtables
for the virtual functions :-/
Hence you *can* use cfront to build RISC OS relocatable modules - as
long as you avoid virtual functions (which basically rules out
inheritance) I have spent many days attepting to get around this by
fiddling the output of cc -S -zM but the problem is that the
relocations are discarded - and the compiler doesn't encode the static
data offset offset from the stack limit into the code but relies on
relocations for storing it - so you end up also not being able to
access static data! Once you get to that stage, you're looking at
hacking the AOF file itself. Now the compiler (Acorn C++ Language
System 3.1 [May 25 1995] together with Norcroft RISC OS ARM C vsn 5.06
(Acorn Computers Ltd) [May 25 1995]) *will* generate you an AOF file.
It will issue an error for each class that requires a vtable, but it will
produce the AOF file. There's only one slight problem: the vtables
aren't in it. Try compiling this C++ source file with:
c++ -c c++.testfile -zM -zO
#include <stdlib.h>
class A { virtual void f(void); };
class B : public A { void f(void); };
void doexit(void) { }
void init(void) { A a; B b; (void) a; (void) b;
atexit(doexit);
}
I've scrunched it up a bit to reduce the apparent size of the code :-)
The reason for the atexit stuff is to prove that addresses of functions
that are only known after run-time relocation can be used. The -zO
option forces doexit to be in a different AREA to init - thus proving
that this works across different AREAs.
You will get 2 errors complaining about static init. to data A::__vtbl
and B::__vtbl. Looking at the AOF file with DecAOF and ignoring the
C$$Code areas, there is an area C$$Data, Alignment 4, Size 8, 2
relocations, R/W Data. The contents of this area are zeroes. The
Relocation table for this is:
At 000004: Word [00000000] displaced by symbol __vtbl__1B
At 000000: Word [00000000] displaced by symbol __vtbl__1A
More importantly, the Symbol Table states:
__vtbl__1A : External reference
__vtbl__1B : External reference
So you will (and do) get link errors when you attempt to link the
module. It is not unreasonable for the compiler to decide to throw away
the vtables when it considers it an error for them to be there. However,
I would much prefer that it did not consider it to be an error!
The approach I took was to pass all the cfront output through an awk
script (remember that I don't know perl and didn't want to have to
learn it before I could hack this stuff so I stuck with gawk because i
knew it). The awk script knew how to recognise cfront vtables and it
read them in and instead generated a zero-initialised vtable and a
global initialiser function for each source file which simply went
through assigning the function addresses to the members of the struct
in turn. That was the easy bit. Arranging for all these global
initialisers to be called is also easy up to a point. When you invoke
the linker with the -c++ option, it looks for functions in each AOF
file with a particular name pattern (I forget the exact name). The
linker builds a list of these functions and embeds them together with a
little piece of code which invokes each one in an arbitrary order. The
problem is then when does this bootstrap code get called. Well, it
gets called by code which cfront inserts specially at the beginning of
the main() function. Now in RISC OS modules, when does main() get
called? When you enter it through its start point.
That's one big problem.
Therefore none of your global initialisers are called UNTIL you start
your module. ie. they will not have been called by the time your code
starts executing its handler for the module init entry point. Now
there is no way I can see of getting the linker to build separate lists
of initialisers for initialisation entry and start entry and call them
at the appropriate time. Also, ISTR that I found I couldn't call the
bootstrap function manually. It's all a bit of a mess currently.
There is no simple solution I know of. I would be absolutely delighted
if there was one ... anybody?
One idea would be for the compiler to place objects declared "static
const" in a CODE area - but that causes problems because you need to
offset all the pointers by the base of the code at run-time and it is
dangerous putting non-const stuff in a CODE area in case it ends up in
read-only memory.
One potential solution which I haven't had time to explore in detail
would be the following:
Parse the output of cfront to pick up the vtables and replace all the
pointers to function with zero (the C compiler won't mind that). (In
fact, it may be necessary to initialise them to non-zero to stop it
placing it in a zero-initialised area if that causes a problem with that
comes next)
Run through cc -zM -c to generate the AOF file.
Edit the AOF file to add each vtable in its own area (for simplicity)
and insert relocation directives to ensure that each word of the vtable
is displaced by the appropriate symbols.
I don't think this is too hard if somebody were to sit down with time
to write it who understood what they were doing. But that person is
not me. I'm not even certain it would work, but I haven't spotted
anything obvious that would prevent it from working (the idea of
statically scoped functions rings alarm bells, but I don't think it's a
problem as long as you have access to the symbol table for the entire
file and can generate a word of data indicating the offset into the
code area and displace that by the base of the area - but that might be
total utter rubbish).
Does anybody see any problems with this approach?
Does anybody want to have a go at implementing it? Manipluating AOF
files is relatively easy because you can just read in each chunk into
memory (forget any clever optimisations about poking about in the AOF
file - it's not worth the extra effort) and whack the file out again.
Damn - I've spent half an hour writing all this - I'd better get back to
my real work of writing my thesis even though it's far less appealing
that dicussing the intracacies of fiddling with AOF files in order to
get around problems with the C++ translator generating code that the C
compiler object to :-)
>In article <ant10195...@pod51.demon.co.uk>
> Dan Ellis <d...@pod51.demon.co.uk> wrote:
>> Anyway the whole idea of writing modules in anything other than assembler
>> seems somewhat of an anathema to me anyway - they're so close to the system
>> that even writing in just c you're not sure exactly what's going on half the
>> time (although I suppose if you spend sufficient time doing so it'll become
>> second nature).
>I think it's a good idea for some stuff, eg networking, then you can use
>existing libraries etc. The Internet module and drivers obviously have
>to be modules, but I think by using C they managed to base it on BSD
>code.
The specific code that I wanted written in C++ was my DNS Resolver
module. The class hierarchy is clear for that and I originally wrote it
all in C++. Then Tom Hughes translated it into C for me - pretty well
doing a manual cfront job on it but without the aggravation.
>Writing Internet clients and servers as modules has distinct
>advantages as well, because it can allow transfers to continue in the
>background while the desktop is busy.
The advantage of it being in a module means you can drive it with events
and service calls rather than needing to get control via Wimp_Poll.