write-your-llvm-backend/index.html

2678 lines
140 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.11.dev">
<meta name="author" content="艮 鮟鱇">
<title>手を動かせばできるLLVMバックエンド チュートリアル</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment @import statement to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
:not(pre)>code.nobreak{word-wrap:normal}
:not(pre)>code.nowrap{white-space:nowrap}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
table.tableblock{max-width:100%;border-collapse:separate}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot,table.frame-ends{border-width:1px 0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:50%;border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>手を動かせばできるLLVMバックエンド チュートリアル</h1>
<div class="details">
<span id="author" class="author">艮 鮟鱇</span><br>
<span id="email" class="email"><a href="mailto:ushitora@anqou.net">ushitora@anqou.net</a></span><br>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#_fixme">FIXME</a></li>
<li><a href="#_この文書について">この文書について</a></li>
<li><a href="#_llvmバックエンド概略">LLVMバックエンド概略</a></li>
<li><a href="#_ところで">ところで</a></li>
<li><a href="#_参考にすべき文献">参考にすべき文献</a>
<ul class="sectlevel2">
<li><a href="#_webページ">Webページ</a></li>
<li><a href="#_書籍">書籍</a></li>
<li><a href="#_バックエンド">バックエンド</a></li>
</ul>
</li>
<li><a href="#_isaの仕様を決める">ISAの仕様を決める</a></li>
<li><a href="#_スケルトンバックエンドを追加する">スケルトンバックエンドを追加する</a>
<ul class="sectlevel2">
<li><a href="#_cahpをtripleに追加する">CAHPをTripleに追加する</a></li>
<li><a href="#_cahpのelfフォーマットを定義する">CAHPのELFフォーマットを定義する</a></li>
<li><a href="#_バックエンドを追加する">バックエンドを追加する</a></li>
</ul>
</li>
<li><a href="#_llvmをビルドする">LLVMをビルドする</a></li>
<li><a href="#_llvmをテストする">LLVMをテストする</a></li>
<li><a href="#_アセンブラを作る">アセンブラを作る</a>
<ul class="sectlevel2">
<li><a href="#_tablegenファイルを追加する">TableGenファイルを追加する</a></li>
<li><a href="#_mctargetdesc_を追加する"><code>MCTargetDesc</code> を追加する</a></li>
<li><a href="#_cahpasmparser_を追加する"><code>CAHPAsmParser</code> を追加する</a></li>
<li><a href="#_cahpinstprinter_を実装する"><code>CAHPInstPrinter</code> を実装する</a></li>
<li><a href="#_テストを書く">テストを書く</a></li>
<li><a href="#_メモリ演算を追加する">メモリ演算を追加する</a></li>
<li><a href="#_フィールドを詳細に指定する">フィールドを詳細に指定する</a></li>
<li><a href="#_ディスアセンブラを実装する">ディスアセンブラを実装する</a></li>
<li><a href="#_relocationとfixupに対応する">relocationとfixupに対応する</a></li>
<li><a href="#_hi_と_lo_に対応する"><code>%hi</code><code>%lo</code> に対応する</a></li>
<li><a href="#_li_a0_foo_をエラーにする"><code>li a0, foo</code> をエラーにする</a></li>
<li><a href="#_llvm_objdump_の調査">llvm-objdump の調査</a></li>
<li><a href="#_hlt_疑似命令を追加する"><code>hlt</code> 疑似命令を追加する</a></li>
</ul>
</li>
<li><a href="#_コード生成部を作る">コード生成部を作る</a>
<ul class="sectlevel2">
<li><a href="#_コンパイラのスケルトンを作成する">コンパイラのスケルトンを作成する</a></li>
<li><a href="#_基本的な演算に対応する">基本的な演算に対応する</a></li>
<li><a href="#_定数の実体化に対応する">定数の実体化に対応する</a></li>
<li><a href="#_メモリ演算に対応する">メモリ演算に対応する</a></li>
<li><a href="#_relocationに対応する">relocationに対応する</a></li>
<li><a href="#_条件分岐に対応する">条件分岐に対応する</a></li>
<li><a href="#_関数呼び出しに対応する">関数呼び出しに対応する</a></li>
<li><a href="#_関数プロローグエピローグを実装する">関数プロローグ・エピローグを実装する</a></li>
<li><a href="#_frame_pointer_eliminationを実装する">frame pointer eliminationを実装する</a></li>
<li><a href="#_select_に対応する"><code>select</code> に対応する</a></li>
<li><a href="#_frameindex_をlowerする"><code>FrameIndex</code> をlowerする。</a></li>
<li><a href="#_大きなスタックフレームに対応する">大きなスタックフレームに対応する</a></li>
<li><a href="#_setcc_に対応する"><code>SETCC</code> に対応する</a></li>
<li><a href="#_externalsymbol_に対応する"><code>ExternalSymbol</code> に対応する</a></li>
<li><a href="#_jump_tableを無効化する">jump tableを無効化する</a></li>
<li><a href="#_インラインアセンブリに対応する">インラインアセンブリに対応する</a></li>
<li><a href="#_fastccに対応する">fastccに対応する</a></li>
</ul>
</li>
<li><a href="#_cコンパイラに仕立てる">Cコンパイラに仕立てる</a>
<ul class="sectlevel2">
<li><a href="#_lldにcahpバックエンドを追加する">LLDにCAHPバックエンドを追加する</a></li>
<li><a href="#_clangをcahpに対応させる">ClangをCAHPに対応させる</a></li>
<li><a href="#_crt0_o_と_cahp_lds_の導入"><code>crt0.o</code><code>cahp.lds</code> の導入</a></li>
<li><a href="#_nmagic_の有効化"><code>--nmagic</code> の有効化</a></li>
<li><a href="#_libcの有効化">libcの有効化</a></li>
</ul>
</li>
<li><a href="#_まともなコードを生成する">まともなコードを生成する</a>
<ul class="sectlevel2">
<li><a href="#_分岐解析に対応する">分岐解析に対応する</a></li>
<li><a href="#_branch_relaxationに対応する">branch relaxationに対応する</a></li>
<li><a href="#_16bit命令を活用する">16bit命令を活用する</a></li>
<li><a href="#_jal_を活用する"><code>jal</code> を活用する</a></li>
<li><a href="#_命令スケジューリングを設定する">命令スケジューリングを設定する</a></li>
<li><a href="#_末尾再帰に対応する">末尾再帰に対応する</a></li>
</ul>
</li>
<li><a href="#_落ち穂拾い">落ち穂拾い</a>
<ul class="sectlevel2">
<li><a href="#_スタックを利用した引数渡し">スタックを利用した引数渡し</a></li>
<li><a href="#_byval_の対応"><code>byval</code> の対応</a></li>
<li><a href="#_動的なスタック領域確保に対応する">動的なスタック領域確保に対応する</a></li>
<li><a href="#_emergency_spillに対応する">emergency spillに対応する</a></li>
<li><a href="#_可変長引数関数に対応する">可変長引数関数に対応する</a></li>
<li><a href="#_単体の_sextzexttrunc_に対応する">単体の <code>sext/zext/trunc</code> に対応する</a></li>
<li><a href="#_乗算に対応する">乗算に対応する</a></li>
<li><a href="#_除算剰余に対応する">除算・剰余に対応する</a></li>
<li><a href="#_frameaddrreturnaddr_に対応する"><code>frameaddr/returnaddr</code> に対応する</a></li>
<li><a href="#_rotlrotrbswapcttzctlzctpop_に対応する"><code>ROTL/ROTR/BSWAP/CTTZ/CTLZ/CTPOP</code> に対応する</a></li>
<li><a href="#_32bitのシフトに対応する">32bitのシフトに対応する</a></li>
<li><a href="#_間接ジャンプに対応する">間接ジャンプに対応する</a></li>
<li><a href="#_blockaddress_のlowerに対応する"><code>BlockAddress</code> のlowerに対応する</a></li>
</ul>
</li>
<li><a href="#_参考文献">参考文献</a></li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_fixme">FIXME</h2>
<div class="sectionbody">
<div class="paragraph">
<p>AsciiDocのコメントを用いて文中にFIXMEを仕込む。
その他のFIXME全般的なものなどをここにリストにする。</p>
</div>
<div class="ulist">
<ul>
<li>
<p>だ・である調をです・ます調に変える。</p>
</li>
<li>
<p>実際にやってみる。</p>
<div class="ulist">
<ul>
<li>
<p>現状過去の作業ログを切り貼りしながら書いているので通してちゃんと動くかは良くわからない。</p>
</li>
<li>
<p>ついでにLLVM v10.0.0に対応させる。</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_この文書について">この文書について</h2>
<div class="sectionbody">
<div class="paragraph">
<p>この文書は <a href="https://asciidoctor.org/">Asciidoctor</a>を用いて執筆されています。
記述方法は <a href="https://asciidoctor.org/docs/user-manual/">Asciidoctor User Manual</a>
参考にしてください。</p>
</div>
<div class="paragraph">
<p>この文書はGitによって管理されています。
<a href="https://github.com/ushitora-anqou/write-your-llvm-backend">リポジトリはGitHubにて
公開しています</a></p>
</div>
<div class="paragraph">
<p>この文書におおよそ則って開発されたLLVMバックエンドのソースコードを
<a href="https://github.com/virtualsecureplatform/llvm-cahp">GitHubリポジトリにて公開しています</a></p>
</div>
<div class="paragraph">
<p>この作品は、クリエイティブ・コモンズの 表示 4.0 国際 ライセンスで提供されています。ライセンスの写しをご覧になるには、 <a href="http://creativecommons.org/licenses/by/4.0/" class="bare">http://creativecommons.org/licenses/by/4.0/</a> をご覧頂くか、Creative Commons, PO Box 1866, Mountain View, CA 94042, USA までお手紙をお送りください<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></p>
</div>
<div class="paragraph">
<p>本文書の内容は筆者が独自に調査したものです。
<strong>疑う余地なく誤りが含まれます</strong>。誤りに気づかれた方はGitHubリポジトリなどを通じて
ご連絡ください。なお誤っていそうな部分についてはAsciidoctorのコメント機能を用いて
コメントを残しています。 <code>FIXME</code> というキーワードでソースコードの全文検索をしてください。</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_llvmバックエンド概略">LLVMバックエンド概略</h2>
<div class="sectionbody">
<div class="paragraph">
<p>本書ではRISC-V風味の独自ISAを例にLLVMバックエンドを開発します。</p>
</div>
<div class="paragraph">
<p>使用するLLVMのバージョンはv9.0.0です。</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_ところで">ところで</h2>
<div class="sectionbody">
<div class="paragraph">
<p>一度もコンパイラを書いたことがない人は、この文書を読む前に
『低レイヤを知りたい人のためのCコンパイラ作成入門』<a href="#rui-compilerbook">[50]</a>などで一度
フルスクラッチからコンパイラを書くことをおすすめします。</p>
</div>
<div class="paragraph">
<p>また<a href="#krister-writing_gcc_backend">[51]</a>などを参考に、
LLVMではなくGCCにバックエンドを追加することも検討してみてはいかがでしょうか。</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_参考にすべき文献">参考にすべき文献</h2>
<div class="sectionbody">
<div class="paragraph">
<p>LLVMバックエンドを開発する際に参考にできる書籍やWebサイトを以下に一覧します。
なおこの文書では、RISC-Vバックエンド及びそれに関する技術資料を<strong>大いに</strong>参考しています。</p>
</div>
<div class="sect2">
<h3 id="_webページ">Webページ</h3>
<div class="ulist">
<ul>
<li>
<p>Writing an LLVM Backend<a href="#llvm-writing_backend">[18]</a></p>
<div class="ulist">
<ul>
<li>
<p>分かりにくく読みにくい。正直あんまり見ていないが、たまに眺めると有益な情報を見つけたりもする。</p>
</li>
</ul>
</div>
</li>
<li>
<p>The LLVM Target-Independent Code Generator<a href="#llvm-code_generator">[31]</a></p>
<div class="ulist">
<ul>
<li>
<p><a href="#llvm-writing_backend">[18]</a>よりもよほど参考になる。LLVMバックエンドがどのようにLLVM IRをアセンブリに落とすかが明記されている。必読。</p>
</li>
</ul>
</div>
</li>
<li>
<p>TableGenのLLVMのドキュメント<a href="#llvm-tablegen">[21]</a></p>
<div class="ulist">
<ul>
<li>
<p>情報量が少ない。これを読むよりも各種バックエンドのTableGenファイルを読むほうが良い。</p>
</li>
</ul>
</div>
</li>
<li>
<p>LLVM Language Reference Manual<a href="#llvm-langref">[43]</a></p>
<div class="ulist">
<ul>
<li>
<p>LLVM IRについての言語リファレンス。LLVM IRの仕様などを参照できる。必要に応じて読む。</p>
</li>
</ul>
</div>
</li>
<li>
<p>Architecture &amp; Platform Information for Compiler Writers<a href="#llvm-compilerwriterinfo">[68]</a></p>
<div class="ulist">
<ul>
<li>
<p>LLVMで公式に実装されているバックエンドに関するISAの情報が集約されている。Lanaiの言語仕様へのリンクが貴重。</p>
</li>
</ul>
</div>
</li>
<li>
<p>RISC-V support for LLVM projects<a href="#github_riscv-llvm">[10]</a></p>
<div class="ulist">
<ul>
<li>
<p><strong>どちゃくそに参考になる</strong>。以下の開発はこれに基づいて行う。</p>
</li>
<li>
<p>LLVMにRISC-Vサポートを追加するパッチ群。バックエンドを開発するためのチュートリアルも兼ねているらしく <code>docs/</code> 及びそれと対応したpatchが参考になる。</p>
</li>
<li>
<p>またこれについて、開発者が2018 LLVM Developers' Meetingで登壇したときの動画は<a href="#youtube_llvm-backend-development-by-example">[11]</a>より閲覧できる。スライドは<a href="#speakerdeck-llvm_backend_development">[30]</a>より閲覧できる。</p>
</li>
<li>
<p>そのときのCoding Labは<a href="#lowrisc-devmtg18">[48]</a>より閲覧できる。</p>
</li>
</ul>
</div>
</li>
<li>
<p>Create an LLVM Backend for the Cpu0 Architecture<a href="#cpu0">[35]</a></p>
<div class="ulist">
<ul>
<li>
<p>Cpu0という独自アーキテクチャのLLVMバックエンドを作成するチュートリアル。多少古いが、内容が網羅的で参考になる。英語が怪しい。</p>
</li>
</ul>
</div>
</li>
<li>
<p>FPGA開発日記<a href="#fpga_develop_diary">[44]</a></p>
<div class="ulist">
<ul>
<li>
<p>Cpu0の資料<a href="#cpu0">[35]</a>をもとに1からRISC-Vバックエンドを作成する過程がブログエントリとして公開されている。GitHubに実装も公開されている<a href="#fpga_develop_diary-llvm">[65]</a></p>
</li>
</ul>
</div>
</li>
<li>
<p>ELVMバックエンド<a href="#elvm-llvm_backend">[36]</a></p>
<div class="ulist">
<ul>
<li>
<p>限られた命令でLLVM IRの機能を達成する例として貴重。でも意外とISAはリッチだったりする。</p>
</li>
<li>
<p>作成者のスライドも参考になる<a href="#elvm-slide">[37]</a></p>
</li>
</ul>
</div>
</li>
<li>
<p>2018年度東大CPU実験で開発されたLLVM Backend<a href="#todai_llvm_backend">[40]</a></p>
<div class="ulist">
<ul>
<li>
<p>これについて書かれたAdCのエントリもある<a href="#todai_llvm_backend-article">[41]</a></p>
</li>
</ul>
</div>
</li>
<li>
<p>Tutorial: Building a backend in 24 hours<a href="#llvm-anton_korobeynikov_2012">[45]</a></p>
<div class="ulist">
<ul>
<li>
<p>LLVMバックエンドの大まかな動きについてざっとまとめたあと、 <code>ret</code> だけが定義された最低限のLLVMバックエンド ("stub backend") を構成している。</p>
</li>
<li>
<p>Instruction Selection の説明にある <strong>Does bunch of magic and crazy pattern-matching</strong> が好き。</p>
</li>
</ul>
</div>
</li>
<li>
<p>2017 LLVM Developers Meeting: M. Braun "Welcome to the back-end: The LLVM machine representation"<a href="#llvm-welcome_to_the_back_end_2017">[46]</a></p>
<div class="ulist">
<ul>
<li>
<p>スライドも公開されている<a href="#welcome_to_the_back_end-slides">[135]</a></p>
</li>
<li>
<p>命令選択が終わったあとの中間表現であるLLVM MIR
<code>MachineFunction</code><code>MachineInstr</code> など)や、それに対する操作の解説。
RegStateやframe index・register scavengerなどの説明が貴重。</p>
</li>
</ul>
</div>
</li>
<li>
<p>Howto: Implementing LLVM Integrated Assembler<a href="#ean10-howto-llvmas">[47]</a></p>
<div class="ulist">
<ul>
<li>
<p>LLVM上でアセンブラを書くためのチュートリアル。アセンブラ単体に焦点を絞ったものは珍しい。</p>
</li>
</ul>
</div>
</li>
<li>
<p>Building an LLVM Backend<a href="#LLVMBackend_2015_03_26_v2">[49]</a></p>
<div class="ulist">
<ul>
<li>
<p>対応するレポジトリが<a href="#github-frasercrmck_llvm_leg">[54]</a>にある。</p>
</li>
</ul>
</div>
</li>
<li>
<p>[LLVMdev] backend documentation<a href="#llvm_dev_ml-059799">[116]</a></p>
<div class="ulist">
<ul>
<li>
<p>llvm-devメーリングリストのバックエンドのよいドキュメントは無いかというスレッド。Cpu0とTriCoreが挙げられているが、深くまで記述したものは無いという回答。</p>
</li>
</ul>
</div>
</li>
<li>
<p>TriCore Backend<a href="#tricore-llvm">[118]</a></p>
<div class="ulist">
<ul>
<li>
<p>TriCoreというアーキテクチャ用のバックエンドを書いたという論文。スライドもある<a href="#tricore-llvm-slides">[117]</a>。ソースコードもGitHub上に上がっているが、どれが公式かわからない<sup class="footnote">[<a id="_footnoteref_2" class="footnote" href="#_footnotedef_2" title="View footnote.">2</a>]</sup></p>
</li>
</ul>
</div>
</li>
<li>
<p>Life of an instruction in LLVM<a href="#life_of_an_instruction">[136]</a></p>
<div class="ulist">
<ul>
<li>
<p>Cコードからassemblyまでの流れを概観。</p>
</li>
</ul>
</div>
</li>
<li>
<p>LLVM Backendの紹介<a href="#llvm_backend_intro">[138]</a></p>
<div class="ulist">
<ul>
<li>
<p>「コンパイラ勉強会」<sup class="footnote">[<a id="_footnoteref_3" class="footnote" href="#_footnotedef_3" title="View footnote.">3</a>]</sup>での、LLVMバックエンドの大きな流れ特に命令選択について概観した日本語スライド。</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_書籍">書籍</h3>
<div class="ulist">
<ul>
<li>
<p>『きつねさんでもわかるLLVM〜コンパイラを自作するためのガイドブック〜』<a href="#fox-llvm">[7]</a></p>
<div class="ulist">
<ul>
<li>
<p>数少ない日本語資料。Passやバックエンドの各クラスについて説明している。<a href="#llvm-code_generator">[31]</a>と合わせて大まかな流れを掴むのに良い。</p>
</li>
<li>
<p>ただし書籍中で作成されているバックエンドは機能が制限されており、またコードベースも多少古い。</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>なおLLVMについてGoogleで検索していると"LLVM Cookbook"なる謎の書籍(の電子コピー)が
見つかるが、内容はLLVM公式文書のパクリのようだ<a href="#amazon-llvm_cookbook-customer_review">[139]</a></p>
</div>
</div>
<div class="sect2">
<h3 id="_バックエンド">バックエンド</h3>
<div class="ulist">
<ul>
<li>
<p>RISC-V<a href="#riscv">[5]</a></p>
<div class="ulist">
<ul>
<li>
<p>パッチ群が開発ドキュメントとともに公開されている<a href="#github_riscv-llvm">[10]</a>。以降の開発はこれをベースに行う。</p>
</li>
</ul>
</div>
</li>
<li>
<p>Lanai<a href="#lanai-isa">[103]</a></p>
<div class="ulist">
<ul>
<li>
<p>Googleが開発した32bit RISCの謎アーキテクチャ。全く実用されていないが、バックエンドが単純に設計されておりコメントも豊富のためかなり参考になる<sup class="footnote">[<a id="_footnoteref_4" class="footnote" href="#_footnotedef_4" title="View footnote.">4</a>]</sup><sup class="footnote">[<a id="_footnoteref_5" class="footnote" href="#_footnotedef_5" title="View footnote.">5</a>]</sup></p>
</li>
</ul>
</div>
</li>
<li>
<p>Sparc</p>
<div class="ulist">
<ul>
<li>
<p><a href="#llvm-writing_backend">[18]</a>でも説明に使われており、コメントが豊富。</p>
</li>
</ul>
</div>
</li>
<li>
<p>x86</p>
<div class="ulist">
<ul>
<li>
<p>みんな大好きx86。貴重なCISCの資料であり、かつ2オペランド方式を採用する場合に実装例を与えてくれる。あと <code>EFLAGS</code> の取り回しなども参考になるが、全体的にコードは読みにくい。ただLLVMの命名規則には従うため、他のバックエンドからある程度推論をして読むのが良い。</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_isaの仕様を決める">ISAの仕様を決める</h2>
<div class="sectionbody">
<div class="paragraph">
<p>本書で使用するISAであるCAHPv3について説明します。</p>
</div>
<div class="paragraph">
<p>cahpv3.pdfを参考のこと。</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_スケルトンバックエンドを追加する">スケルトンバックエンドを追加する</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/d0b8dd14570dc9efac09d3c5fd6e8512980fd7b7">d0b8dd14570dc9efac09d3c5fd6e8512980fd7b7</a></p>
</div>
<div class="paragraph">
<p>CAHPのためのビルドを行うために、中身のないバックエンドスケルトンバックエンド
LLVMに追加します。</p>
</div>
<div class="sect2">
<h3 id="_cahpをtripleに追加する">CAHPをTripleに追加する</h3>
<div class="paragraph">
<p><a href="#github_riscv-llvm_docs_02">[8]</a>を参考にして
CAHPをLLVMに認識させます。LLVMではコンパイル先のターゲットをTripleという単位で
管理しています。そのTripleの一つとしてCAHPを追加します。</p>
</div>
<div class="paragraph">
<p><code>llvm/include/llvm/ADT/Triple.h</code><code>llvm/lib/Support/Triple.cpp</code> などの
ファイルにTripleが列挙されているため、そこにCAHPを追加します。
また <code>llvm/unittests/ADT/TripleTest.cpp</code> にTripleが正しく認識されているかをチェックする
テストを書きます。</p>
</div>
</div>
<div class="sect2">
<h3 id="_cahpのelfフォーマットを定義する">CAHPのELFフォーマットを定義する</h3>
<div class="paragraph">
<p><a href="#github_riscv-llvm_patch_03">[13]</a>を参考にして、CAHPのためのELFフォーマットを定義します。
具体的にはCAHPのマシンを表す識別コードや再配置情報などを記述し、
ELFファイルの出力が動作するようにします。
ただし独自ISAではそのような情報が決まっていないため、適当にでっちあげます。</p>
</div>
</div>
<div class="sect2">
<h3 id="_バックエンドを追加する">バックエンドを追加する</h3>
<div class="paragraph">
<p><a href="#github_riscv-llvm_patch_04">[14]</a>を参考に <code>llvm/lib/Target</code> ディレクトリ内に
<code>CAHP</code> ディレクトリを作成し、最低限必要なファイルを用意します。</p>
</div>
<div class="paragraph">
<p>まずビルドのために <code>CMakeLists.txt</code><code>LLVMBuild.txt</code> を用意します。
またCAHPに関する情報を提供するために
<code>CAHPTargetInfo.cpp</code><code>CAHPTargetMachine.cpp</code> などを記述します。</p>
</div>
<div class="paragraph">
<p><code>CAHPTargetMachine.cpp</code> ではdata layoutを文字列で指定します。
詳細はLLVM IRの言語仕様<a href="#llvm-langref-datalayout">[53]</a>を参考してください。</p>
</div>
<div class="paragraph">
<p>以上で必要最小限のファイルを用意することができました。</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_llvmをビルドする">LLVMをビルドする</h2>
<div class="sectionbody">
<div class="paragraph">
<p>LLVMは巨大なプロジェクトで、ビルドするだけでも一苦労です。
以下では継続的な開発のために、高速にLLVMをデバッグビルドする手法を紹介します。
<a href="#github_riscv-llvm_docs_01">[1]</a><a href="#llvm_getting-started">[2]</a><a href="#clang_gettings-started">[3]</a>
参考にしています。</p>
</div>
<div class="paragraph">
<p>ビルドの際には以下のソフトウェアが必要になります。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>cmake</code></p>
</li>
<li>
<p><code>ninja</code></p>
</li>
<li>
<p><code>clang</code></p>
</li>
<li>
<p><code>clang++</code></p>
</li>
<li>
<p><code>lld</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>まずLLVMのソースコードをGitを用いて取得します。
前述したように、今回の開発ではLLVM v9.0.0をベースとします。
そこでブランチ <code>llvmorg-9.0.0</code> から独自実装のためのブランチ <code>cahp</code> を生成し、
以降の開発はこのブランチ上で行うことにします。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ git clone https://github.com/llvm/llvm-project.git
$ cd llvm-project
$ git switch llvmorg-9.0.0
$ git checkout -b cahp</pre>
</div>
</div>
<div class="paragraph">
<p>続いて、ビルドを行うための設定をCMakeを用いて行います。
大量のオプションはビルドを早くするためのものです<a href="#llvm_dev_ml-106187">[96]</a></p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ mkdir build
$ cd build
$ cmake -G Ninja \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DCMAKE_BUILD_TYPE="Debug" \
-DBUILD_SHARED_LIBS=True \
-DLLVM_USE_SPLIT_DWARF=True \
-DLLVM_OPTIMIZED_TABLEGEN=True \
-DLLVM_BUILD_TESTS=True \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_USE_LINKER=lld \
-DLLVM_TARGETS_TO_BUILD="" \
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="CAHP" \
../llvm</pre>
</div>
</div>
<div class="paragraph">
<p>Ninjaを用いてビルドを行います。直接Ninjaを実行しても構いません <code>$ ninja</code> )が、
CMakeを用いて間接的に実行することもできます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ cmake --build .</pre>
</div>
</div>
<div class="paragraph">
<p>手元の環境CPUはIntel Core i7-8700で6コア12スレッド、RAMは16GBでは
30分弱でビルドが完了しました。
また別の環境CPUはIntel Core i5-7200Uで2コア4スレッド、RAMは8GBでは
1時間半程度かかりました。以上から類推すると、
\(n\)コアのCPUを使用する場合およそ\(\frac{180}{n}\)分程度かかるようです。</p>
</div>
<div class="paragraph">
<p>ビルドが終了すると <code>bin/</code> ディレクトリ以下にコンパイルされたバイナリが生成されます。
例えば次のようにして、CAHPバックエンドが含まれていることを確認できます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ bin/llc --version
LLVM (http://llvm.org/):
LLVM version 9.0.0
DEBUG build with assertions.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
Registered Targets:
cahp - CAHP</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>ここでは開発用にデバッグビルドを行いました。
一方で、他人に配布する場合などはリリースビルドを行います。
その際は次のようにCMakeのオプションを指定します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ cmake -G Ninja \
-DLLVM_ENABLE_PROJECTS="lld;clang" \
-DCMAKE_BUILD_TYPE="Release" \
-DLLVM_BUILD_TESTS=True \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_USE_LINKER=lld \
-DLLVM_TARGETS_TO_BUILD="" \
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="CAHP" \
../llvm</pre>
</div>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_llvmをテストする">LLVMをテストする</h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>llvm-lit</code> を使用してLLVMをテストできます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ bin/llvm-lit test -s # 全てのテストを実行する。
$ bin/llvm-lit -s --filter "Triple" test # Tripleに関するテストを実行する。
$ bin/llvm-lit -s --filter 'CAHP' test # CAHPを含むテストを実行する。
$ bin/llvm-lit -as --filter 'CAHP' test # テスト結果を詳細に表示する。
$ bin/llvm-lit -as --filter 'CAHP' --debug test # デバッグ情報を表示する。</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_アセンブラを作る">アセンブラを作る</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/2c31c0a80020cc50bba6df1c35da228905190d97">2c31c0a80020cc50bba6df1c35da228905190d97</a></p>
</div>
<div class="paragraph">
<p>この章ではLLVMバックエンドの一部としてアセンブラを実装します。
具体的にはLLVMのMCLayerを実装し、アセンブリからオブジェクトファイルへの変換を可能にします。
一度にアセンブラ全体を作るのは難しいため、まずレジスタのみを使用する演算命令に絞って実装し、
その後メモリを使用する命令をカバーします。</p>
</div>
<div class="sect2">
<h3 id="_tablegenファイルを追加する">TableGenファイルを追加する</h3>
<div class="paragraph">
<p>LLVM coreは基本的にC&#43;&#43;によって記述されています。一方で、多くの箇所で共通する処理などは
独自のDSLドメイン固有言語であるTableGenを用いて記述し <code>llvm-tblgen</code> という
ソフトウェアを用いてこれをC&#43;&#43;コードに変換しています。
こうすることによって記述量を減らし、ヒューマンエラーを少なくするという考え方
のようです<a href="#llvm-tablegen">[21]</a></p>
</div>
<div class="paragraph">
<p>LLVMバックエンドでは、アーキテクチャが持つレジスタや命令などの情報をTableGenによって
記述します。大まかに言って、TableGenで書ける場所はTableGenによって書き、
対応できない部分をC&#43;&#43;で直に書くというのがLLVM coreの方針のようです。
ここでは、簡単なアセンブラを実装するために最低限必要なTableGenファイルを追加します。
内訳は次のとおりです。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CAHP.td</code>: 下のTableGenファイルをincludeし、その他もろもろを定義。</p>
</li>
<li>
<p><code>CAHPRegisterInfo.td</code>: レジスタを定義。</p>
</li>
<li>
<p><code>CAHPInstrFormats.td</code>: 命令形式を定義。</p>
</li>
<li>
<p><code>CAHPInstrInfo.td</code>: 命令を定義。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>順に説明します。 <code>CAHP.td</code> がTableGenファイル全体をまとめているTableGenファイルで、
内部では <code>include</code> を使って他のファイルを読み込んでいます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>include "llvm/Target/Target.td"</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>include "CAHPRegisterInfo.td"
include "CAHPInstrInfo.td"</pre>
</div>
</div>
<div class="paragraph">
<p>また同時に、今回想定するプロセッサを表す <code>ProcessorModel</code> や、
現在実装しているターゲットの <code>CAHP</code> について定義しています。</p>
</div>
<div class="paragraph">
<p><code>CAHPRegisterInfo.td</code> ではCAHPに存在するレジスタを定義します。
まず <code>Register</code> を継承して <code>class CAHPReg</code> を作り、これに基本的なレジスタの性質をもたせます。
ついで <code>class CAHPReg</code> の実体として <code>X0</code> から <code>X15</code> を作成します。
<code>alt</code> にはレジスタの別名を指定します。
最後に、レジスタをまとめて <code>RegisterClass</code> である <code>GPR</code>
General Purpose Register; 汎用レジスタの意)を定義します。
このあと命令を定義する際にはこの <code>RegisterClass</code> 単位で指定します。
ここでレジスタを並べる順番が先であるほどレジスタ割り付けで割り付けられやすいため、
caller-savedなもの使ってもspill outが起こりにくいものを先に並べておきます。</p>
</div>
<div class="paragraph">
<p><code>GPR</code> と同様に <code>SP</code> という <code>RegisterClass</code> も作成し、 <code>X1</code>
つまりスタックポインタを表すレジスタのみを追加しておきます。
この <code>RegisterClass</code> を命令のオペランドに指定することで
<code>lwsp</code><code>swsp</code> などの「スタックポインタのみを取る命令」を表現することができます。</p>
</div>
<div class="paragraph">
<p>命令は <code>CAHPInstrFormats.td</code><code>CAHPInstrInfo.td</code> に分けて記述します。
<code>CAHPInstrFormats.td</code> ではおおよその命令の「形」を定義しておき、
<code>CAHPInstrInfo.td</code> でそれを具体化します。言葉で言ってもわかりにくいので、コードで見ます。
例えば24bit長の加算命令は次のように定義されます。
まずCAHPの命令全体に共通する事項を <code>class CAHPInst</code> として定義します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>class CAHPInst&lt;dag outs, dag ins, string opcodestr, string argstr, list&lt;dag&gt; pattern = []&gt;
: Instruction {
let Namespace = "CAHP";
dag OutOperandList = outs;
dag InOperandList = ins;
let AsmString = opcodestr # "\t" # argstr;
// Matching patterns used when converting SelectionDAG into MachineDAG.
let Pattern = pattern;
}</pre>
</div>
</div>
<div class="paragraph">
<p>次に、CAHPの24bit命令に共通する事項を <code>class CAHPInst</code> を継承した
<code>class CAHP24Inst</code> として定義します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>// 24-bit instruction format.
class CAHPInst24&lt;dag outs, dag ins, string opcodestr, string argstr, list&lt;dag&gt; pattern = []&gt;
: CAHPInst&lt;outs, ins, opcodestr, argstr, pattern&gt; {
let Size = 3;
bits&lt;24&gt; Inst;
}</pre>
</div>
</div>
<div class="paragraph">
<p>さらに、24bit長加算命令の「形」である24bit R形式オペランドにレジスタを3つとる
<code>class CAHPInst24R</code> として定義します。 <code>class CAHPInst24</code> を継承します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>// 24-bit R-instruction format.
class CAHPInst24R&lt;bits&lt;8&gt; opcode, dag outs, dag ins, string opcodestr, string argstr&gt;
: CAHPInst24&lt;outs, ins, opcodestr, argstr&gt; {
bits&lt;4&gt; rd;
bits&lt;4&gt; rs1;
bits&lt;4&gt; rs2;
let Inst{23-20} = 0;
let Inst{19-16} = rs2;
let Inst{15-12} = rs1;
let Inst{11-8} = rd;
let Inst{7-0} = opcode;
}</pre>
</div>
</div>
<div class="paragraph">
<p>最後にこれを使って加算命令 <code>ADD</code> を定義します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>def ADD : CAHPInst24R&lt;0b00000001, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
"add", "$rd, $rs1, $rs2"&gt;;</pre>
</div>
</div>
<div class="paragraph">
<p>上記の継承による構造を展開すると、結局 <code>class Instruction</code> を使って
次のような定義を行ったことになります。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>def ADD : Instruction {
let Namespace = "CAHP";
let Pattern = [];
let Size = 3; // 命令長は8bit * 3 = 24bit
bits&lt;24&gt; Inst;
bits&lt;4&gt; rd; // オペランドrdは4bit
bits&lt;4&gt; rs1; // オペランドrs1は4bit
bits&lt;4&gt; rs2; // オペランドrs2は4bit
// 命令のエンコーディングは次の通り。
let Inst{23-20} = 0; // 20〜23bit目は0
let Inst{19-16} = rs2; // 16〜19bit目はrs2
let Inst{15-12} = rs1; // 12〜15bit目はrs1
let Inst{11-8} = rd; // 8〜11bit目はrd
let Inst{7-0} = 0b00000001; // 0〜7bit目は0bit目だけが1で残りは0
// 出力はレジスタクラスGPRのrdに入る。
dag OutOperandList = (outs GPR:$rd);
// 入力はレジスタクラスGPRのrs1とrs2に入る。
dag InOperandList = (ins GPR:$rs1, GPR:$rs2);
// アセンブリ上では「add rd, rs1, rs2」という形で与えられる。
let AsmString = "add\t$rd, $rs1, $rs2";
}</pre>
</div>
</div>
<div class="paragraph">
<p><code>Inst</code> フィールドにエンコーディングを設定することで、
TableGenにエンコードの処理を移譲することができます<sup class="footnote">[<a id="_footnoteref_6" class="footnote" href="#_footnotedef_6" title="View footnote.">6</a>]</sup></p>
</div>
<div class="paragraph">
<p>続いて即値を用いる命令を見ます。例として <code>addi</code> を取り上げます。
<code>addi</code> は8bit符号付き即値をオペランドに取ります。まずこれを定義します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>class ImmAsmOperand&lt;string prefix, int width, string suffix&gt; : AsmOperandClass {
let Name = prefix # "Imm" # width # suffix;
let RenderMethod = "addImmOperands";
let DiagnosticType = "Invalid" # Name;
}</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>class SImmAsmOperand&lt;int width, string suffix = ""&gt;
: ImmAsmOperand&lt;"S", width, suffix&gt; {
}</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>def simm8 : Operand&lt;i16&gt; {
let ParserMatchClass = SImmAsmOperand&lt;8&gt;;
}</pre>
</div>
</div>
<div class="paragraph">
<p>続いて命令の「形」を定義します。 <code>addi</code> は24bit I形式です。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>class CAHPInst24I&lt;bits&lt;8&gt; opcode, dag outs, dag ins, string opcodestr, string argstr&gt;
: CAHPInst24&lt;outs, ins, opcodestr, argstr&gt; {
bits&lt;4&gt; rd;
bits&lt;4&gt; rs1;
bits&lt;8&gt; imm;
let Inst{23-16} = imm;
let Inst{15-12} = rs1;
let Inst{11-8} = rd;
let Inst{7-0} = opcode;
}</pre>
</div>
</div>
<div class="paragraph">
<p>最後に、これを用いて <code>addi</code> を定義します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>def ADDI : CAHPInst24I&lt;0b11000011, (outs GPR:$rd), (ins GPR:$rs1, simm8:$imm),
"addi", "$rd, $rs1, $imm"&gt;;</pre>
</div>
</div>
<div class="paragraph">
<p><code>add</code> の際には <code>GPR</code> とした第三オペランドが <code>simm8</code> となっています。
これによって、この部分に符号付き8bit即値が来ることを指定しています。</p>
</div>
<div class="paragraph">
<p>即値のうち、下位1bitが0になるものは <code>_lsb0</code> というサフィックスを名前につけ区別しておきます。
<code>uimm7_lsb0</code><code>simm11_lsb0</code> がそれに当たります。
後々、C&#43;&#43;コードにてこの制限が守られているかをチェックします。</p>
</div>
<div class="paragraph">
<p><code>add2</code> のような2オペランドの命令を記述する場合、上の方法では問題があります。
というのも <code>add2</code> の第一オペランドは入力であると同時に出力先でもあるためです。
このような場合は次のように <code>Constraints</code> フィールドにその旨を記述します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>let Constraints = "$rd = $rd_w" in {
def ADD2 : CAHPInst16R&lt;0b10000000, (outs GPR:$rd_w), (ins GPR:$rd, GPR:$rs),
"add2", "$rd, $rs"&gt;;
}</pre>
</div>
</div>
<div class="paragraph">
<p>なおTableGenでは <code>let</code> で囲むレコードが一つの場合は括弧 <code>{ }</code> は必要ありません。
また <code>let</code> で外からフィールドを上書きするのと、 <code>def</code> の中身に記載するのとで意味は
変わりません。すなわち、上のコードは次の2通りと意味は異なりません<a href="#llvm-tablegen-langref">[25]</a></p>
</div>
<div class="literalblock">
<div class="content">
<pre>let Constraints = "$rd = $rd_w" in
def ADD2 : CAHPInst16R&lt;0b10000000, (outs GPR:$rd_w), (ins GPR:$rd, GPR:$rs),
"add2", "$rd, $rs"&gt;;</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>def ADD2 : CAHPInst16R&lt;0b10000000, (outs GPR:$rd_w), (ins GPR:$rd, GPR:$rs),
"add2", "$rd, $rs"&gt; {
let Constraints = "$rd = $rd_w";
}</pre>
</div>
</div>
<div class="paragraph">
<p>必要なTableGenファイルを追加した後、
これらのTableGenファイルが正しいかどうか <code>llvm-tblgen</code> を用いて確認します。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ bin/llvm-tblgen -I ../llvm/lib/Target/CAHP/ -I ../llvm/include/ -I ../llvm/lib/Target/ ../llvm/lib/Target/CAHP/CAHP.td</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_mctargetdesc_を追加する"><code>MCTargetDesc</code> を追加する</h3>
<div class="paragraph">
<p>アセンブラ本体のC&#43;&#43;コードを作成します。ここでは、
アセンブリのエンコードからバイナリ生成部分を担当する <code>MCTargetDesc</code> ディレクトリを追加し、
必要なファイルを揃えます。複数のクラスを定義しますが、それらは全て
<code>MCTargetDesc/CAHPMCTargetDesc.cpp</code> にある <code>LLVMInitializeCAHPTargetMC</code>
関数でLLVM coreに登録されます。</p>
</div>
<div class="paragraph">
<p>定義するクラスは次のとおりです。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CAHPMCAsmInfo</code></p>
</li>
<li>
<p><code>CAHPMCInstrInfo</code></p>
</li>
<li>
<p><code>CAHPMCRegisterInfo</code></p>
</li>
<li>
<p><code>CAHPMCSubtargetInfo</code></p>
</li>
<li>
<p><code>CAHPMCCodeEmitter</code></p>
</li>
<li>
<p><code>CAHPAsmBackend</code></p>
</li>
<li>
<p><code>CAHPELFObjectWriter</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>順に説明します。</p>
</div>
<div class="paragraph">
<p><code>CAHPMCAsmInfo</code> にはアセンブリがどのように表記されるかを主に記述します。
<code>MCTargetDesc/CAHPMCAsmInfo.{h,cpp}</code> に記述します。</p>
</div>
<div class="paragraph">
<p><code>CAHPMCInstrInfo</code> は先程記述したTableGenファイルから、
TableGenによって <code>InitCAHPMCInstrInfo</code> 関数として自動的に生成されます。
<code>CAHPMCTargetDesc.cpp</code> 内でこれを呼び出して作成します。</p>
</div>
<div class="paragraph">
<p><code>CAHPMCRegisterInfo</code> も同様に自動的に生成されます。
<code>InitCAHPMCRegisterInfo</code> 関数を呼び出します。なおこの関数の第二引数には
関数の戻りアドレスが入るレジスタを指定します<sup class="footnote">[<a id="_footnoteref_7" class="footnote" href="#_footnotedef_7" title="View footnote.">7</a>]</sup>
CAHPではx0を表す <code>CAHP::X0</code> を渡すことになります。</p>
</div>
<div class="paragraph">
<p><code>CAHPMCSubtargetInfo</code> も同様に自動生成されます。
<code>createCAHPMCSubtargetInfoImpl</code> を呼び出します。この関数の第二引数には
<code>CAHP.td</code><code>ProcessorModel</code> として定義したCPUの名前を指定します。</p>
</div>
<div class="paragraph">
<p><code>CAHPMCCodeEmitter</code> はアセンブリのエンコード作業を行います。
<code>MCTargetDesc/CAHPMCCodeEmitter.cpp</code> に記述します。
主要なエンコード処理はTableGenによって自動生成された
<code>getBinaryCodeForInstr</code><code>CAHPMCCodeEmitter::encodeInstruction</code>
から呼び出すことによって行われます。
この関数は <code>CAHPGenMCCodeEmitter.inc</code> というファイルに定義されるため、
これを <code>MCTargetDesc/CAHPMCCodeEmitter.cpp</code> 末尾で <code>#include</code> しておきます。</p>
</div>
<div class="paragraph">
<p><code>CAHPAsmBackend</code> にはオブジェクトファイルを作成する際に必要な
fixupの操作 <code>applyFixup</code> )や指定バイト数分の無効命令を書き出す処理( <code>writeNopData</code>
などを記述します。 <code>MCTargetDesc/CAHPAsmBackend.cpp</code> に記述します。
fixupについては後ほど実装するためここではスタブにしておきます。</p>
</div>
<div class="paragraph">
<p><code>CAHPELFObjectWriter</code> にはELFファイルの特にヘッダを作成する際に必要な情報を記載します。
このクラスは <code>LLVMInitializeCAHPTargetMC</code> ではなく
<code>CAHPAsmBackend</code><code>createObjectTargetWriter</code> メンバ関数として紐付けられます。
親クラス <code>MCELFObjectTargetWriter</code> のコンストラクタに、
CAHPマシンを表す <code>ELF::EM_CAHP</code> と、 <code>.rel</code> ではなく <code>.rela</code> を使用する旨を示す
<code>true</code> を渡しておきます<sup class="footnote">[<a id="_footnoteref_8" class="footnote" href="#_footnotedef_8" title="View footnote.">8</a>]</sup>
また <code>getRelocType</code> メンバ関数はどのような再配置を行うかを見繕うためのものですが、
ここではスタブにしておきます。</p>
</div>
<div class="paragraph">
<p>上記を実装してビルドします。一度使ってみましょう。
LLVMのアセンブラを単体で使う場合は <code>llvm-mc</code> というコマンドを使用します。
次のようにすると <code>foo.s</code> というアセンブリファイルをオブジェクトファイルに
変換できます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ bin/llvm-mc -arch=cahp -filetype=obj foo.s
bin/llvm-mc: error: this target does not support assembly parsing.</pre>
</div>
</div>
<div class="paragraph">
<p>このようなエラーメッセージが出れば成功です<sup class="footnote">[<a id="_footnoteref_9" class="footnote" href="#_footnotedef_9" title="View footnote.">9</a>]</sup>
このエラーメッセージはCAHPターゲットがアセンブリのパーズ構文解析に対応していない
ことを意味しています。これは次の節で実装します。</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>RISC-Vの拡張C命令には <code>add</code> などレジスタを5bitで指定する命令と、
<code>sub</code> などレジスタを3bitで指定する命令の2種類があります。
LLVM RISC-Vバックエンドを見ると、
エンコードに際してこれらの区別のための特別な処理は行っていません。
というのも、3bitでレジスタを指定する場合その添字の下位3bit以外が無視されるため、
結果的に正しいコードが出力されるのです。
例えば <code>x8</code> を指定すると、これに <code>1000</code> という添字が振られ、
4bit目を無視することで <code>000</code> となるため、
3bitでのレジスタ指定方法として正しいものになります。</p>
</div>
<div class="paragraph">
<p>独自ISAなどで、このような手法が取れないレジスタの並びを使用する場合は、
アセンブリをコードに変換する際にそのレジスタのエンコーディングを補正します。
このようなレジスタオペランドエンコードのフックを行う関数を指定する場所として
<code>RegisterOperand</code><code>EncoderMethod</code> があります。
例えば <code>sub</code><code>X3</code> から <code>X10</code> を0〜7というエンコードで用いたい場合、
<code>X3</code> から <code>X10</code><code>GPRC</code> という <code>RegisterClass</code> とした上で、
これを <code>RegisterOperand</code> で包み <code>ShiftedGPRC</code> とします。
これの <code>EncoderMethod</code> として <code>RV32KEncodeShiftedGPRCRegisterOperand</code> という関数を指定します。
これは <code>RV32KMCCodeEmitter</code> クラスのメンバ関数として定義する。
これによって任意の処理をフックすることができる。https://reviews.llvm.org/rL303044</p>
</div>
<div class="literalblock">
<div class="content">
<pre>def GPRC : RegisterClass&lt;"RV32K", [i32], 32, (add
X3, X4, X5, X6, X7, X8, X9, X10
)&gt;;
def ShiftedGPRC : RegisterOperand&lt;GPRC&gt; {
let EncoderMethod = "RV32KEncodeShiftedGPRCRegisterOperand";
//let DecoderMethod = "RV32KDecodeShiftedGPRCRegisterOperand";
}</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>uint64_t
RV32KEncodeShiftedGPRCRegisterOperand(const MCInst &amp;MI, unsigned no,
SmallVectorImpl&lt;MCFixup&gt; &amp;Fixups,
const MCSubtargetInfo &amp;STI) const;
uint64_t RV32KMCCodeEmitter::RV32KEncodeShiftedGPRCRegisterOperand(
const MCInst &amp;MI, unsigned no, SmallVectorImpl&lt;MCFixup&gt; &amp;Fixups,
const MCSubtargetInfo &amp;STI) const {
const MCOperand &amp;MO = MI.getOperand(no);
if (MO.isReg()) {
uint64_t op = Ctx.getRegisterInfo()-&gt;getEncodingValue(MO.getReg());
assert(3 &lt;= op &amp;&amp; op &lt;= 10 &amp;&amp; "op should belong to GPRC.");
return op - 3;
}
llvm_unreachable("Unhandled expression!");
return 0;
}</pre>
</div>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_cahpasmparser_を追加する"><code>CAHPAsmParser</code> を追加する</h3>
<div class="paragraph">
<p>アセンブリのパーズは <code>CAHPAsmParser</code> クラスが取り仕切っています。
新しく <code>AsmParser</code> ディレクトリを作成し、その中に <code>CAHPAsmParser.cpp</code> を作成して
パーズ処理を記述します。<a href="#github_riscv-llvm_patch_07">[19]</a>を参考にします。</p>
</div>
<div class="paragraph">
<p><code>CAHPAsmParser::ParseInstruction</code> がパーズ処理のエントリポイントです。
<code>CAHPAsmParser::parseOperand</code><code>CAHPAsmParser::parseRegister</code>
<code>CAHPAsmParser::parseImmediate</code> を適宜用いながら、
アセンブリのトークンを切り出し <code>Operands</code> に詰め込みます<sup class="footnote">[<a id="_footnoteref_10" class="footnote" href="#_footnotedef_10" title="View footnote.">10</a>]</sup></p>
</div>
<div class="paragraph">
<p>この際にオペランドを表すクラスとして <code>CAHPOperand</code> を定義・使用しています。
オペランドとして現れうるのはレジスタと即値とその他のトークン(命令や括弧文字など)なので
その旨を記述します<sup class="footnote">[<a id="_footnoteref_11" class="footnote" href="#_footnotedef_11" title="View footnote.">11</a>]</sup>
TableGenにて定義・使用した即値を正しく認識するために <code>isUImm4</code><code>isSImm11Lsb0</code> などの
メンバ関数を定義する必要があります。これらの関数は後述の <code>MatchInstructionImpl</code> 内で
使用されます。</p>
</div>
<div class="paragraph">
<p>切り出されたオペランドのリストを命令としてLLVMに認識させるのは <code>MatchAndEmitInstruction</code>
行います。具体的には、先程の <code>Operands</code> を読み込んで <code>MCInst</code> に変換します。
ただし実際の処理の殆どはTableGenによって自動生成された <code>MatchInstructionImpl</code> によって
行われます。実際に書く必要があるのはこの関数が失敗した場合のエラーメッセージ等です。</p>
</div>
<div class="paragraph">
<p><code>CAHPAsmParser</code> を実装するとアセンブラが完成します。使ってみましょう。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ cat foo.s
li x9, 3
mv x11, x1
sub x9, x10
add x8, x1
nop
$ bin/llvm-mc -arch=rv32k -filetype=obj foo.s | od -tx1z -Ax -v
000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 &gt;.ELF............&lt;
000010 01 00 f5 00 01 00 00 00 00 00 00 00 00 00 00 00 &gt;................&lt;
000020 68 00 00 00 00 00 00 00 34 00 00 00 00 00 28 00 &gt;h.......4.....(.&lt;
000030 04 00 01 00 8d 44 86 85 89 8c 06 94 01 00 00 00 &gt;.....D..........&lt;
000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &gt;................&lt;
000050 00 2e 74 65 78 74 00 2e 73 74 72 74 61 62 00 2e &gt;..text..strtab..&lt;
000060 73 79 6d 74 61 62 00 00 00 00 00 00 00 00 00 00 &gt;symtab..........&lt;
000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &gt;................&lt;
000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &gt;................&lt;
000090 07 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 &gt;................&lt;
0000a0 50 00 00 00 17 00 00 00 00 00 00 00 00 00 00 00 &gt;P...............&lt;
0000b0 01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 &gt;................&lt;
0000c0 06 00 00 00 00 00 00 00 34 00 00 00 0a 00 00 00 &gt;........4.......&lt;
0000d0 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 &gt;................&lt;
0000e0 0f 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 &gt;................&lt;
0000f0 40 00 00 00 10 00 00 00 01 00 00 00 01 00 00 00 &gt;@...............&lt;
000100 04 00 00 00 10 00 00 00 &gt;........&lt;
000108</pre>
</div>
</div>
<div class="paragraph">
<p>0x34から0x3dにある <code>8d 44 86 85 89 8c 06 94 01 00</code> が出力であり、
正しく生成されていることが分かります。</p>
</div>
</div>
<div class="sect2">
<h3 id="_cahpinstprinter_を実装する"><code>CAHPInstPrinter</code> を実装する</h3>
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/aa66568c3dfe1d80a83a96bd0437a26fdb96872a">aa66568c3dfe1d80a83a96bd0437a26fdb96872a</a></p>
</div>
<div class="paragraph">
<p>次の節では、上記までで作成したアセンブラのテストを記述します。
その際、アセンブリを <code>MCInst</code> に変換した上でそれをアセンブリに逆変換したものが、
もとのアセンブリと同じであるか否かをチェックします。
このテストを行うためには <code>MCInst</code> からアセンブリを得るための仕組みが必要です。
この節ではこれを行う <code>CAHPInstPrinter</code> クラスを実装します。
<a href="#github_riscv-llvm_patch_08">[20]</a>を参考にします。</p>
</div>
<div class="paragraph">
<p><code>InstPrinter</code> ディレクトリを作成し <code>InstPrinter/CAHPInstPrinter.{cpp,h}</code> を作成します。
命令印字処理の本体は <code>CAHPInstPrinter::printInst</code> ですが、
そのほとんどの処理は <code>CAHPInstPrinter::printInstruction</code> というTableGenが生成する
メンバ関数により実行されます。 <code>CAHPInstPrinter::printRegName</code> はレジスタ名を
出力する関数で <code>CAHPInstPrinter::printOperand</code> から呼ばれますが、
これも <code>CAHPInstPrinter::getRegisterName</code> という自動生成された
メンバ関数に処理を移譲します。この <code>CAHPInstPrinter::getRegisterName</code> の第二引数に
何も渡さなければ(デフォルト引数 <code>CAHP::ABIRegAltName</code> を利用すれば)
TableGenで定義したAltNameが出力に使用されます<sup class="footnote">[<a id="_footnoteref_12" class="footnote" href="#_footnotedef_12" title="View footnote.">12</a>]</sup>
<code>CAHP::NoRegAltName</code> を渡すと本来の名前CAHPでは <code>x0</code><code>x15</code> )が使用されます。</p>
</div>
<div class="paragraph">
<p><code>CAHPInstPrinter</code> クラスは <code>MCTargetDesc/CAHPMCTargetDesc.cpp</code> にて作成・登録されます。</p>
</div>
<div class="paragraph">
<p>節の冒頭で説明した「アセンブリを <code>MCInst</code> に変換した上でそれをアセンブリに逆変換」は
<code>llvm-mc</code><code>-show-encoding</code> オプションを用いて行うことができます。
<code>-show-encoding</code> を指定することよって当該アセンブリがどのような機械語に
翻訳されるか確認することができます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ cat foo.s
// FIXME
$ bin/llvm-mc -arch=rv32k -show-encoding foo.s
.text
li x9, 3 # encoding: [0x8d,0x44]
mv x11, x1 # encoding: [0x86,0x85]
sub x9, x10 # encoding: [0x89,0x8c]
add x8, x1 # encoding: [0x06,0x94]
nop # encoding: [0x01,0x00]</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_テストを書く">テストを書く</h3>
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/c8bbf894c7ba046ddd3f55677f2d4512dd944aa0">c8bbf894c7ba046ddd3f55677f2d4512dd944aa0</a></p>
</div>
<div class="paragraph">
<p>前節で動作させた <code>-show-encoding</code> オプションを用いて、
アセンブラが正しく動作していることを確認するためのテストを記述します。
前節と同様にパッチ<a href="#github_riscv-llvm_patch_08">[20]</a>を参考にします。</p>
</div>
<div class="paragraph">
<p>まず <code>test/MC/CAHP</code> ディレクトリを作成し、その中に <code>cahp-valid.s</code><code>cahp-invalid.s</code>
作成します。前者で正しいアセンブリが適切に処理されるか、
後者で誤ったアセンブリに正しくエラーを出力するかを確認します。</p>
</div>
<div class="paragraph">
<p>記述後 <code>llvm-lit</code> を用いてテストを行います。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ bin/llvm-lit -as --filter 'RV32K' test
PASS: LLVM :: MC/RV32K/rv32k-valid.s (1 of 2)
Script:
--
: 'RUN: at line 1'; /home/anqou/workspace/llvm-project/build/bin/llvm-mc /data/anqou/workspace/llvm-project/llvm/test/MC/RV32K/rv32k-valid.s -triple=rv32k -show-encoding | /home/anqou/workspace/llvm-project/build/bin/FileCheck -check-prefixes=CHECK,CHECK-INST /data/anqou/workspace/llvm-project/llvm/test/MC/RV32K/rv32k-valid.s
--
Exit Code: 0
********************
PASS: LLVM :: MC/RV32K/rv32k-invalid.s (2 of 2)
Script:
--
: 'RUN: at line 1'; not /home/anqou/workspace/llvm-project/build/bin/llvm-mc -triple rv32k &lt; /data/anqou/workspace/llvm-project/llvm/test/MC/RV32K/rv32k-invalid.s 2&gt;&amp;1 | /home/anqou/workspace/llvm-project/build/bin/FileCheck /data/anqou/workspace/llvm-project/llvm/test/MC/RV32K/rv32k-invalid.s
--
Exit Code: 0
********************
Testing Time: 0.11s
Expected Passes : 2</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_メモリ演算を追加する">メモリ演算を追加する</h3>
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/43145f861dc729756a8a85df13a7257248e98169">43145f861dc729756a8a85df13a7257248e98169</a></p>
</div>
<div class="paragraph">
<p>前節までで、レジスタのみを使用する命令に対応しました。この節ではメモリを使用する
命令に対応します。具体的にはメモリから1ワード2バイト読み込む <code>lw</code>
1ワード書き込む <code>sw</code> 、及びその1バイト版である <code>lb/lbu/sb</code>
更にスタックへの読み書きに特化した <code>lwsp/swsp</code> を追加します。</p>
</div>
<div class="paragraph">
<p>まずTableGenにこれらの命令を定義します。
CAHPアセンブリ中ではメモリは即値とレジスタの組み合わせで表現されます。
例えば <code>x8</code> に入っている値に <code>4</code> 足した番地から1ワード読み込んで <code>x9</code> に入れる場合は
<code>lw x9, 4(x8)</code> と書きます。これを正しく表示するために <code>AsmString</code> にはこのように書きます。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>def LW : CAHPInst24MLoad &lt;0b010101, (outs GPR:$rd), (ins GPR:$rs, simm11_lsb0:$imm),
"lw", "$rd, ${imm}(${rs})"&gt;</pre>
</div>
</div>
<div class="paragraph">
<p>ここで <code>${imm}</code> と括弧でくくっているのは、単に <code>$imm(</code> とかくと <code>imm(</code> という識別子として
認識されてしまうためです。</p>
</div>
<div class="paragraph">
<p>次いでこれらのアセンブリをパーズできるように <code>CAHPAsmParser</code> に手を加えます。
<code>CAHPAsmParser::parseMemOpBaseReg</code> メンバ関数を定義してメモリ指定のアセンブリである
<code>即値(レジスタ)</code> という形を読み込めるようにし、これを <code>CAHPAsmParser::parseOperand</code> から
呼び出します。</p>
</div>
<div class="paragraph">
<p>最後にテストを書きます。</p>
</div>
</div>
<div class="sect2">
<h3 id="_フィールドを詳細に指定する">フィールドを詳細に指定する</h3>
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/1963e0288a450c3785723861c7c5d5c7280186fc">1963e0288a450c3785723861c7c5d5c7280186fc</a></p>
</div>
<div class="paragraph">
<p>各命令がどのような特性を持つかをTableGenで指定します。
この情報はコード生成の際に使用されます。
これらのフィールドは <code>llvm/include/llvm/Target/Target.td</code>
にてコメントとともに定義されています。</p>
</div>
<div class="paragraph">
<p>以下に主要なフィールドについて説明します。</p>
</div>
</div>
<div class="sect2">
<h3 id="_ディスアセンブラを実装する">ディスアセンブラを実装する</h3>
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/01fdfc0e1a5281527e339913ee08cb0da9d75f46">01fdfc0e1a5281527e339913ee08cb0da9d75f46</a></p>
</div>
<div class="paragraph">
<p><a href="#github_riscv-llvm_patch_10">[16]</a>を参考にしてディスアセンブラを実装します。
<code>Disassembler</code> ディレクトリを作成して <code>Disassembler/CAHPDisassembler.cpp</code>
を追加・記述します。</p>
</div>
<div class="paragraph">
<p>ディスアセンブラの本体は <code>CAHPDisassembler::getInstruction</code> です。
ディスアセンブルの処理のほとんどはTableGenが生成する <code>decodeInstruction</code> 関数によって
行われます。CAHPでは24bitの命令と16bitの命令が混在するため、
バイナリ列を解析してどちらの命令かを判断し、 <code>decodeInstruction</code> の第一引数に
渡すテーブルを選びます。</p>
</div>
<div class="paragraph">
<p>レジスタのディスアセンブルは <code>DecodeGPRRegisterClass</code> にて行います。</p>
</div>
<div class="paragraph">
<p>即値のディスアセンブルは <code>decodeUImmOperand</code><code>decodeSImmOperand</code> にて
行います。これらの関数は <code>CAHPInstrInfo.td</code> にて 即値オペランドの <code>DecoderMethod</code> として
指定します。</p>
</div>
<div class="paragraph">
<p>ナイーブに実装すると <code>lwsp</code><code>swsp</code> が入ったバイナリをディスアセンブルしようとしたときに
エラーがでる。これは例えば次のようにして確認することができる。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>$ cat test.s
lwsp x11, 0(sp)
$ bin/llvm-mc -filetype=obj -triple=rv32k &lt; test.s | bin/llvm-objdump -d -</pre>
</div>
</div>
<div class="paragraph">
<p>原因は <code>lwsp</code><code>swsp</code> がアセンブリ上はspというオペランドをとるにも関わらず、
バイナリにはその情報が埋め込まれないためである。このためディスアセンブル時に
オペランドが一つ足りない状態になり、配列の添字チェックに引っかかってしまう。</p>
</div>
<div class="paragraph">
<p>これを修正するためには <code>lwsp</code><code>swsp</code> に含まれる即値のDecoderが呼ばれたときをフックし、
<code>sp</code> のオペランドが必要ならばこれを補えばよい<sup class="footnote">[<a id="_footnoteref_13" class="footnote" href="#_footnotedef_13" title="View footnote.">13</a>]</sup>
この関数を <code>addImplySP</code> という名前で実装する。ここで即値をオペランドに追加するために呼ぶ
<code>Inst.addOperand</code><code>addImplySP</code> の呼び出しの順序に注意が必要である。
すなわち <code>LWSP</code><code>CAHPInstrInfo.td</code> で定義したときのオペランドの順序で呼ばなければ
<code>lwsp x11, sp(0)</code> のようなおかしなアセンブリが生成されてしまう。</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>ちなみにエンコード方式にコンフリクトがある場合はビルド時に教えてくれる。</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Decoding Conflict:
111...........01
111.............
................
BNEZ 111___________01
BNEZhoge 111___________01</pre>
</div>
</div>
<div class="paragraph">
<p>これを防ぐためには、もちろん異なるエンコード方式を指定すればよいのだが、
他にディスアセンブル時に命令を無効化する方法としてTableGenファイルで
<code>isPseudo = 1</code> を指定して疑似命令にしたり
<code>isCodeGen = 1</code> を指定してコード生成時にのみ効力を持つ
命令にすることなどができる。</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_relocationとfixupに対応する">relocationとfixupに対応する</h3>
<div class="paragraph">
<p><a href="https://github.com/virtualsecureplatform/llvm-cahp/commit/a03e70e9157510937ca522f14ca0c64c61d47ca7">a03e70e9157510937ca522f14ca0c64c61d47ca7</a></p>
</div>
<div class="paragraph">
<p>ワンパスでは決められない値についてあとから補うための機構であるfixupと、
コンパイル時には決定できない値に対してリンカにその処理を任せるためのrelocationについて
対応する。参考にするパッチは<a href="#github_riscv-llvm_patch_11">[27]</a></p>
</div>
<div class="paragraph">
<p>必要な作業は大きく分けて次の通り。
* Fixupの種類とその内容を定義する。
* Fixupを適用する関数を定義する。
* アセンブラがFixupを生成するように改変する。
* Fixupが解決されないまま最後まで残る場合は、これをrelocationに変換する。</p>
</div>
</div>
<div class="sect2">
<h3 id="_hi_と_lo_に対応する"><code>%hi</code><code>%lo</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_li_a0_foo_をエラーにする"><code>li a0, foo</code> をエラーにする</h3>
</div>
<div class="sect2">
<h3 id="_llvm_objdump_の調査">llvm-objdump の調査</h3>
</div>
<div class="sect2">
<h3 id="_hlt_疑似命令を追加する"><code>hlt</code> 疑似命令を追加する</h3>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_コード生成部を作る">コード生成部を作る</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_コンパイラのスケルトンを作成する">コンパイラのスケルトンを作成する</h3>
</div>
<div class="sect2">
<h3 id="_基本的な演算に対応する">基本的な演算に対応する</h3>
</div>
<div class="sect2">
<h3 id="_定数の実体化に対応する">定数の実体化に対応する</h3>
</div>
<div class="sect2">
<h3 id="_メモリ演算に対応する">メモリ演算に対応する</h3>
</div>
<div class="sect2">
<h3 id="_relocationに対応する">relocationに対応する</h3>
</div>
<div class="sect2">
<h3 id="_条件分岐に対応する">条件分岐に対応する</h3>
</div>
<div class="sect2">
<h3 id="_関数呼び出しに対応する">関数呼び出しに対応する</h3>
</div>
<div class="sect2">
<h3 id="_関数プロローグエピローグを実装する">関数プロローグ・エピローグを実装する</h3>
</div>
<div class="sect2">
<h3 id="_frame_pointer_eliminationを実装する">frame pointer eliminationを実装する</h3>
</div>
<div class="sect2">
<h3 id="_select_に対応する"><code>select</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_frameindex_をlowerする"><code>FrameIndex</code> をlowerする。</h3>
</div>
<div class="sect2">
<h3 id="_大きなスタックフレームに対応する">大きなスタックフレームに対応する</h3>
</div>
<div class="sect2">
<h3 id="_setcc_に対応する"><code>SETCC</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_externalsymbol_に対応する"><code>ExternalSymbol</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_jump_tableを無効化する">jump tableを無効化する</h3>
</div>
<div class="sect2">
<h3 id="_インラインアセンブリに対応する">インラインアセンブリに対応する</h3>
</div>
<div class="sect2">
<h3 id="_fastccに対応する">fastccに対応する</h3>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_cコンパイラに仕立てる">Cコンパイラに仕立てる</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_lldにcahpバックエンドを追加する">LLDにCAHPバックエンドを追加する</h3>
</div>
<div class="sect2">
<h3 id="_clangをcahpに対応させる">ClangをCAHPに対応させる</h3>
</div>
<div class="sect2">
<h3 id="_crt0_o_と_cahp_lds_の導入"><code>crt0.o</code><code>cahp.lds</code> の導入</h3>
</div>
<div class="sect2">
<h3 id="_nmagic_の有効化"><code>--nmagic</code> の有効化</h3>
</div>
<div class="sect2">
<h3 id="_libcの有効化">libcの有効化</h3>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_まともなコードを生成する">まともなコードを生成する</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_分岐解析に対応する">分岐解析に対応する</h3>
</div>
<div class="sect2">
<h3 id="_branch_relaxationに対応する">branch relaxationに対応する</h3>
</div>
<div class="sect2">
<h3 id="_16bit命令を活用する">16bit命令を活用する</h3>
</div>
<div class="sect2">
<h3 id="_jal_を活用する"><code>jal</code> を活用する</h3>
</div>
<div class="sect2">
<h3 id="_命令スケジューリングを設定する">命令スケジューリングを設定する</h3>
</div>
<div class="sect2">
<h3 id="_末尾再帰に対応する">末尾再帰に対応する</h3>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_落ち穂拾い">落ち穂拾い</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_スタックを利用した引数渡し">スタックを利用した引数渡し</h3>
</div>
<div class="sect2">
<h3 id="_byval_の対応"><code>byval</code> の対応</h3>
</div>
<div class="sect2">
<h3 id="_動的なスタック領域確保に対応する">動的なスタック領域確保に対応する</h3>
</div>
<div class="sect2">
<h3 id="_emergency_spillに対応する">emergency spillに対応する</h3>
</div>
<div class="sect2">
<h3 id="_可変長引数関数に対応する">可変長引数関数に対応する</h3>
</div>
<div class="sect2">
<h3 id="_単体の_sextzexttrunc_に対応する">単体の <code>sext/zext/trunc</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_乗算に対応する">乗算に対応する</h3>
</div>
<div class="sect2">
<h3 id="_除算剰余に対応する">除算・剰余に対応する</h3>
</div>
<div class="sect2">
<h3 id="_frameaddrreturnaddr_に対応する"><code>frameaddr/returnaddr</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_rotlrotrbswapcttzctlzctpop_に対応する"><code>ROTL/ROTR/BSWAP/CTTZ/CTLZ/CTPOP</code> に対応する</h3>
</div>
<div class="sect2">
<h3 id="_32bitのシフトに対応する">32bitのシフトに対応する</h3>
</div>
<div class="sect2">
<h3 id="_間接ジャンプに対応する">間接ジャンプに対応する</h3>
</div>
<div class="sect2">
<h3 id="_blockaddress_のlowerに対応する"><code>BlockAddress</code> のlowerに対応する</h3>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_参考文献">参考文献</h2>
<div class="sectionbody">
<div class="ulist bibliography">
<ul class="bibliography">
<li>
<p><a id="github_riscv-llvm_docs_01"></a>[1] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/docs/01-intro-and-building-llvm.mkd" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/docs/01-intro-and-building-llvm.mkd</a></p>
</li>
<li>
<p><a id="llvm_getting-started"></a>[2] <a href="https://llvm.org/docs/GettingStarted.html" class="bare">https://llvm.org/docs/GettingStarted.html</a></p>
</li>
<li>
<p><a id="clang_gettings-started"></a>[3] <a href="https://clang.llvm.org/get_started.html" class="bare">https://clang.llvm.org/get_started.html</a></p>
</li>
<li>
<p><a id="asciidoctor_user-manual"></a>[4] <a href="https://asciidoctor.org/docs/user-manual/" class="bare">https://asciidoctor.org/docs/user-manual/</a></p>
</li>
<li>
<p><a id="riscv"></a>[5] <a href="https://riscv.org/" class="bare">https://riscv.org/</a></p>
</li>
<li>
<p><a id="riscv_specifications"></a>[6] <a href="https://riscv.org/specifications/" class="bare">https://riscv.org/specifications/</a></p>
</li>
<li>
<p><a id="fox-llvm"></a>[7] 『きつねさんでもわかるLLVM〜コンパイラを自作するためのガイドブック〜』柏木 餅子・風薬・矢上 栄一、株式会社インプレス、2013年</p>
</li>
<li>
<p><a id="github_riscv-llvm_docs_02"></a>[8] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/docs/02-starting-the-backend.mkd" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/docs/02-starting-the-backend.mkd</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_02"></a>[9] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0002-RISCV-Recognise-riscv32-and-riscv64-in-triple-parsin.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0002-RISCV-Recognise-riscv32-and-riscv64-in-triple-parsin.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm"></a>[10] <a href="https://github.com/lowRISC/riscv-llvm" class="bare">https://github.com/lowRISC/riscv-llvm</a></p>
</li>
<li>
<p><a id="youtube_llvm-backend-development-by-example"></a>[11] <a href="https://www.youtube.com/watch?v=AFaIP-dF-RA" class="bare">https://www.youtube.com/watch?v=AFaIP-dF-RA</a></p>
</li>
<li>
<p><a id="msyksphinz_try-riscv64-llvm-backend"></a>[12] <a href="http://msyksphinz.hatenablog.com/entry/2019/01/02/040000_1" class="bare">http://msyksphinz.hatenablog.com/entry/2019/01/02/040000_1</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_03"></a>[13] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0003-RISCV-Add-RISC-V-ELF-defines.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0003-RISCV-Add-RISC-V-ELF-defines.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_04"></a>[14] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0004-RISCV-Add-stub-backend.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0004-RISCV-Add-stub-backend.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_06"></a>[15] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0006-RISCV-Add-bare-bones-RISC-V-MCTargetDesc.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0006-RISCV-Add-bare-bones-RISC-V-MCTargetDesc.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_10"></a>[16] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0010-RISCV-Add-support-for-disassembly.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0010-RISCV-Add-support-for-disassembly.patch</a></p>
</li>
<li>
<p><a id="llvm-writing_backend-operand_mapping"></a>[17] <a href="https://llvm.org/docs/WritingAnLLVMBackend.html#instruction-operand-mapping" class="bare">https://llvm.org/docs/WritingAnLLVMBackend.html#instruction-operand-mapping</a></p>
</li>
<li>
<p><a id="llvm-writing_backend"></a>[18] <a href="https://llvm.org/docs/WritingAnLLVMBackend.html" class="bare">https://llvm.org/docs/WritingAnLLVMBackend.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_07"></a>[19] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0007-RISCV-Add-basic-RISCVAsmParser.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0007-RISCV-Add-basic-RISCVAsmParser.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_08"></a>[20] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0008-RISCV-Add-RISCVInstPrinter-and-basic-MC-assembler-te.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0008-RISCV-Add-RISCVInstPrinter-and-basic-MC-assembler-te.patch</a></p>
</li>
<li>
<p><a id="llvm-tablegen"></a>[21] <a href="https://llvm.org/docs/TableGen/index.html" class="bare">https://llvm.org/docs/TableGen/index.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_09"></a>[22] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0009-RISCV-Add-support-for-all-RV32I-instructions.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0009-RISCV-Add-support-for-all-RV32I-instructions.patch</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-tablegen_definition_question"></a>[23] <a href="http://lists.llvm.org/pipermail/llvm-dev/2015-December/093310.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2015-December/093310.html</a></p>
</li>
<li>
<p><a id="llvm_doxygen-twine"></a>[24] <a href="https://llvm.org/doxygen/classllvm_1_1Twine.html" class="bare">https://llvm.org/doxygen/classllvm_1_1Twine.html</a></p>
</li>
<li>
<p><a id="llvm-tablegen-langref"></a>[25] <a href="https://llvm.org/docs/TableGen/LangRef.html" class="bare">https://llvm.org/docs/TableGen/LangRef.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_docs_05"></a>[26] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/docs/05-disassembly.mkd" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/docs/05-disassembly.mkd</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_11"></a>[27] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0011-RISCV-Add-common-fixups-and-relocations.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0011-RISCV-Add-common-fixups-and-relocations.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_docs_06"></a>[28] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/docs/06-relocations-and-fixups.mkd" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/docs/06-relocations-and-fixups.mkd</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_13"></a>[29] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0013-RISCV-Initial-codegen-support-for-ALU-operations.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0013-RISCV-Initial-codegen-support-for-ALU-operations.patch</a></p>
</li>
<li>
<p><a id="speakerdeck-llvm_backend_development"></a>[30] <a href="https://speakerdeck.com/asb/llvm-backend-development-by-example-risc-v" class="bare">https://speakerdeck.com/asb/llvm-backend-development-by-example-risc-v</a></p>
</li>
<li>
<p><a id="llvm-code_generator"></a>[31] <a href="https://llvm.org/docs/CodeGenerator.html" class="bare">https://llvm.org/docs/CodeGenerator.html</a></p>
</li>
<li>
<p><a id="llvm-code_generator-target_independent_code_gen_alg"></a>[32] <a href="https://llvm.org/docs/CodeGenerator.html#target-independent-code-generation-algorithms" class="bare">https://llvm.org/docs/CodeGenerator.html#target-independent-code-generation-algorithms</a></p>
</li>
<li>
<p><a id="llvm-code_generator-selectiondag_instruction_selection"></a>[33] <a href="https://llvm.org/docs/CodeGenerator.html#selectiondag-instruction-selection-process" class="bare">https://llvm.org/docs/CodeGenerator.html#selectiondag-instruction-selection-process</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_15"></a>[34] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0015-RISCV-Codegen-support-for-memory-operations.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0015-RISCV-Codegen-support-for-memory-operations.patch</a></p>
</li>
<li>
<p><a id="cpu0"></a>[35] <a href="https://jonathan2251.github.io/lbd/" class="bare">https://jonathan2251.github.io/lbd/</a></p>
</li>
<li>
<p><a id="elvm-llvm_backend"></a>[36] <a href="https://github.com/shinh/llvm/tree/elvm" class="bare">https://github.com/shinh/llvm/tree/elvm</a></p>
</li>
<li>
<p><a id="elvm-slide"></a>[37] <a href="http://shinh.skr.jp/slide/llel/000.html" class="bare">http://shinh.skr.jp/slide/llel/000.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_16"></a>[38] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0016-RISCV-Codegen-support-for-memory-operations-on-globa.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0016-RISCV-Codegen-support-for-memory-operations-on-globa.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_17"></a>[39] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0017-RISCV-Codegen-for-conditional-branches.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0017-RISCV-Codegen-for-conditional-branches.patch</a></p>
</li>
<li>
<p><a id="todai_llvm_backend"></a>[40] <a href="https://github.com/cpu-experiment-2018-2/llvm/tree/master/lib/Target/ELMO" class="bare">https://github.com/cpu-experiment-2018-2/llvm/tree/master/lib/Target/ELMO</a></p>
</li>
<li>
<p><a id="todai_llvm_backend-article"></a>[41] <a href="http://uenoku.hatenablog.com/entry/2018/12/25/044244" class="bare">http://uenoku.hatenablog.com/entry/2018/12/25/044244</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_18"></a>[42] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0018-RISCV-Support-for-function-calls.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0018-RISCV-Support-for-function-calls.patch</a></p>
</li>
<li>
<p><a id="llvm-langref"></a>[43] <a href="http://llvm.org/docs/LangRef.html" class="bare">http://llvm.org/docs/LangRef.html</a></p>
</li>
<li>
<p><a id="fpga_develop_diary"></a>[44] <a href="http://msyksphinz.hatenablog.com/" class="bare">http://msyksphinz.hatenablog.com/</a></p>
</li>
<li>
<p><a id="llvm-anton_korobeynikov_2012"></a>[45] <a href="https://llvm.org/devmtg/2012-04-12/Slides/Workshops/Anton_Korobeynikov.pdf" class="bare">https://llvm.org/devmtg/2012-04-12/Slides/Workshops/Anton_Korobeynikov.pdf</a></p>
</li>
<li>
<p><a id="llvm-welcome_to_the_back_end_2017"></a>[46] <a href="https://www.youtube.com/watch?v=objxlZg01D0" class="bare">https://www.youtube.com/watch?v=objxlZg01D0</a></p>
</li>
<li>
<p><a id="ean10-howto-llvmas"></a>[47] <a href="https://www.embecosm.com/appnotes/ean10/ean10-howto-llvmas-1.0.html" class="bare">https://www.embecosm.com/appnotes/ean10/ean10-howto-llvmas-1.0.html</a></p>
</li>
<li>
<p><a id="lowrisc-devmtg18"></a>[48] <a href="https://www.lowrisc.org/llvm/devmtg18/" class="bare">https://www.lowrisc.org/llvm/devmtg18/</a></p>
</li>
<li>
<p><a id="LLVMBackend_2015_03_26_v2"></a>[49] <a href="http://www.inf.ed.ac.uk/teaching/courses/ct/other/LLVMBackend-2015-03-26_v2.pdf" class="bare">http://www.inf.ed.ac.uk/teaching/courses/ct/other/LLVMBackend-2015-03-26_v2.pdf</a></p>
</li>
<li>
<p><a id="rui-compilerbook"></a>[50] <a href="https://www.sigbus.info/compilerbook" class="bare">https://www.sigbus.info/compilerbook</a></p>
</li>
<li>
<p><a id="krister-writing_gcc_backend"></a>[51] <a href="https://kristerw.blogspot.com/2017/08/writing-gcc-backend_4.html" class="bare">https://kristerw.blogspot.com/2017/08/writing-gcc-backend_4.html</a></p>
</li>
<li>
<p><a id="llvm-ml-129089"></a>[52] <a href="http://lists.llvm.org/pipermail/llvm-dev/2019-January/129089.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2019-January/129089.html</a></p>
</li>
<li>
<p><a id="llvm-langref-datalayout"></a>[53] <a href="https://llvm.org/docs/LangRef.html#langref-datalayout" class="bare">https://llvm.org/docs/LangRef.html#langref-datalayout</a></p>
</li>
<li>
<p><a id="github-frasercrmck_llvm_leg"></a>[54] <a href="https://github.com/frasercrmck/llvm-leg/tree/master/lib/Target/LEG" class="bare">https://github.com/frasercrmck/llvm-leg/tree/master/lib/Target/LEG</a></p>
</li>
<li>
<p><a id="llvm_doxygen-InitMCRegisterInfo"></a>[55] <a href="https://llvm.org/doxygen/classllvm_1_1MCRegisterInfo.html#a989859615fcb74989b4f978c4d227a03" class="bare">https://llvm.org/doxygen/classllvm_1_1MCRegisterInfo.html#a989859615fcb74989b4f978c4d227a03</a></p>
</li>
<li>
<p><a id="llvm-programmers_manual"></a>[56] <a href="http://llvm.org/docs/ProgrammersManual.html" class="bare">http://llvm.org/docs/ProgrammersManual.html</a></p>
</li>
<li>
<p><a id="llvm-writing_backend-calling_conventions"></a>[57] <a href="https://llvm.org/docs/WritingAnLLVMBackend.html#calling-conventions" class="bare">https://llvm.org/docs/WritingAnLLVMBackend.html#calling-conventions</a></p>
</li>
<li>
<p><a id="riscv-calling"></a>[58] <a href="https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf" class="bare">https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-how_to_debug_instruction_selection"></a>[59] <a href="http://lists.llvm.org/pipermail/llvm-dev/2017-August/116501.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2017-August/116501.html</a></p>
</li>
<li>
<p><a id="fpga_develop_diary-20190612040000"></a>[60] <a href="http://msyksphinz.hatenablog.com/entry/2019/06/12/040000" class="bare">http://msyksphinz.hatenablog.com/entry/2019/06/12/040000</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-br_cc_questions"></a>[61] <a href="http://lists.llvm.org/pipermail/llvm-dev/2014-August/075303.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2014-August/075303.html</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-multiple_result_instrs"></a>[62] <a href="https://groups.google.com/forum/#!topic/llvm-dev/8kPOj-_lbGk" class="bare">https://groups.google.com/forum/#!topic/llvm-dev/8kPOj-_lbGk</a></p>
</li>
<li>
<p><a id="stackoverflow-frame_lowering"></a>[63] <a href="https://stackoverflow.com/questions/32872946/what-is-stack-frame-lowering-in-llvm" class="bare">https://stackoverflow.com/questions/32872946/what-is-stack-frame-lowering-in-llvm</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-selecting_frame_index"></a>[64] <a href="https://groups.google.com/d/msg/llvm-dev/QXwtqgau-jA/PwnHDF0gG_oJ" class="bare">https://groups.google.com/d/msg/llvm-dev/QXwtqgau-jA/PwnHDF0gG_oJ</a></p>
</li>
<li>
<p><a id="fpga_develop_diary-llvm"></a>[65] <a href="https://github.com/msyksphinz/llvm/tree/myriscvx/impl90/lib/Target/MYRISCVX" class="bare">https://github.com/msyksphinz/llvm/tree/myriscvx/impl90/lib/Target/MYRISCVX</a></p>
</li>
<li>
<p><a id="llvm-github_cd44ae"></a>[66] <a href="https://github.com/llvm/llvm-project/commit/cd44aee3da22f9a618f2e63c226bebf615fa8cf8" class="bare">https://github.com/llvm/llvm-project/commit/cd44aee3da22f9a618f2e63c226bebf615fa8cf8</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d43752"></a>[67] <a href="https://reviews.llvm.org/D43752" class="bare">https://reviews.llvm.org/D43752</a></p>
</li>
<li>
<p><a id="llvm-compilerwriterinfo"></a>[68] <a href="https://llvm.org/docs/CompilerWriterInfo.html" class="bare">https://llvm.org/docs/CompilerWriterInfo.html</a></p>
</li>
<li>
<p><a id="wikipedia-The_Gleaners"></a>[69] <a href="https://en.wikipedia.org/wiki/The_Gleaners" class="bare">https://en.wikipedia.org/wiki/The_Gleaners</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_20"></a>[70] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0020-RISCV-Support-and-tests-for-a-variety-of-additional-.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0020-RISCV-Support-and-tests-for-a-variety-of-additional-.patch</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d47422"></a>[71] <a href="https://reviews.llvm.org/D47422" class="bare">https://reviews.llvm.org/D47422</a></p>
</li>
<li>
<p><a id="llvm-extendingllvm"></a>[72] <a href="https://llvm.org/docs/ExtendingLLVM.html" class="bare">https://llvm.org/docs/ExtendingLLVM.html</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-001264"></a>[73] <a href="http://lists.llvm.org/pipermail/llvm-dev/2004-June/001264.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2004-June/001264.html</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d42958"></a>[74] <a href="https://reviews.llvm.org/D42958" class="bare">https://reviews.llvm.org/D42958</a></p>
</li>
<li>
<p><a id="compiler_rt"></a>[75] <a href="https://compiler-rt.llvm.org/" class="bare">https://compiler-rt.llvm.org/</a></p>
</li>
<li>
<p><a id="github-riscv_compiler_rt"></a>[76] <a href="https://github.com/andestech/riscv-compiler-rt" class="bare">https://github.com/andestech/riscv-compiler-rt</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_27"></a>[77] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0027-RISCV-Support-stack-frames-and-offsets-up-to-32-bits.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0027-RISCV-Support-stack-frames-and-offsets-up-to-32-bits.patch</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d44885"></a>[78] <a href="https://reviews.llvm.org/D44885" class="bare">https://reviews.llvm.org/D44885</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d45859"></a>[79] <a href="https://reviews.llvm.org/D45859" class="bare">https://reviews.llvm.org/D45859</a></p>
</li>
<li>
<p><a id="llvm-langref-poison_value"></a>[80] <a href="http://llvm.org/docs/LangRef.html#poisonvalues" class="bare">http://llvm.org/docs/LangRef.html#poisonvalues</a></p>
</li>
<li>
<p><a id="github-emscripten-issues-34"></a>[81] <a href="https://github.com/emscripten-core/emscripten/issues/34" class="bare">https://github.com/emscripten-core/emscripten/issues/34</a></p>
</li>
<li>
<p><a id="switch_lowering_in_llvm"></a>[82] <a href="http://fileadmin.cs.lth.se/cs/education/edan75/part2.pdf" class="bare">http://fileadmin.cs.lth.se/cs/education/edan75/part2.pdf</a></p>
</li>
<li>
<p><a id="github-avr_llvm-issues-88"></a>[83] <a href="https://github.com/avr-llvm/llvm/issues/88" class="bare">https://github.com/avr-llvm/llvm/issues/88</a></p>
</li>
<li>
<p><a id="asciidoctor-quickref"></a>[84] <a href="https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/" class="bare">https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d56351"></a>[85] <a href="https://reviews.llvm.org/D56351" class="bare">https://reviews.llvm.org/D56351</a></p>
</li>
<li>
<p><a id="hatenablog-rhysd-230119"></a>[86] <a href="https://rhysd.hatenablog.com/entry/2017/03/13/230119" class="bare">https://rhysd.hatenablog.com/entry/2017/03/13/230119</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-115805"></a>[87] <a href="http://lists.llvm.org/pipermail/llvm-dev/2017-July/115805.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2017-July/115805.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_29"></a>[88] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0029-RISCV-Add-support-for-llvm.-frameaddress-returnaddre.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0029-RISCV-Add-support-for-llvm.-frameaddress-returnaddre.patch</a></p>
</li>
<li>
<p><a id="github-riscv_llvm-clang"></a>[89] <a href="https://github.com/lowRISC/riscv-llvm/tree/master/clang" class="bare">https://github.com/lowRISC/riscv-llvm/tree/master/clang</a></p>
</li>
<li>
<p><a id="github-elvm_clang"></a>[90] <a href="https://github.com/shinh/clang/tree/elvm" class="bare">https://github.com/shinh/clang/tree/elvm</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_22"></a>[91] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0022-RISCV-Support-lowering-FrameIndex.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0022-RISCV-Support-lowering-FrameIndex.patch</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-087879"></a>[92] <a href="http://lists.llvm.org/pipermail/llvm-dev/2015-July/087879.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2015-July/087879.html</a></p>
</li>
<li>
<p><a id="stackoverflow-27467293"></a>[93] <a href="https://stackoverflow.com/questions/27467293/how-to-force-clang-use-llvm-assembler-instead-of-system" class="bare">https://stackoverflow.com/questions/27467293/how-to-force-clang-use-llvm-assembler-instead-of-system</a></p>
</li>
<li>
<p><a id="github-riscv_llvm-clang-03"></a>[94] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/clang/0003-RISCV-Implement-clang-driver-for-the-baremetal-RISCV.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/clang/0003-RISCV-Implement-clang-driver-for-the-baremetal-RISCV.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_25"></a>[95] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0025-RISCV-Add-custom-CC_RISCV-calling-convention-and-imp.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0025-RISCV-Add-custom-CC_RISCV-calling-convention-and-imp.patch</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-106187"></a>[96] <a href="http://lists.llvm.org/pipermail/llvm-dev/2016-October/106187.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2016-October/106187.html</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d39322"></a>[97] <a href="https://reviews.llvm.org/D39322" class="bare">https://reviews.llvm.org/D39322</a></p>
</li>
<li>
<p><a id="cpu0-lld"></a>[98] <a href="http://jonathan2251.github.io/lbt/lld.html" class="bare">http://jonathan2251.github.io/lbt/lld.html</a></p>
</li>
<li>
<p><a id="youtube-how_to_add_a_new_target_to_lld"></a>[99] <a href="https://www.youtube.com/watch?v=FIXaeRU31Ww" class="bare">https://www.youtube.com/watch?v=FIXaeRU31Ww</a></p>
</li>
<li>
<p><a id="llvm-smith_newlldtargetpdf"></a>[100] <a href="https://llvm.org/devmtg/2016-09/slides/Smith-NewLLDTarget.pdf" class="bare">https://llvm.org/devmtg/2016-09/slides/Smith-NewLLDTarget.pdf</a></p>
</li>
<li>
<p><a id="llvm-lld"></a>[101] <a href="https://lld.llvm.org/index.html" class="bare">https://lld.llvm.org/index.html</a></p>
</li>
<li>
<p><a id="note-n9948f0cc3ed3"></a>[102] <a href="https://note.mu/ruiu/n/n9948f0cc3ed3" class="bare">https://note.mu/ruiu/n/n9948f0cc3ed3</a></p>
</li>
<li>
<p><a id="lanai-isa"></a>[103] <a href="https://docs.google.com/document/d/1jwAc-Rbw1Mn7Dbn2oEB3-0FQNOwqNPslZa-NDy8wGRo/pub" class="bare">https://docs.google.com/document/d/1jwAc-Rbw1Mn7Dbn2oEB3-0FQNOwqNPslZa-NDy8wGRo/pub</a></p>
</li>
<li>
<p><a id="github-blog_os-issues-370"></a>[104] <a href="https://github.com/phil-opp/blog_os/issues/370" class="bare">https://github.com/phil-opp/blog_os/issues/370</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d61688"></a>[105] <a href="https://reviews.llvm.org/D61688" class="bare">https://reviews.llvm.org/D61688</a></p>
</li>
<li>
<p><a id="man-xtensa_linux_gnu_ld"></a>[106] <a href="https://linux.die.net/man/1/xtensa-linux-gnu-ld" class="bare">https://linux.die.net/man/1/xtensa-linux-gnu-ld</a></p>
</li>
<li>
<p><a id="man-elf"></a>[107] <a href="https://linuxjm.osdn.jp/html/LDP_man-pages/man5/elf.5.html" class="bare">https://linuxjm.osdn.jp/html/LDP_man-pages/man5/elf.5.html</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d45385"></a>[108] <a href="https://reviews.llvm.org/D45385" class="bare">https://reviews.llvm.org/D45385</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d47882"></a>[109] <a href="https://reviews.llvm.org/D47882" class="bare">https://reviews.llvm.org/D47882</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-128257"></a>[110] <a href="https://lists.llvm.org/pipermail/llvm-dev/2018-December/128257.html" class="bare">https://lists.llvm.org/pipermail/llvm-dev/2018-December/128257.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_31"></a>[111] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0031-RISCV-Implement-support-for-the-BranchRelaxation-pas.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0031-RISCV-Implement-support-for-the-BranchRelaxation-pas.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_30"></a>[112] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0030-RISCV-Implement-branch-analysis.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0030-RISCV-Implement-branch-analysis.patch</a></p>
</li>
<li>
<p><a id="stackoverflow-5789806"></a>[113] <a href="https://stackoverflow.com/questions/5789806/meaning-of-and-in-c" class="bare">https://stackoverflow.com/questions/5789806/meaning-of-and-in-c</a></p>
</li>
<li>
<p><a id="compiler_study_report"></a>[114] <a href="https://proc-cpuinfo.fixstars.com/2018/11/compiler_study_report/" class="bare">https://proc-cpuinfo.fixstars.com/2018/11/compiler_study_report/</a></p>
</li>
<li>
<p><a id="github-llvm-bcb36be8e3f5dced36710ba1a2e2206071ccc7ba"></a>[115] <a href="https://github.com/llvm/llvm-project/commit/bcb36be8e3f5dced36710ba1a2e2206071ccc7ba" class="bare">https://github.com/llvm/llvm-project/commit/bcb36be8e3f5dced36710ba1a2e2206071ccc7ba</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-059799"></a>[116] <a href="http://lists.llvm.org/pipermail/llvm-dev/2013-February/059799.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2013-February/059799.html</a></p>
</li>
<li>
<p><a id="tricore-llvm-slides"></a>[117] <a href="https://reup.dmcs.pl/wiki/images/7/7a/Tricore-llvm-slides.pdf" class="bare">https://reup.dmcs.pl/wiki/images/7/7a/Tricore-llvm-slides.pdf</a></p>
</li>
<li>
<p><a id="tricore-llvm"></a>[118] <a href="https://opus4.kobv.de/opus4-fau/files/1108/tricore_llvm.pdf" class="bare">https://opus4.kobv.de/opus4-fau/files/1108/tricore_llvm.pdf</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-111697"></a>[119] <a href="http://lists.llvm.org/pipermail/llvm-dev/2017-April/111697.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2017-April/111697.html</a></p>
</li>
<li>
<p><a id="takayuki-no09"></a>[120] <a href="http://www.ertl.jp/~takayuki/readings/c/no09.html" class="bare">http://www.ertl.jp/~takayuki/readings/c/no09.html</a></p>
</li>
<li>
<p><a id="hwenginner-linker"></a>[121] <a href="https://hwengineer.github.io/linker/" class="bare">https://hwengineer.github.io/linker/</a></p>
</li>
<li>
<p><a id="koikikukan-000300"></a>[122] <a href="http://www.koikikukan.com/archives/2017/04/05-000300.php" class="bare">http://www.koikikukan.com/archives/2017/04/05-000300.php</a></p>
</li>
<li>
<p><a id="stackoverflow-57735654_34997577"></a>[123] <a href="https://stackoverflow.com/questions/34997577/linker-script-allocation-of-bss-section#comment57735654_34997577" class="bare">https://stackoverflow.com/questions/34997577/linker-script-allocation-of-bss-section#comment57735654_34997577</a></p>
</li>
<li>
<p><a id="redhat-ld_simple_example"></a>[124] <a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/simple-example.html" class="bare">https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/simple-example.html</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d45395"></a>[125] <a href="https://reviews.llvm.org/D45395" class="bare">https://reviews.llvm.org/D45395</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d45395-398662"></a>[126] <a href="https://reviews.llvm.org/D45395#inline-398662" class="bare">https://reviews.llvm.org/D45395#inline-398662</a></p>
</li>
<li>
<p><a id="llvm-langref-inline_asm"></a>[127] <a href="http://llvm.org/docs/LangRef.html#inline-assembler-expressions" class="bare">http://llvm.org/docs/LangRef.html#inline-assembler-expressions</a></p>
</li>
<li>
<p><a id="hazymoon-gcc_inline_asm"></a>[128] <a href="http://caspar.hazymoon.jp/OpenBSD/annex/gcc_inline_asm.html" class="bare">http://caspar.hazymoon.jp/OpenBSD/annex/gcc_inline_asm.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_28"></a>[129] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0028-RISCV-Add-basic-support-for-inline-asm-constraints.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0028-RISCV-Add-basic-support-for-inline-asm-constraints.patch</a></p>
</li>
<li>
<p><a id="llvm-langref-inline_asm-asm_template_argument_modifier"></a>[130] <a href="http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers" class="bare">http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers</a></p>
</li>
<li>
<p><a id="github-llvm-0715d35ed5ac2312951976bee2a0d2587f98f39f"></a>[131] <a href="https://github.com/llvm/llvm-project/commit/0715d35ed5ac2312951976bee2a0d2587f98f39f" class="bare">https://github.com/llvm/llvm-project/commit/0715d35ed5ac2312951976bee2a0d2587f98f39f</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_32"></a>[132] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0032-RISCV-Reserve-an-emergency-spill-slot-for-the-regist.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0032-RISCV-Reserve-an-emergency-spill-slot-for-the-regist.patch</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_26"></a>[133] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0026-RISCV-Support-for-varargs.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0026-RISCV-Support-for-varargs.patch</a></p>
</li>
<li>
<p><a id="github-fracture-wiki-how-dagisel-works"></a>[134] <a href="https://github.com/draperlaboratory/fracture/wiki/How-TableGen%27s-DAGISel-Backend-Works" class="bare">https://github.com/draperlaboratory/fracture/wiki/How-TableGen%27s-DAGISel-Backend-Works</a></p>
</li>
<li>
<p><a id="welcome_to_the_back_end-slides"></a>[135] <a href="http://llvm.org/devmtg/2017-10/slides/Braun-Welcome%20to%20the%20Back%20End.pdf" class="bare">http://llvm.org/devmtg/2017-10/slides/Braun-Welcome%20to%20the%20Back%20End.pdf</a></p>
</li>
<li>
<p><a id="life_of_an_instruction"></a>[136] <a href="https://eli.thegreenplace.net/2012/11/24/life-of-an-instruction-in-llvm/" class="bare">https://eli.thegreenplace.net/2012/11/24/life-of-an-instruction-in-llvm/</a></p>
</li>
<li>
<p><a id="shinh-blog-010637"></a>[137] <a href="http://shinh.hatenablog.com/entry/2014/10/03/010637" class="bare">http://shinh.hatenablog.com/entry/2014/10/03/010637</a></p>
</li>
<li>
<p><a id="llvm_backend_intro"></a>[138] <a href="https://www.slideshare.net/AkiraMaruoka/llvm-backend" class="bare">https://www.slideshare.net/AkiraMaruoka/llvm-backend</a></p>
</li>
<li>
<p><a id="amazon-llvm_cookbook-customer_review"></a>[139] <a href="https://www.amazon.co.jp/dp/178528598X#customer_review-R28L2NAL8T9M2H" class="bare">https://www.amazon.co.jp/dp/178528598X#customer_review-R28L2NAL8T9M2H</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-117139"></a>[140] <a href="https://lists.llvm.org/pipermail/llvm-dev/2017-September/117139.html" class="bare">https://lists.llvm.org/pipermail/llvm-dev/2017-September/117139.html</a></p>
</li>
<li>
<p><a id="github_riscv-llvm_patch_85"></a>[141] <a href="https://github.com/lowRISC/riscv-llvm/blob/master/0085-RISCV-Set-AllowRegisterRenaming-1.patch" class="bare">https://github.com/lowRISC/riscv-llvm/blob/master/0085-RISCV-Set-AllowRegisterRenaming-1.patch</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-135337"></a>[142] <a href="https://lists.llvm.org/pipermail/llvm-dev/2019-September/135337.html" class="bare">https://lists.llvm.org/pipermail/llvm-dev/2019-September/135337.html</a></p>
</li>
<li>
<p><a id="wikipedia-weak_symbol"></a>[143] <a href="https://en.wikipedia.org/wiki/Weak_symbol" class="bare">https://en.wikipedia.org/wiki/Weak_symbol</a></p>
</li>
<li>
<p><a id="wikipedia-remat"></a>[144] <a href="https://en.wikipedia.org/wiki/Rematerialization" class="bare">https://en.wikipedia.org/wiki/Rematerialization</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d46182"></a>[145] <a href="https://reviews.llvm.org/D46182" class="bare">https://reviews.llvm.org/D46182</a></p>
</li>
<li>
<p><a id="nakata-compiler"></a>[146] 『コンパイラの構成と最適化第2版中田育男、朝倉書店、2009</p>
</li>
<li>
<p><a id="fpga_develop_diary-to_llvm9"></a>[147] <a href="http://msyksphinz.hatenablog.com/entry/2019/08/17/040000" class="bare">http://msyksphinz.hatenablog.com/entry/2019/08/17/040000</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d60488"></a>[148] <a href="https://reviews.llvm.org/D60488" class="bare">https://reviews.llvm.org/D60488</a></p>
</li>
<li>
<p><a id="llvm_phabricator-rl364191"></a>[149] <a href="https://reviews.llvm.org/rL364191" class="bare">https://reviews.llvm.org/rL364191</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d64121"></a>[150] <a href="https://reviews.llvm.org/D64121" class="bare">https://reviews.llvm.org/D64121</a></p>
</li>
<li>
<p><a id="llvm-codingstandards"></a>[151] <a href="https://llvm.org/docs/CodingStandards.html" class="bare">https://llvm.org/docs/CodingStandards.html</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-134921"></a>[152] <a href="https://lists.llvm.org/pipermail/llvm-dev/2019-September/134921.html" class="bare">https://lists.llvm.org/pipermail/llvm-dev/2019-September/134921.html</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d43256"></a>[153] <a href="https://reviews.llvm.org/D43256" class="bare">https://reviews.llvm.org/D43256</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-114675"></a>[154] <a href="http://lists.llvm.org/pipermail/llvm-dev/2017-June/114675.html" class="bare">http://lists.llvm.org/pipermail/llvm-dev/2017-June/114675.html</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d42780"></a>[155] <a href="https://reviews.llvm.org/D42780" class="bare">https://reviews.llvm.org/D42780</a></p>
</li>
<li>
<p><a id="llvm_phabricator-d51732"></a>[156] <a href="https://reviews.llvm.org/D51732" class="bare">https://reviews.llvm.org/D51732</a></p>
</li>
<li>
<p><a id="llvm_devmtg-schedmachinemodel"></a>[157] <a href="http://llvm.org/devmtg/2014-10/Slides/Estes-MISchedulerTutorial.pdf" class="bare">http://llvm.org/devmtg/2014-10/Slides/Estes-MISchedulerTutorial.pdf</a></p>
</li>
<li>
<p><a id="llvm_dev_ml-098535"></a>[158] <a href="https://lists.llvm.org/pipermail/llvm-dev/2016-April/098535.html" class="bare">https://lists.llvm.org/pipermail/llvm-dev/2016-April/098535.html</a></p>
</li>
<li>
<p><a id="llvm_devmtg-writinggreatsched"></a>[159] <a href="https://www.youtube.com/watch?v=brpomKUynEA" class="bare">https://www.youtube.com/watch?v=brpomKUynEA</a></p>
</li>
<li>
<p><a id="anandtech-11441"></a>[160] <a href="https://www.anandtech.com/show/11441/dynamiq-and-arms-new-cpus-cortex-a75-a55/4" class="bare">https://www.anandtech.com/show/11441/dynamiq-and-arms-new-cpus-cortex-a75-a55/4</a></p>
</li>
<li>
<p><a id="llvm_devmtg-larintrick"></a>[161] <a href="https://llvm.org/devmtg/2012-11/Larin-Trick-Scheduling.pdf" class="bare">https://llvm.org/devmtg/2012-11/Larin-Trick-Scheduling.pdf</a></p>
</li>
<li>
<p><a id="llvm-schedinorder"></a>[162] <a href="https://llvm.org/devmtg/2016-09/slides/Absar-SchedulingInOrder.pdf" class="bare">https://llvm.org/devmtg/2016-09/slides/Absar-SchedulingInOrder.pdf</a></p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnotedef_1">
<a href="#_footnoteref_1">1</a>. この 段落はクリエイティブ・コモンズより引用。
</div>
<div class="footnote" id="_footnotedef_2">
<a href="#_footnoteref_2">2</a>. 論文とスライドも怪しいものだが、著者が一致しているので多分正しいだろう。
</div>
<div class="footnote" id="_footnotedef_3">
<a href="#_footnoteref_3">3</a>. これとは別の発表で「コンパイラ開発してない人生はFAKE」という名言が飛び出した勉強会<a href="#compiler_study_report">[114]</a>
</div>
<div class="footnote" id="_footnotedef_4">
<a href="#_footnoteref_4">4</a>. LLVMバックエンドの開発を円滑にするためのアーキテクチャなのではと思うほどに分かりやすい。
</div>
<div class="footnote" id="_footnotedef_5">
<a href="#_footnoteref_5">5</a>. 後のSparcについて<a href="#llvm_dev_ml-059799">[116]</a> にて指摘されているように、商業的に成功しなかったバックエンドほどコードが単純で分かりやすい。
</div>
<div class="footnote" id="_footnotedef_6">
<a href="#_footnoteref_6">6</a>. 一方でx86など 複雑なエンコーディングを行うISAの場合は <code>Inst</code> フィールドを使用せず、 自前で変換を行っている。
</div>
<div class="footnote" id="_footnotedef_7">
<a href="#_footnoteref_7">7</a>. 内部で <code>llvm::MCRegisterInfo::InitMCRegisterInfo</code> <a href="#llvm_doxygen-InitMCRegisterInfo">[55]</a> を呼び出していることからわかります。
</div>
<div class="footnote" id="_footnotedef_8">
<a href="#_footnoteref_8">8</a>. CAHPマシンの仕様などはこの世に存在しないので、 これらは勝手に決めたものです。
</div>
<div class="footnote" id="_footnotedef_9">
<a href="#_footnoteref_9">9</a>. 失敗した場合は assertなどで異常終了し、スタックトレースなどが表示されます。
</div>
<div class="footnote" id="_footnotedef_10">
<a href="#_footnoteref_10">10</a>. なお以下では しばらくの間、命令を表す <code>add</code> などの文字列そのものも「オペランド」として扱います。
</div>
<div class="footnote" id="_footnotedef_11">
<a href="#_footnoteref_11">11</a>. なおラベルなどの識別子がオペランドに来るアセンブリには まだ対応していませんが、後ほど対応する際にはトークンではなく 即値として対応することになります。
</div>
<div class="footnote" id="_footnotedef_12">
<a href="#_footnoteref_12">12</a>. この場合 <code>AltNames</code> が指定されていないレジスタ(条件分岐のためのフラグなど)があるとエラーとなります。 アセンブリ中に表示され得ないレジスタにもダミーの名前をつける必要があります。
</div>
<div class="footnote" id="_footnotedef_13">
<a href="#_footnoteref_13">13</a>. この実装手法はRISC Vのそれによる。かなりad-hocだと感じるが、他の方法が分からないのでとりあえず真似る。
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2020-04-01 08:00:26 UTC
</div>
</div>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
messageStyle: "none",
tex2jax: {
inlineMath: [["\\(", "\\)"]],
displayMath: [["\\[", "\\]"]],
ignoreClass: "nostem|nolatexmath"
},
asciimath2jax: {
delimiters: [["\\$", "\\$"]],
ignoreClass: "nostem|noasciimath"
},
TeX: { equationNumbers: { autoNumber: "none" } }
})
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains("stemblock")) {
data.math.root.display = "block"
}
return data
})
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>
</body>
</html>