llvm-gcc is able to compile foo.cbe.c, but I need to use another C
compiler which gives a syntax error message for not recognizing
the expression '0x0p+0'.
Yup, that'll do it. Although you might want to do a little optimization
otherwise you're going to get a lot of C code on output. Try passing -O2
to llvm-g++.
In the resulting file foo.cbe.c there are many occurences of '0x0p+0'.
What is it used for? Here's a code snippet from the file foo.cbe.c
llvm-gcc is able to compile foo.cbe.c, but I need to use another C
compiler which gives a syntax error message for not recognizing
the expression '0x0p+0'.
Get a new C compiler
The syntax in question is a C99 feature. It is printed by the C Backend
with the %a conversion token for printf. This is the representation of a
floating point number in hexadecimal. It allows certain values that
cannot otherwise be represented with a decimal number to be represented.
The C Backend needs to use this to ensure that the floating point value
it has in mind is *exactly* represented through the conversion to the C
source and then back by your C compiler.
Thank you for your email. I need to use this C compiler that only
supports ANSI C 1989. What is the equivalent of '0x0p+0' in C89 ?
Is there any way around this?
I supposed you could always hack the CBE to have it produce traditional floating point numbers (like 0.0 or whatever) using "%f" instead of "%a". However, you might have problems with precision during comparisons. I.e., if you have something like "if (a == 37.927)", it may not work.
The "hack" has already been implemented. As I mentioned in my last
email, all you need to do is configure LLVM with --disable-cbe-printf-a
and it will avoid using the %a conversion token and instead use ftostr.
As noted in the comment, this is for target-specific code needed at the
start of main. It looks like your target needs a few assembly
instructions there.
As for the __main function, its a gcc library call required by the
compiler for program startup. The details vary but the call is needed.
Amongst other things it will probably initialize your C++ static
constructors.
Emil Mikulic suggested that this be implemented with a command line
switch so that whenever the CBE is invoked you can tell it to avoid
printf-a. That's a pretty good idea and I'll probably flip the
implementation of this to use a command line switch, but I'm not sure
when I'll get to that. Patches welcome.
The function _Z4CONTv() in helloworld.c never got called from main().
This function is supposed to be the C version of CONT() in
helloworld.cpp. Where should I insert the code in hellowrld.c to call
_Z4CONTv() ?
As for the __main function, its a gcc library call required by the
compiler for program startup. The details vary but the call is needed.
Amongst other things it will probably initialize your C++ static
constructors.
Hi Reid:
I'm not using gcc for this purpose but another C compiler called AMPC.
It compiles C code into Java Bytecode. What I'm missing is the C++ to
JVM portion which I'm trying to use LLVM for converting C++ to C then
pass it through AMPC to get the Java Bytecode.
One question is does the resulting C code produced by llc will call C++
functions/methods still? It would be good if only C library functions
are called since I already have the standard C library compiled by AMPC
in the bytecode format.
...
> As for the __main function, its a gcc library call required by the
> compiler for program startup. The details vary but the call is needed.
> Amongst other things it will probably initialize your C++ static
> constructors.
Hi Reid:
I'm not using gcc for this purpose but another C compiler called AMPC.
It compiles C code into Java Bytecode. What I'm missing is the C++ to
JVM portion which I'm trying to use LLVM for converting C++ to C then
pass it through AMPC to get the Java Bytecode.
Okay, cool
One question is does the resulting C code produced by llc will call C++
functions/methods still?
Yes.
It would be good if only C library functions
are called since I already have the standard C library compiled by AMPC
in the bytecode format.
If you use the stdc++ library in your source code then you'll need to
compile that with AMPC as well (after siphoning it through llvm).
I hate to be a pain. But when I ran the program helloworld.class
after compiling it with AMPC I got the following message:
Exception in thread "main" java.lang.NoClassDefFoundError:
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
at helloworld._Z4CONTv(Unknown Source)
at helloworld.__main(Unknown Source)
at helloworld._$C_main(Unknown Source)
at helloworld._$pre_C_main(Unknown Source)
at helloworld.main(Unknown Source)
The function _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc()
was generated by llc after translating it from the C++ statement
std::cout.
How do you suggest I handle this sort of things properly?
The appropriate files are attached.
After converting a piece of C++ code to C one of the functions that are
generated is this:
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
Where is it defined and where can I find the source for it? I need the
source to compile it with a C compiler (AMPC) that will convert the C
code to Java Bytecode. If the above function is in C++ then I need to
convert it to C first.
Here's the code segment that uses the function:
int main(void) {
struct
l_struct_2E_std_3A__3A_basic_ostream_3C_char_2C_std_3A__3A_char_traits_
3C_char_3E__20__3E_ *ltmp_2_2;
After converting a piece of C++ code to C one of the functions that are
generated is this:
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
This is a method/function from the standard C++ library. You can link it in at the bytecode level with:
llvm-g++ -o output.bc <yourfile.bc> -lstdc++
You might also be able to do:
llvm-g++ -o output.bc <yourfile.bc> -lsupc++
... if you're only doing minimal C++ work.
One caveat: you will still have references to external C library functions (fopen(), open(), etc) that will not exist in the C output from the llc command. Can your C to Java Bytecode compiler handle calls to these functions?
After converting a piece of C++ code to C one of the functions that are
generated is this:
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
This is defined in the C++ standard library. You can get the demangled name like so:
$ c++filt _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char>
&, char const*)
Where is it defined and where can I find the source for it? I need the
source to compile it with a C compiler (AMPC) that will convert the C
code to Java Bytecode. If the above function is in C++ then I need to
convert it to C first.
It comes with llvm-gcc4 in libstdc++. You'll need to compile it to bytecode by modifying the makefile though.
Yes, AMPC handles calls to these functions. It supports ANSI C 1989.
The only functions in the standard C library that are not supported yet
are raise(), signal(), longjmp(), and setjmp(). Others work fine.
The purpose of my using LLVM is to convert C++ to C, then compile it
using AMPC and link it with the standard C library that has already been
compiled for the JVM also with AMPC. So, now I guess I will have to
also compile the C++ standard library to the JVM in order to support
functions like:
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc().
Thanks. Do I need to deal with the long names like
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc() or is there an
option to use the shorter version?
After converting a piece of C++ code to C one of the functions that are
generated is this:
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
This is defined in the C++ standard library. You can get the demangled
name like so:
$ c++filt _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
std::basic_ostream<char, std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char>
&, char const*)
Where is it defined and where can I find the source for it? I need the
source to compile it with a C compiler (AMPC) that will convert the C
code to Java Bytecode. If the above function is in C++ then I need to
convert it to C first.
It comes with llvm-gcc4 in libstdc++. You'll need to compile it to
bytecode by modifying the makefile though.
Thanks. Do I need to deal with the long names like
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc() or is there an
option to use the shorter version?
I don't think you will need to deal with any names. The C++ standard
library has already been compiled to LLVM bytecode (it is part of the
llvm-gcc/llvm-g++ distribution). If you use "llvm-g++ -lstdc++" it
should link in whatever libstdc++ functions are needed by your program;
they will get translated to C code along with the rest of your program
when you use llc.