Tutorial: Creating an LLVM Backend for
the Cpu0 Architecture
Release 3.9.1
Chen Chung-Shu
May 11, 2018
1 About
2 Cpu0 architecture and LLVM structure
3 Backend structure
4 Arithmetic and logic instructions
5 Generating object files
6 Global variables
7 Other data type
8 Control flow statements
9 Function call
10 ELF Support
11 Assembler
12 C++ support
13 Verify backend on Verilog simulator
14 Appendix A: Getting Started: Installing LLVM and the Cpu0 example code
15 Appendix B: Cpu0 document and test
16 Todo List
17 Book example code
18 Alternate formats
19 Presentation files
20 Search this website
CONTENTS
1
11
63
173
211
241
273
297
333
435
453
507
543
567
583
593
595
597
599
601
i
ii
• Authors
• Contributors
• Acknowledgments
• Support
• Revision history
• Licensing
• Motivation
• Preface
• Prerequisites
• Outline of Chapters
1.1 Authors
Chen Chung-Shu gamma_chen@yahoo.com.tw
http://jonathan2251.github.io/web/index.html
1.2 Contributors
Anoushe Jamshidi, ajamshidi@gmail.com, Chapters 1, 2, 3 English re-writing and Sphinx tool and
format setting.
Chen Wei-Ren, chenwj@iis.sinica.edu.tw, assisted with text and code formatting.
Chen Zhong-Cheng, who is the author of original cpu0 verilog code.
1.3 Acknowledgments
We would like to thank Sean Silva, chisophugis@gmail.com, for his help, encouragement, and as-
sistance with the Sphinx document generator. Without his help, this book would not have been
CHAPTER
ONE
ABOUT
1
Tutorial: Creating an LLVM Backend for the Cpu0 Architecture, Release 3.9.1
finished and published online. We also thank those corrections from readers who make the book
more accurate.
1.4 Support
We get the kind help from LLVM development mail list, llvmdev@cs.uiuc.edu, even we don’t know
them. So, our experience is you are not alone and can get help from the development list members
in working with the LLVM project. Some of them are:
Akira Hatanaka
in va_arg question answer.
Ulrich Weigand in AsmParser question answer.
1.5 Revision history
Version 3.9.2, Not release yet.
Version 3.9.1, Released May 11, 2018 Fix tailcall bug. Fix return-vector.ll run slowly problem, bug from
Cpu0ISelLowering.cpp. Add figure “Tblgen generate files for Cpu0 backend”. Modify section float
and double of Chapter Other data type. Move storeRegToStack() and loadRegFromStack() from
Chapter9_1 to Chapter3_5. Section DSA of chapter Cpu0 architecture and LLVM structure.
Version 3.9.0, Released November 22, 2016 Porting to llvm 3.9. Correct writing.
Version 3.7.4, Released December 7, 2016 Change bal instruction from with delay slot to without delay
slot.
Version 3.7.3, Released July 20, 2016 Refine code-block according sphinx lexers. Add search this book.
Version 3.7.2, Released June 29, 2016 Add Verilog delay slot simulation. Explain “tablegen(” in CMake-
Lists.txt. Correct typing. Add lbdex/install_llvm/*.sh for installation. Upgrade sphinx to 1.4.4.
Version 3.7.1, Released November 7, 2015 Remove EM_CPU0_EL. Add subsection Caller and callee
saved registers. Add IR blockaddress and indirectbr support. Correct tglobaladdr, tblockaddress,
tjumptable and tglobaltlsaddr of Cpu0InstrInfo.td. Add stacksave and stackrestore support. Add sub-
section frameaddress, returnaddress and eh.return support of chapter Function call. Match Mips 3.7 style. Add bswap
in Chapter Function call. Add section “Vector type (SIMD) support” of Chapter “Other data type”. Add section “Long
branch support” of Chapter “Control flow statements”. Add sub-section “eh.dwarf intrinsic” of Chapter Function call.
Change display “ret $rx” to “jr $rx” where $rx is not $lr. Move sub-section Caller and callee saved registers. Add
sub-sections Live in and live out register. Add Phi node. Replace ch3-proepilog.ll with ch3_largeframe.cpp. Remove
DecodeCMPInstruction(). Re-organize testing ch4_2_1.cpp, ch4_2_2.cpp and ch9_4.cpp. Fix dynamic alloca bug.
Move Cpu0AnalyzeImmediate.cpp and related functions from Chapter3_4 to Chapter3_5. Rename input files.
Version 3.7.0, Released September 24, 2015 Porting to lld 3.7. Change tricore_llvm.pdf web link. Add
C++ atomic to regression test.
Version 3.6.4, Released July 15, 2015 Add C++ atomic support.
Version 3.6.3, Released May 25, 2015 Correct typing.
Version 3.6.2, Released May 3, 2015 Write Appendix B. Split chapter Appendix B from Appendix A.
Move some test from lbt to lbd. Remove warning in build Cpu0 code.
Version 3.6.1, Released March 22, 2015 Add Cpu0 instructions ROLV and RORV.
Version 3.6.0, Released March 9, 2015 Update Appendix A for llvm 3.6. Replace cpp with ll for appear-
ing in document. Move chapter lld, optimization, library to https://github.com/Jonathan2251/lbt.git.
2
Chapter 1. About
Tutorial: Creating an LLVM Backend for the Cpu0 Architecture, Release 3.9.1
Version 3.5.9, Released February 2, 2015 Fix bug of 64 bits shift. Fix global address error by replacing
addiu with ori. Change encode of “cmp $sw, $3, $2” from 0x10320000 to 0x10f32000.
Version 3.5.8, Released December 27, 2014 Correct
for update lb-
dex/src/modify/src/ of install.rst. Add libsoftfloat/compiler-rt and libc/avr-libc-1.8.1. Add LLVM-
VPO in chapter Optimization.
Fix typing error
typing.
Version 3.5.7, Released December 1, 2014 Fix over 16-bits frame prologue/epilogue error from 3.5.3.
Call convention ABI S32 is enabled by option. Change from ADD to ADDu in copyPhysReg() of
Cpu0SEInstrInfo.cpp. Add asm directive .weak back which exists in 3.5.3.
Version 3.5.6, Released November 18, 2014 Remove
Add
Cpu0SetChapter.h for ex-build-test.sh. Correct typing. Fix thread variable error come from
version 3.5.3 in static mode. Add sub-section “Cpu0 backend machine ID and relocation records”
of Chapter 2.
instructions.
IRET
SWI
and
Version 3.5.5, Released November 11, 2014 Rename SPR to C0R. Add ISR simulation.
Version 3.5.4, Released November 6, 2014 Adjust chapter 9 sections. Fix .cprestore bug. Re-organize
sections. Add sub-section “Why not using ADD instead of SUB?” in chapter 2. Add overflow
control option to use ADD and SUB instructions.
Version 3.5.3, Released October 29, 2014 Merge Cpu0 example code into one copy and it can be config
by Cpu0Config.h.
Version 3.5.2, Released October 3, 2014 Move R_CPU0_32 from type of non-relocation record to type
ofrelocation record. Correct logic error for setgt of BrcondPatsSlt of Cpu0InstrInfo.td.
Version 3.5.1, Released October 1, 2014 Add move alias instruction for addu $reg, $zero. Add cpu cy-
cles count in verilog. Fix ISD::SIGN_EXTEND_INREG error in other types beside i1. Support
DAG op br_jt and DAG node JumpTable.
Version 3.5.0, Released September 05, 2014 Issue NOP in delay slot.
Version 3.4.8, Released August 29, 2014 Add reason that set endian swap in memory module. Add pre-
sentation files.
Version 3.4.7, Released August 22, 2014 Fix wrapper_pic for cmov.ll. Add shift operations 64 bits sup-
port. Fix wrapper_pic for ch8_5.cpp. Add section thread of chapter 14. Add section Motivation
of chapter about. Support little endian for cpu0 verilog. Move ch8_5.cpp test from Chapter Run
backend to Chapter lld since it need lld linker. Support both big endian and little endian in cpu0 Verilog, elf2hex and
lld. Make branch release_34_7.
Version 3.4.6, Released July 26, 2014 Add Chapter 15, optimization. Correct typing. Add Chapter 14,
C++. Fix bug of generating cpu032II instruction in dynamic_linker.cpp.
Version 3.4.5, Released June 30, 2014 Correct typing.
Version 3.4.4, Released June 24, 2014 Correct typing. Add the reason of use SSA form. Move sections
LLVM Code Generation Sequence, DAG and Instruction Selection from Chapter 3 to Chapter 2.
Version 3.4.3, Released March 31, 2014 Fix Disassembly bug for GPROut register class. Adjust Chap-
ters. Remove hand copy Table of tblgen in AsmParser.
Version 3.4.2, Released February 9, 2014 Add ch12_2.cpp for slt instruction explanation and fix bug in
Cpu0InstrInfo.cpp. Correct typing. Move Cpu0 Status Register from Number 20 to Number 10. Fix
llc -mcpu option problem. Update example code build shell script. Add condition move instruction.
Fix bug of branch pattern match in Cpu0InstrInfo.td.
Version 3.4.1, Released January 18, 2014 Add ch9_4.cpp to lld test.
Fix the wrong reference in
inlineasm. First instruction jmp X, where X changed from _Z5startv
lbd/lib/Target/Cpu0 code.
to start. Correct typing.
1.5. Revision history
3
Tutorial: Creating an LLVM Backend for the Cpu0 Architecture, Release 3.9.1
Version 3.4.0, Released January 9, 2014 Porting to llvm 3.4 release.
Version 3.3.14, Released January 4, 2014 lld support on iMac. Correct typing.
Version 3.3.13, Released December 27, 2013 Update section Install
Fig/llvmstructure/cpu0_arch.odp.
sphinx on install.rst.
Add
Version 3.3.12, Released December 25, 2013 Correct typing error. Adjust Example Code. Add section
Data operands DAGs of backendstructure.rst. Fix bug in instructions lb and lh of cpu0.v. Fix bug in
itoa.cpp. Add ch7_2_2.cpp for othertype.rst. Add AsmParser reference web.
Version 3.3.11, Released December 11, 2013 Add Figure Code generation and execution flow in
about.rst. Update backendstructure.rst. Correct otherinst.rst. Decoration. Correct typing error.
Version 3.3.10, Released December 5, 2013 Correct typing error. Dynamic linker in lld.rst. Correct er-
rors came from old version of example code. lld.rst.
Version 3.3.9, Released November 22, 2013 Add LLD introduction and Cpu0 static linker document in
lld.rst. Fix the plt bug in elf2hex.h for dynamic linker.
Version 3.3.8, Released November 19, 2013 Fix the reference file missing for make gh-page.
Version 3.3.7, Released November 17, 2013 lld.rst documentation. Add cpu032I and cpu032II in llc -
mcpu. Reference only for Chapter12_2.
Version 3.3.6, Released November 8, 2013 Move example code from github to dropbox since the name
is not work for download example code.
Version 3.3.5, Released November 7, 2013 Split the elf2hex code from modiified llvm-objdump.cpp to
elf2hex.h. Fix bug for tail call setting in LowerCall(). Fix bug for LowerCPLOAD(). Update elf.rst.
Fix typing error. Add dynamic linker support. Merge cpu0 Chapter12_1 and Chapter12_2 code into
one, and identify each of them by -mcpu=cpu0I and -mcpu=cpu0II. cpu0II. Update lld.rst for static linker. Change the
name of example code from LLVMBackendTutorialExampleCode to lbdex.
Version 3.3.4, Released September 21, 2013 Fix Chapter Global variables error for LUi instructions and
the material move to Chapter Other data type. Update regression test items.
Version 3.3.3, Released September 20, 2013 Add Chapter othertype
Version 3.3.2, Released September 17, 2013 Update example code. Fix bug sext_inreg. Fix llvm-
objdump.cpp bug to support global variable of .data. Update install.rst to run on llvm 3.3.
Version 3.3.1, Released September 14, 2013 Add load bool type in chapter 6. Fix chapter 4 error. Add
interrupt function in cpu0i.v. Fix bug in alloc() support of Chapter 8 by adding code of spill $fp
register. Add JSUB texternalsym for memcpy function call of llvm auto reference. Rename cpu0i.v
to cpu0s.v. Modify itoa.cpp. Cpu0 of lld.
Version 3.3.0, Released July 13, 2013 Add Table: C operator ! corresponding IR of .bc and IR of DAG
and Table: C operator ! corresponding IR of Type-legalized selection DAG and Cpu0 instructions.
Add explanation in section Full support %. Add Table: Chapter 4 operators. Add Table: Chapter 3
.bc IR instructions. Rewrite Chapter 5 Global variables. Rewrite section Handle $gp register in PIC addressing mode.
Add Large Frame Stack Pointer support. Add dynamic link section in elf.rst. Re-oganize Chapter 3. Re-oganize
Chapter 8. Re-oganize Chapter 10. Re-oganize Chapter 11. Re-oganize Chapter 12. Fix bug that ret not $lr register.
Porting to LLVM 3.3.
Version 3.2.15, Released June 12, 2013 Porting to llvm 3.3. Rewrite section Support arithmetic instruc-
tions of chapter Adding arithmetic and local pointer support with the table adding. Add two sentences
in Preface. Add llc -debug-pass in section LLVM Code Generation Sequence. Remove section Ad-
just cpu0 instructions. Remove section Use cpu0 official LDI instead of ADDiu of Appendix-C.
Version 3.2.14, Released May 24, 2013 Fix example code disappeared error.
4
Chapter 1. About