in4lio / ev3dev-c

LEGO MINDSTORMS EV3 Debian C library + Python, Ruby and Perl wrappers
MIT License
71 stars 30 forks source link

Generating ARM Assembly compliant headers #12

Closed tcwan closed 6 years ago

tcwan commented 6 years ago

Hi,

This is a bit of a tangent, but I'm planning on using ev3dev-c to implement an ARM Assembly Language-based EV3 programming environment. The gist of it is to use the GCC C-Compiler to preprocess the source files (C or Assembly source), so C-style preprocessor directives can be utilized in Assembly Language source files as well.

My main issue currently is how to make the header file definitions accessible from both C and Assembly. In my previous project nxos-armdebug, I used C preprocessor macros (see ev3dev-arm.h) to define shared definitions such as enums, while commenting out function defintions and typedefs.

Since ev3dev-c is using yupp to generate the headers, I'm thinking that it is probably a better solution for my use case. Nonetheless, I'm not sure where to start looking in the yupp code to understand how to modify the output generation module to create ARM assembly syntax headers instead of the C/Ruby/Perl/etc headers.

I'd appreciate it if you can point me towards the relevant info for yupp; that would be great!

in4lio commented 6 years ago

Hi @tcwan -- Everything is collected here. Unfortunately, not too much information)) But do not hesitate to ask. I'll take a look at your task...

tcwan commented 6 years ago

@in4lio:

Thanks for the link, but they're explaining how to use yupp, not how to modify yupp. I would need some info regarding the backend (output) generator to do what I described. Thanks!

in4lio commented 6 years ago

Ok. Could you give me an example, for any generated header file from ev3dev-c, how it should look like in case of asm?

tcwan commented 6 years ago

There are basically 3 things in the header file which need to be handled differently:

  1. Typedefs

There are no concept of typedefs in Assembly, so basically they would be commented out, using '/ /', '//' or '@' (ASM syntax for comments).

There is the possibility of exporting typedefs of structs but I haven't thought about how to best generate the output in a consistent and foolproof manner, so I'm not going to attempt it for now.

  1. Function Prototypes

Again, function prototypes are not used in Assembly, and can be commented out like for typedefs, though having the name referenced is useful but not strictly necessary for the Linker to resolve them to their respective functions (since the object file containing the actual function implementation will export the function names).

i.e., a_function(); in C becomes:

    .extern a_function
  1. Enums

This is the part that needs the most work. Currently I'm using a bunch of macros in ev3dev-arm.h to handle the definition of enums that can be included in both C and ASM headers. See the example at the end of ev3dev-arm.h.

However, as a comparison of how enums are declared, for C:

typedef enum {
     first = 1,
     second,
     third = 13,
     fourth
} order;

Becomes something like:

   .equiv first, 1
   .equiv second, 2
   .equiv third, 13
   .equiv fourth, 14

The typedef name is ignored currently, though if generated via yupp, perhaps it can be output as:

   .equiv order_first, 1
   .equiv order_second, 2
   .equiv order_third, 13
   .equiv order_fourth, 14

to avoid namespace clashes.

My macros keep track of the current enum values and auto-increment them based on the last assigned values. If there were no explicit assigned values, then the initial enum value is 0.

Something that I didn't have in my nxos-armdebug are extern references in the headers. If needed, a C

extern reference_name

can be translated into

   .extern reference_name

C variable types and sizes are not used in Assembly language headers.

Other prepropcessor related definitions are used as is so there is no issue with using #define CONSTANTVAL 123 directly in the Assembly source file.

in4lio commented 6 years ago

Perhaps, you just need a slightly modified ev3_class-h.yu file. Please take a look at the "asm" folder.

tcwan commented 6 years ago

The output is quite good for a first pass. Thanks!

Some things that are missing:

  1. The Enum definitions currently assumes that there will always be an ENUM_0 at the start of the enum list. If the list starts with a non-zero enum value (defined using ENUM_EQ), ENUM_COUNTER is not updated.

I think it can be fixed as follows:

.macro ENUM_EQ name, value
.equiv \name, \value
.set ENUM_COUNTER, \value + 1
.endm
  1. The ENUM list generation currently defines the XXCOUNT_ as an enum and then ENUM_EQ it to the last enum value XXUNKNOWN_. While this is correct, semantically it is confusing since the actual enum value should be XXUNKNOWN, and the COUNT is the equivalent.

  2. Can we include the C function parameter type information in the header comments? Easiest is to just output the C function prototype definition as part of the header comments.

  3. Need to protect the definitions with #ifndef __HEADER__ / ... / #endif __HEADER__

  4. I don't think you can define macros with the same names repeatedly. So, the lines 11-24 would need to be in a common include header file.

in4lio commented 6 years ago

Updated. The enum values XX__NONE_, XX__COUNT_ and XX__UNKNOWN_ are enclosed in additinal underscores to be unique)

tcwan commented 6 years ago

Wow, that is quick! I presume that #pragma once should protect the headers from multiple #includes?

Thanks a lot, I think it should work well enough for me to start using them. So are the ASM headers available for the entire ev3dev-c library now or do I need to wait for a new release?

in4lio commented 6 years ago

Yes, exactly. Done.

tcwan commented 6 years ago

Thanks!

I took a quick look at ev3_port.h, the lines 46-67 has ENUM_N followed by ENUM_EQ on the same line. I think there are missing \n in the generated output somewhere. There's a similar problem for ev3_sensor.h lines 167-191

Then the output for ev3_led.h and ev3_light.h seems to not #include enum_asm.h but expands the macros directly?

in4lio commented 6 years ago

Fixed, Looks like this macro is not very suitable for them))

tcwan commented 6 years ago

Ok. I'll use what's available here. Thanks!