In many cases, to port C/C++ source code to GCC involves simply recompiling the code using Blackfin GCC. But you will need to take care of the differences between VDSP C/C++ compiler and GCC - since every compiler defines its own set of extensions. How to translate between these dialects is the focus of this page. Whenever possible, please refer to the manuals of both compilers.
Pragmas are implementation-specific directives that modify the compiler’s behavior.
GCC for the most part uses attributes rather than pragmas as they flow more naturally in the language specification.
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
So while the VDSP #pragma would look something like:
#pragma align 4 char a;
The GCC attribute would look like:
char a __attribute__((aligned(4)));
| VDSP | GCC | Description |
|---|---|---|
align num | aligned(num) | Set alignment to num |
alignment_region num | N/A | Set default alignment to num |
alloc | malloc | Function returns allocated memory |
always_inline | same | Always inline |
const | same | Like pure, but no global memory accesses |
core(core) | N/A | Place symbols into different cores |
exception | exception_handler | Function is an exception handler |
file_attr | N/A | Declare file attributes |
hdrstop | N/A | Control precompiled header stopping |
inline | same | Inline when compiler likes it |
interrupt | interrupt_handler | Function is an interrupt handler |
interrupt_level | N/A | Function is a specific interrupt handler |
interrupt_reentrant | interrupt_handler, nesting | Function is a nested interrupt handler |
linkage_name name | alias(“name”) | Rename decl to name |
misra_func(arg) | N/A | MISRA-C stuff |
never_inline | noinline | Do not inline |
nmi | nmi_handler | Function is an nmi handler |
no_implicit_inclusion | N/A | Disable C++ implicit header search |
no_pch | N/A | Disable precompiled header option |
noreturn | same | Function never returns |
once | same | Only include this header once |
optimize_as_cmd_line | N/A | Use command line optimization |
optimize_for_space | optimize(“Os”) | Optimize for smaller size |
optimize_for_speed | optimize(2) | Optimize for faster execution |
optimize_off | optimize(0) | Do not optimize |
overlay | N/A | Function may be in an overlay |
pack(align) | packed, aligned(num) | Pack data with alignment num |
pad(align) | N/A | Pad data with alignment num |
param_never_null name | nonnull(pos) | Function argument cannot be NULL |
pgo_ignore | N/A | Ignore function in profile guided optimization |
pure | same | Return value is always the same based on input arguments |
regs_clobbered | N/A | Declare clobbered registers |
regs_clobbered_call | N/A | Declare clobbered registers |
result_alignment(num) | N/A | Result is always aligned to num |
retain_name | used | Always keep symbol |
section(section) | section(“section”) | Place symbol in section |
suppress_null_check | N/A | Suppress NULL checking in generated C++ code |
symbolic_ref | N/A | Declare symbol with symbolic refs |
system_header | same | This is a system header |
weak_entry | weak | Declare symbol with weak linkage |
These pragmas are not supported by GCC in any way:
all_aligned, different_banks, extra_loop_loads, loop_count, loop_unroll, no_alias, no_vectorization, vector_forcode_bank, data_bank, stack_bank, bank_memory_kind, bank_read_cycles, bank_write_cycles, bank_optimal_width#ifdef __GNUC__ static char buf[SIZE] __attribute__((aligned(4))); #else #pragma align 4 static char buf[SIZE]; #endif
#ifdef __GNUC__ int foo (int) asm ("_foo_1"); #else #pragma linkage_name _foo_1 int foo (int); #endif
#ifdef __GNUC__ volatile u16 sFrame0[FRAMESIZE] __attribute__((section("vd0_sdram"))) ; #else section("vd0_sdram") volatile u16 sFrame0[FRAMESIZE]; #endif
To porting VDSP code using built-in or intrinsic functions, please refer to built-in_functions.
See the inline assembly page as well as the gcc asm constraints page:
http://gcc.gnu.org/onlinedocs/gcc/Constraints.html
http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
| VDSP | GCC | Description | Registers |
|---|---|---|---|
a | same | General addressing registers | P0 - P5 |
A | e | Accumulator registers | A0, A1 |
b | same | DAG addressing registers | I0 - I3 |
d | same | General data registers | R0 - R7 |
D | d | General data registers | R0 - R7 |
e | same | Accumulator registers | A0, A1 |
E | D | Even general data registers | R0, R2, R4, R6 |
f | same | Modifier registers | M0 - M3 |
h | N/A | High halves of the general data registers | R0.H, R1.H, …, R7.H |
H | N/A | Low or high halves of the general data registers | R0.H, R0.L, …, R7.L, R7.H |
i | b | DAG addressing registers | I0 - I3 |
I | N/A | General data register pairs | (R0-R1), (R2-R3), (R4-R5), (R6-R7) |
l | N/A | Low halves of the general data registers | R0.L, R1.L, …, R7.L |
L | k | Loop counter registers | LC0, LC1 |
n | same | Compile time constant | N/A |
p | a | General addressing registers | P0 - P5 |
O | W | Odd general data registers | R1, R3, R5, R7 |
r | d | General data registers | R0 - R7 |
There are many Analog Devices extension in the VDSP++ C and C++ Run Time Library that have no gcc or Linux equivalent.
If you run into errors like undefined reference to function_name this is one of those cases. There is nothing you can do except understand what the original code was trying to do, and re-write it with the POSIX or Linux like function.