Gnu Assembler: Evaluate symbols in macro arguments? - macros

In GNU assembler (v. 2.31.1) I would like to pass symbols as set by .equ (or .set) to macros.
As an example on ARM, I would like to convert integer symbols to strings:
.equ WIDTH, 100
.macro numToString label, num
\label :
.asciz "\num"
.equ \label\()Len, .-\label
.endm
numToString xyzWidthStr, WIDTH
However, this results in a label "xyzWidthStr" for the null-terminated string "WIDTH" instead of "100". Is there a way to force the macro to evaluate/substitute an argument before it is used?

Is there a way to force the macro to evaluate/substitute an argument before it is used?
You could use the C preprocessor to resolve it when you
#define WIDTH 100
Assemble with arm-gcc (not arm-as). gcc will call the C preprocessor for the file before assembling it if the file extension is .S or .sx. If you use a different extension, you can
arm-gcc -x assembler-with-cpp code.asm <options>
If you want to see the intermediate, pre-processed code, add -save-temps to <options>. gcc will save it to code.s.

Related

Concatenating an expanded macro and a word using the Fortran preprocessor

I'm trying to concatenate a word in the source code with the expansion of a preprocessor macro. Basically I have foo somewhere in the code, and with a #define EXPANSION bar I want to obtain foobar. However, I'm struggling to find a way to do this, which works with all compilers. For the moment I would be happy if it works with gfortran and ifort.
According to its documentation, the gfortran preprocessor is a C preprocessor running in "traditional mode", which does not have the ## token paste operator. However, the same effect can be obtained with an empty C-style /**/ comment. The ifort preprocessor seems to behave more like the normal C preprocessor, so normal token pasting does the trick in ifort. Unfortunately the empty /**/ comment does not work in ifort, as the comment is replaced by a single space instead.
Here is a little example:
#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y
foo/**/EXPANSION
CAT(foo,EXPANSION)
For which gfortran produces:
foobar
foo ## bar
While ifort gives me:
foo bar
foobar
Of course I could choose the right way by checking the predefined macros for both compilers:
#ifdef __GFORTRAN__
foo/**/EXPANSION
#else
CAT(foo,EXPANSION)
#endif
This works for both of them, but it's rather ugly to have the preprocessor conditional for every expansion. I would much rather avoid this and have some macro magic only once in the beginning.
I have seen this answer to another question, which would probably allow me to work around this issue, but I would rather find a solution that does not invoke the preprocessor separately.
I'm not too familiar with the C preprocessor. Maybe there is a simple way to do what I want. Any ideas?
EDIT: I've already tried something like this:
#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#ifdef __GFORTRAN__
#define PASTE(x,y) x/**/y
#else
#define PASTE(x,y) x ## y
#endif
CAT(foo,EXPANSION)
Unfortunately this does not work in gfortran where it produces fooEXPANSION. I'm not entirely sure how this works, but apparently the expansion of the CAT macro prevents the expansion of EXPANSION in the same line. I suspect that this is a feature of the "traditional" C preprocessor ...
I have done some research and it seems that basically most Fortran compilers (i.e. Intel and PGI) use a relatively normal C-preprocessor with a token pasting operator. We only need a special treatment for gfortran, which uses a C preprocessor in traditional mode without a token pasting operator.
Thanks to an entry on c-faq.com I found this definition of a CAT macro that works with all compilers I tested so far:
#ifdef __GFORTRAN__
#define PASTE(a) a
#define CAT(a,b) PASTE(a)b
#else
#define PASTE(a) a ## b
#define CAT(a,b) PASTE(a,b)
#endif
Another solution (that still uses the /**/ trick) was posted by Jonathan Leffler in this answer to a related question.

Systemverilog: scope of text substitution macro

