Modify the LLVM front-end to support EFI C and Add LLVM to EFI Byte Code(EBC) target

Hello all,

I want to the do followings:

(1) Modify the LLVM front-end(clang) to support EFI C

(2) Add EFI Byte Code target to LLVM

I am wondering to know which task should I do first, modify front end or porting LLVM?



As long as EFI C isn't radically different from normal C, I would
suggest adding a EBC target to LLVM first. Otherwise you have no way
to test the clang modifications.

- Michael Spencer

You might want to look at the challenges discussed in this thread, mainly that pointer size is a run-time not a compile-time value in EFI C and EFI Byte Code:
("Idea for Google Summer Code : C Compiler for EFI Byte Code implement in LLVM", starting 2010/03/10)


Hello Isaac and all

I have read the challenges discussed.

I summarize the issues may occurred in the followings:

Would you mind to give some advise?

  1. struct layout may be not static, which means that struct field offset are no longer constant in this model.

Such like the following example:

struct S{
void* x;
int e;

struct size(S) is 5 byte for 32-bit processor and 9 byte for 64-bit processor, it also effect the struct field c offset.


We can use the natural indexing in EBC specification to solve this issue.

Assume BASE be the address of c in R0, then the address of c.e is content of R0 add (0 + 1 * sizeof(void*)).

If the EFI C code is c.e = 4, the assembly generated is MOVI @R0(1, 0), 4 after compiled.

(Notation @R1 (+n, +c) means the memory which address is content of R1 add (c + nsizeof(void)).

The EBC assembly above indicate move immediate value 4 to memory which address is content of

R0 add (0 + 1sizeof(void)).

  1. sizeof is evaluated at runtime because the pointer size (void*) is determined at runtime.


This issue could be solved by implementing sizeof as an intrinsic, and the code of sizeof intrinsic could be as follows:

MOVI R1, 0
MOVI R2, Label
ADD32 R1, @R2 (1, 0)
Label: UINT32
UINT32 4
UINT32 8

R1 ends up with the size of the void*.

  1. void*-typed automatic variables cause dynamic activation record.


Consider a Function call of function foo() which does not have any parameter.

Although there is only return address in the activation record (which type is void*), the activation record

size is determined at runtime. It doesn’t know how many bytes should be subtracted from

sp (stack pointer register). With natural indexing, we can just generate assembly such like

SUB SP, R1, with R1= sizeof(void*) and can be calculated as above.



As was stated in the last post on this subject, EFI C has integer types that have a size determined at run time. I can't see how this would be integrated into the existing IRGen infrastructure in clang without some serious modification, nor how you would represent these in LLVM IR. Mapping from a language that has variable-sized ints, to a target that has variable-sized ints, via an intermediate representation that does not have variable-sized ints would be tricky, I suspect.


-- Sent from my PDP-11

Hello Michael and all,

So the issue related can be reduced into the two problem:

  1. There is no good representation of EBC int in LLVM IR.

  2. clang IRGen may have some serious modification.

I know LLVM IR is extensible. Is it possible to add a new type in(natural int) to represent EFI int and

integrated into clang IRGen??



2010/12/17 David Chisnall <>