I writes some C-program code for Altera/Nios II microprocessor (uP). This code will be different with Altera Arm 9 microprocessor. So I need to write 2 different code pieces for different uP-s. How can I check in execution time which uP is present. Or more simple, current uP is Nios or not.
As the two processors are from different architectures, you will not be able to check which processor is running at run-time. You could do it at compile time, as you will have a specific define flag set by your toolchain (see https://sourceforge.net/p/predef/wiki/Architectures/). For Arm it should be __arm__ or similar, depending on the toolchain you are using for the HPS.
#ifdef __arm__
<specific code for HPS>
#else
<specific code for NIOS>
#endif /* __arm__ */
You can also look at the toolchain's defines using the c pre-processor command (cpp):
<toolchain>-cpp -dM /dev/null
Note: for Arm processor, the MIDR register could be used to know which type you are running and this one could be accessed at runtime. But when building for NIOS II, you would have a compilation error. So you need to use the preprocessor to call specific Arm register name and to remove the code when building for NiosII.
Presumably it will be compiled with a different compiler? These compilers will (very likely) have a #define of some sort which you can use to build different code for each one.
You can make the compiler dump all its default preprocessor defines using:
echo | ./nios2-elf-gcc.exe -dM -E -
This will in particular emit:
#define nios2 1
Related
In a c program I want to do different things. This program will run on x86/x64 based GNU/Linux system as well as ARM based one e.g. on a PC or RaspberryPI.
Is there predefined macros in GCC to tell the platform?
something like
#ifdef _X64_
/do x64 stuff
#elif _ARM_
//do arm stuff
#endif
Or maybe that is the wrong approach? I will be using Makefileto compile and I could get away with my own defines.
What would be the best/safest approach?
This has already been answered on these posts:
GCC predefined macros for architecture X, Detecting CPU architecture compile-time
You can have them here:
http://sourceforge.net/p/predef/wiki/Architectures/
Your approach should only be used for small portions of code or functions but it should work.
Edit:
Basically, because links can become invalid:
__arm__ should work on ARM.
__x86_64__ should work on x64 architecture.
And yes, you can do:
#ifdef __x86_64__
// do x64 stuff
#elif __arm__
// do arm stuff
#endif
I want to compile part of my code only on x86 and x86_64 linux, but not s390 linux or others. How to use the macro define in C to achieve it? I know linux is to determine linux OS, and 386, 486 and 586 to determine CPU architecture. Is there an easy macro define to determine x86 linux and x86_64 linux? Thanks
You can detect whether or not you are in a 64 bit mode easily:
#if defined(__x86_64__)
/* 64 bit detected */
#endif
#if defined(__i386__)
/* 32 bit x86 detected */
#endif
If your compiler does not provide pre-defined macros and constants, you may define it yourself: gcc -D WHATEVER_YOU_WANT.
Additional reward: if you compile your code for, say, amd64, but you don't define amd64, you can compare the results (the version which use amd64-specific parts vs the generic version) and see, whether your amd64 optimalization worths the effort.
Another option instead of pre-processor macros is sizeof(void*) == 4 to detect 32-bit and/or sizeof(void*) == 8 for 64-bit. This is more portable, as it does not rely on any defined symbols or macros.
As long as your compiler has any level of optimization enabled, it should be able to see that this kind of statement is either always true or always false for the current build target, so the resulting binary should be no less efficient than if you'd used pre-processor macros.
I am currently using predefined cpu target macros to make software run on multiple cpu targets.
#ifdef __TARGET_CPU_CORTEX_M0
[do something here]
#elif __TARGET_CPU_CORTEX_M3
[do something here]
#else
#error Unsupported compiler platform
#endif
Example:
This works for Cortex-M0 and Cortex-M3, but I can't figure out what macro to use for Cortex-M0+. Does anyone know which macro I can use?
I use the armcc compiler.
This is documented, albeit rather obliquely. The relevant macro name is derived from the command-line option, thus --cpu=Cortex-M0plus defines __TARGET_CPU_CORTEX_M0PLUS.
Annoyingly, whilst it doesn't show up in the --cpu=list output, the compiler (I tried armcc version 5.04) does also recognise the option --cpu=Cortex-M0+, for which it defines the macro __TARGET_CPU_CORTEX_M0_
In general, invoking armcc --cpu=xx --list_macros /dev/null will show what macros are defined for cpu option xx (or an error if it isn't supported).
How do I determine a user's OS in terminal application, in C?
For example, in the code below, what should I replace windows and linux with?
/* pseudo code */
if(windows)
{system(cls)}
else if(linux)
{system(clear)}
else{...}
I should mention that I am a beginner at C, and need something like this so my code can work on windows and/or linux, without making separate source for each.
Typically, this is done with macros in the build system (since you have to BUILD the code for each system anyway.
e.g. gcc -DLINUX myfile.c
and then in myfile.c
#ifdef LINUX
... do stuff for linux ...
#else if defined(WINDOWS)
... do something for windows ...
#else if ... and so on.
...
#endif
(Most of the time, you can find some way that doesn't actually require the addition of a -D<something> on the command line, by using predefined macros for the tools you are using to compile for that architecture).
Alternatively, you ca do the same thing, but much quicker and better (but not 100% portable) by printing the ANSI escape sequence for "clear screen":
putstr("\033" "2J");
yes, that's two strings, because if you write "\0332J" the compile will use the character 0332, not character 033, followed by the digit 2. So two strings next to each other will do the trick.
I believe you can avoid runtime check by specializing your 'functions' during compilation. So, how about this then:
#ifdef WIN32
CLEAR = cls
#elif __linux__
CLEAR = clear
#endif
Predefs vary from compiler to compiler, so here's a good list to have: http://sourceforge.net/p/predef/wiki/OperatingSystems/
It is probably better to detect the environment at compile time rather than runtime. With compiled languages like C you aren't going to have the same compiler output running on different platforms as you would with a lanugage such as Java so you don't need to do this kind of check at runtime.
This is the header I use to work out what platform my code is being compiled on. It will define different macros depending on the OS (as well as other things).
Something like this in use:
#if defined(UTIL_PLATFORM_WINDOWS)
printf("windows\n");
#elif defined(UTIL_PLATFORM_UNIXLIKE)
printf("Unix\n");
#endif
I have next problem:
I have some tests related to xop check with using some Bulldozer (xop) instructions.
And I must run this tests only on Bulldozer processors.
How can I check that my processor supports xop instruction at compile-time?
Language: C, Os: Linux;
You can write a program that checks CPUID and use the output of that program while compiling:
gcc $(cpuid_test) my_prog.c
where cpuid_test returns '-march=bdver1' or -DXOP_SUPPORT=1
You cannot test at compile time, but you can compile for AMD Bulldozer using:
$ gcc -march=bdver1 -mtune=bdver1 ...
See: http://gcc.gnu.org/gcc-4.6/changes.html
If your build machine is your target machine, look into /proc/cpuinfo.
If a source is compiled with -march=bdver1 (which enables XOP support among other things), the preprocessor macro __XOP__ will be defined to 1.
You can test at compile time for XOP with
#ifdef __XOP__
...XOP code path here...
#else
...non XOP code here...
#endif