I read that text substitution macros have global scope in 'verilog'. How does SystemVerilog work? I want to use 2 different definitions of the same text macro in 2 different SystemVerilog files - is that OK to do?
In SystemVerilog, macro definitions are limited to the compilation-unit scope but what that is depends on the tool configuration. From the specification:
The exact mechanism for defining which files constitute a compilation
unit is tool-specific. However, compliant tools shall provide use
models that allow both of the following cases:
a) All files on a given compilation command line make a single
compilation unit (in which case the declarations within those files
are accessible following normal visibility rules throughout the
entire set of files).
b) Each file is a separate compilation unit (in which case the
declarations in each compilation-unit scope are accessible only
within its corresponding file).
Therefore if you use multiple-file compilation units (-mfcu for Modelsim), there will be collisions since the macro namespace will have global scope. However the specification explicitly allows redefinitions so you may not get an error(or warning) in this case, unless your tool supports it.
The text macro name space is global within the compilation unit.
Because text macro names are introduced and used with a leading ‘
character, they remain unambiguous with any other name space. The text
macro names are defined in the linear order of appearance in the set
of input files that make up the compilation unit. Subsequent
definitions of the same name override the previous definitions for the
balance of the input files.
Depending on how you are using macros, you may want to consider using parameters instead. Parameters are essentially constants that are more limited in scope than preprocessor directives. They can also be used to selectively instance code using generate constructs.
You can get the SV specification here for free.
If the desired macro have simuliar structure/format, then you can use macro with arguments. See IEEE1800-2012 Section 22.5.1.
`define myMacro(arg1,arg2) \
prefix_``arg1 = arg2``_postfix
If the desired macro definition is exclusively in its respected file and unique, then you can do the following. All other files will not have an `mymacro that can be called. `undef is from Verilog, IEEE1364-1995 Section 16.3.2, and has been in included into SystemVerilog. You can read more about `undef in the latest revision; IEEE1800-2012 Section 22.5.2.
file1.sv:
`define mymacro abcd
/* SystemVerilog code */
`undef mymacro
file2.sv:
`define mymacro wxyz
/* SystemVerilog code */
`undef mymacro

How can I reference #defines in a C file from python?

