[llvm-commits] PATCH for PIC16 target.

Sanjiv.Gupta at microchip.com Sanjiv.Gupta at microchip.com
Mon May 12 22:54:55 PDT 2008


 
> How is PIC16 different from existing LLVM targets?
> Did you encounter any problems in developing this target for 
> LLVM? Is there anything in LLVM that you had to work around, 
> or that poses a challenge for PIC16?
> 
> How is PIC16 similar to existing LLVM targets? Which other 
> targets is this code based on, or were relevant as examples?
> 
> Thanks,
> 
> Dan

Our target is an 8-bit microcontroller with only one 8-bit register
which is the accumulator. All arithmetic/load/store operations are 8-bit
only.
The architecture has two address spaces: program and data. The program
memory is divided into 2K pages and the data memory is divided into
banks of 128 byte, with only 80 usable bytes, resulting in an
non-contiguous data memory. 

It supports direct data memory access (by specifying the address as part
of the instruction) and indirect data and program memory access (in an
unorthodox fashion which utilize a 16 bit pointer register). 

Two classes of registers exist: (8-bit class which is only one
accumulator) (16-bit class, which contains one or more 16 bit
pointer(s))

 

You can see that our target bears very little similarity to other
targets. Currently the port is very elementary and handles very few
source constructs.

Below are the few challenges that we faced while using llvm framework.
1. The granularity of llvm operation expansion phase is the largest
register size available on the target m/c. So if the target has pointer
registers of size greater than data registers (in this case the 16 bit
pointer register), the operations on the data are not lowered/legalized
to correct granularity (8-bit). For example in our case,
LowerOperation() is not called for add:i16. This has been the most
challenging problem for us. We have tackled this problem having LLVM to
lower to 16 bit, and then by manually expanding the datatypes/operations
to 8-bit for basic arithmetic and load/store in PerformDAGCombine()
method.

2. Due to non-contiguous data memory, we can not support stack (and no
recursion therefore). LLVM framework is inherently stack based and has
little or no support for static allocation of locals. We tackled this
problem in the frontend by code generating globals for stack vars.

3. Accessing the memory through pointer register is generally
inefficient in our architecture. However, the fundamental trend in LLVM
(and most other compilers for that matter) for accessing the memory is
based on pointers. Luckily we are able to identifying the DAG patterns
for different types of memory access and generate the appropriate
instructions (so far no problem)

4. Like most other compilers, LLVM likes to have as many registers as
possible. This is not the case for our accumulator based architecture.
However, we have been able to model our code generation to overcome this
problem by viewing register spills as intermediate values in
calculations. And this seems to be working for us. As a future
improvement, we plan to also implement our own LLVM register allocator
to minimize the intermediate values.

 Although LLVM framework has not been designed to support architectures
like ours, in general we think that it provides great features and we
are willing to take on the challenges that we face to use LLVM for our
compiler development. Most importantly, the friendly and helpful
feedbacks that we receive from the LLVM community further encourage us
in this endeavor.

- Sanjiv




More information about the llvm-commits mailing list