I have a C file that has a bunch of #defines for bits that I'd like to reference from python. There's enough of them that I'd rather not copy them into my python code, instead is there an accepted method to reference them directly from python?
Note: I know I can just open the header file and parse it, that would be simple, but if there's a more pythonic way, I'd like to use it.
Edit:
These are very simple #defines that define the meanings of bits in a mask, for example:
#define FOO_A 0x3
#define FOO_B 0x5
Running under the assumption that the C .h file contains only #defines (and therefore has nothing external to link against), then the following would work with swig 2.0 (http://www.swig.org/) and python 2.7 (tested). Suppose the file containing just defines is named just_defines.h as above:
#define FOO_A 0x3
#define FOO_B 0x5
Then:
swig -python -module just just_defines.h ## generates just_defines.py and just_defines_wrap.c
gcc -c -fpic just_defines_wrap.c -I/usr/include/python2.7 -I. ## creates just_defines_wrap.o
gcc -shared just_defines_wrap.o -o _just.so ## create _just.so, goes with just_defines.py
Usage:
$ python
Python 2.7.3 (default, Aug 1 2012, 05:16:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import just
>>> dir(just)
['FOO_A', 'FOO_B', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_just', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic']
>>> just.FOO_A
3
>>> just.FOO_B
5
>>>
If the .h file also contains entry points, then you need to link against some library (or more) to resolve those entry points. That makes the solution a little more complicated since you may have to hunt down the correct libs. But for a "just defines case" you don't have to worry about this.
You might have some luck with the h2py.py script found in the Tools/scripts directory of the Python source tarball. While it can't handle complex preprocessor macros, it might be sufficient for your needs.
Here is a description of the functionality from the top of the script:
Read #define's and translate to Python code.
Handle #include statements.
Handle #define macros with one argument.
Anything that isn't recognized or doesn't translate into valid
Python is ignored.
Without filename arguments, acts as a filter.
If one or more filenames are given, output is written to corresponding
filenames in the local directory, translated to all uppercase, with
the extension replaced by ".py".
By passing one or more options of the form "-i regular_expression"
you can specify additional strings to be ignored. This is useful
e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".
#defines are macros, that have no meaning whatsoever outside of your C compiler's preprocessor. As such, they are the bane of multi-language programmers everywhere. (For example, see this Ada question: Setting the license for modules in the linux kernel from two weeks ago).
Short of running your source code through the C-preprocessor, there really is no good way to deal with them. I typically just figure out what they evalutate to (in complex cases, often there's no better way to do this than to actually compile and run the damn code!), and hard-code that value into my program.
The (well one of the) annoying parts is that the C preprocessor is considered by C coders to be a very simple little thing that they often use without even giving a second thought to. As a result, they tend to be shocked that it causes big problems for interoperability, while we can deal with most other problems C throws at us fairly easily.
In the simple case shown above, by far the easiest way to handle it would be to encode the same two values in constants in your python program somewhere. If keeping up with changes is a big deal, it probably wouldn't be too much trouble to write a Python program to parse those values out of the file. However, you'd have to realise that your C code would only re-evaluate those values on a compile, while your python program would do it whenever it runs (and thus should probably only be run when the C code is also compiled).
If you're writing an extension module, use http://docs.python.org/3/c-api/module.html#PyModule_AddIntMacro
I had almost exactly this same problem so wrote a Python script to parse the C file. It's intended to be renamed to match your c file (but with .py instead of .h) and imported as a Python module.
Code: https://gist.github.com/camlee/3bf869a5bf39ac5954fdaabbe6a3f437
Example:
configuration.h
#define VERBOSE 3
#define DEBUG 1
#ifdef DEBUG
#define DEBUG_FILE "debug.log"
#else
#define NOT_DEBUGGING 1
#endif
Using from Python:
>>> import configuration
>>> print("The verbosity level is %s" % configuration.VERBOSE)
The verbosity level is 3
>>> configuration.DEBUG_FILE
'"debug.log"'
>>> configuration.NOT_DEBUGGING is None
True

Doxygen conditional compilation does not produce documentation

I'm a relative beginner with doxygen, and am documenting a C program
Part of the code is:
\#include "options.h"
// options.h contains
\#define VAL0 0 // Possible values for PARAM
\#define VAL1 1
\#define PARAM VAL0
// Here's the conditional compilation
\#if (PARAM == VAL0)
// code chunk, which doesn't get compiled by Doxygen
\#endif
The code compiles with GCC as expected, but I get no Doxygen documentation
OK, Doxygen doesn't expand macros, so I tried:
\#define SYMEQ(A, B) (A == B) ? 1 : 0
\#if SYMEQ(PARAM, VAL0)
// code chunk
\#endif
Set the Doxygen:
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
No Predefined macros
EXPAND_AS_DEFINED = SYMEQ
No doxygen output from the conditional part, just up to it
I also tried EXPAND_AS_DEFINED SYMEQ(A, B)
Also no luck
I found a few examples with simple names, then #ifdef NAME \code #endif, but none with macro functions
I just had the problem #ifdef CONDITION \code not compiled by doxygen\ #endif and fixed it by brute force, i.e, appending the conditions to the setting PREDEFINED=CONDITION1 CONDITION2 ... manually.
I tried the header file solution -- generate a file with conditions and include it by setting SEARCH_INCLUDES, INCLUDE_PATH and INCLUDE_FILE_PATTERNS -- but it did not work. From the doxygen manual, I think it requires to explicitly #include "the condition file" in the source files, which means to modify the source code, so I give up.
SEARCH_INCLUDES:
If the SEARCH_INCLUDES tag is set to YES (the default) the includes files in the INCLUDE_PATH (see below) will be searched if a #include is found.
MACRO_EXPANSION and EXPAND_ONLY_PREDEF only control whether a macro will be expanded in your code, not how it will be evaluated in conditional preprocessor blocks. For example, if you had code like:
#define RET_TYPE int
/**
* Some function
*/
RET_TYPE func(void);
With MACRO_EXPANSION=NO, this will be documented by doxygen as RET_TYPE func(void), the macro isn't expanded. With MACRO_EXPANSION=YES, this will be documented as int func(void), the macro is expanded and the resulting signature is documented.
To control conditional code, you'll want to focus on the ENABLE_PREPROCESSING. If this option is set to NO, conditional code will be ignored, and all code within the condition will be documented. If it is set to YES, the conditional code will be evaluated, and only blocks for which the condition matches will be documented. In this case, you'll need to make sure that all of the values being evaluated are defined correctly, this can be accomplished by allowing doxygen to evaluate include files (see SEARCH_INCLUDES, INCLUDE_PATH and INCLUDE_FILE_PATTERNS options), or by predefining the macros to have a particular value (see PREDEFINED).

Getting the warning " ISO C90 forbids variable-size array" in gcc compiler while compiling C90 code

I am compiling my C90 c code in gcc . I am getting the warningISO C90 forbids variable-size array while making the declaration like
int symbols[nc];
Where nc is integer whose value is read from the input file. The values on the input files are varied so i can't keep a constant value. How can I get rid of it? Is it indeed necessary to resolve this warning or we can simply ignore it?
Thanks in advance.
You get that warning because C90 does not support variable length arrays.
You'll either have to switch gcc to C99 mode (which does support vla) , by using the -std=c99 or std=gnu99 command line flag, or rewrite your code to dynamically allocate memory or use a fixed size array.
The warning just tells you that you're not conforming to C90 in this case, but it's otherwise safe. Ignoring a warning should really not be an option though.