Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
74a1e417
wa
项目概览
wa-lang
/
wa
大约 1 年 前同步成功
通知
68
Star
655
Fork
45
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
wa
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
74a1e417
编写于
11月 22, 2022
作者:
B
Ben Shi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
llvm: support building WA source file to an Arduino project
上级
9ea8f464
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
122 addition
and
4 deletion
+122
-4
_examples/llvm/arduino_blink.wa
_examples/llvm/arduino_blink.wa
+30
-0
internal/app/app.wa.go
internal/app/app.wa.go
+35
-0
internal/backends/compiler_llvm/compile.go
internal/backends/compiler_llvm/compile.go
+15
-1
internal/backends/compiler_llvm/compile_function.go
internal/backends/compiler_llvm/compile_function.go
+20
-3
internal/backends/compiler_llvm/utils.go
internal/backends/compiler_llvm/utils.go
+22
-0
未找到文件。
_examples/llvm/arduino_blink.wa
0 → 100644
浏览文件 @
74a1e417
# Test the llvm backend.
# Make Arduino's builtin LED blinking.
# `wa native --target=avr arduino_blink.wa`
#wa:linkname __avr_write_port__
fn write_port(p i16, v i8)
# Delay a period of time
var cnt i8
fn delay(n i32) {
for i := i32(0); i < n; i++ {
cnt++
}
}
fn main() {
# Set Pin #5 (connected with the builtin LED) of Port B to output mode.
write_port(0x24, 0x20)
for b := 0; ; b++ {
if (b % 2) == 0 {
# Turn on the LED.
write_port(0x25, 0x20)
} else {
# Turn off the LED.
write_port(0x25, 0x00)
}
# Delay a period of time
delay(99999)
}
}
internal/app/app.wa.go
浏览文件 @
74a1e417
...
...
@@ -331,6 +331,12 @@ func (p *App) LLVM(infile string, outfile string, target string, debug bool) err
if
target
!=
""
{
llc
=
append
(
llc
,
"-mtriple"
,
target
)
}
// Add target specific options.
switch
target
{
case
"avr"
:
llc
=
append
(
llc
,
"-mcpu=atmega328"
)
default
:
}
cmd0
:=
exec
.
Command
(
p
.
opt
.
Llc
,
llc
...
)
cmd0
.
Stderr
=
os
.
Stderr
if
err
:=
cmd0
.
Run
();
err
!=
nil
{
...
...
@@ -338,6 +344,35 @@ func (p *App) LLVM(infile string, outfile string, target string, debug bool) err
return
err
}
// TODO: This is a temporary solution for AVR-Arduino. We generate
// an Arduino project instead of an ELF.
if
target
==
"avr"
{
// Create a new directory for the output Arduino project.
ext
,
outdir
:=
path
.
Ext
(
outfile
),
""
if
len
(
ext
)
>
0
{
pos
:=
strings
.
Index
(
outfile
,
ext
)
outdir
=
outfile
[
0
:
pos
]
}
if
err
:=
os
.
RemoveAll
(
outdir
);
err
!=
nil
{
return
err
}
if
err
:=
os
.
Mkdir
(
outdir
,
0755
);
err
!=
nil
{
return
err
}
// Move the assembly file to the project directory.
newAsmFile
:=
strings
.
ReplaceAll
(
asmfile
,
".s"
,
".S"
)
if
err
:=
os
.
Rename
(
asmfile
,
path
.
Join
(
outdir
,
newAsmFile
));
err
!=
nil
{
return
err
}
// Create the project main '.ino' file.
inoFile
:=
path
.
Join
(
outdir
,
path
.
Base
(
outdir
)
+
".ino"
)
inoStr
:=
"void setup(void) {}
\n
extern
\"
C
\"
{ extern void wa_main(void); }
\n
void loop(void) { wa_main(); }
\n
"
if
err
:=
os
.
WriteFile
(
inoFile
,
[]
byte
(
inoStr
),
0644
);
err
!=
nil
{
return
err
}
return
nil
}
// Invoke command `clang xxx.s -o outfile --target=xxx`.
clangArgs
:=
[]
string
{
asmfile
,
"-static"
,
"-o"
,
outfile
}
if
target
!=
""
{
...
...
internal/backends/compiler_llvm/compile.go
浏览文件 @
74a1e417
...
...
@@ -56,7 +56,7 @@ func (p *Compiler) Compile(prog *loader.Program) (output string, err error) {
}
// Emit some auxiliary functions.
p
.
output
.
WriteString
(
"define void @main() {
\n
"
)
p
.
output
.
WriteString
(
"define void @
wa_
main() {
\n
"
)
p
.
output
.
WriteString
(
" call void @"
)
p
.
output
.
WriteString
(
getNormalName
(
prog
.
SSAMainPkg
.
Pkg
.
Path
()
+
".init()
\n
"
))
p
.
output
.
WriteString
(
" call void @"
)
...
...
@@ -67,8 +67,22 @@ func (p *Compiler) Compile(prog *loader.Program) (output string, err error) {
// Emit some target specific functions.
switch
getArch
(
p
.
target
)
{
case
""
,
"x86_64"
,
"aarch64"
:
p
.
output
.
WriteString
(
"define void @main() {
\n
"
)
p
.
output
.
WriteString
(
" call void @wa_main()
\n
"
)
p
.
output
.
WriteString
(
" ret void
\n
"
)
p
.
output
.
WriteString
(
"}
\n\n
"
)
p
.
output
.
WriteString
(
"declare i32 @printf(i8* readonly, ...)
\n
"
)
case
"avr"
:
p
.
output
.
WriteString
(
"define void @__avr_write_port__(i16 %0, i8 zeroext %1) {
\n
"
)
p
.
output
.
WriteString
(
" %3 = inttoptr i16 %0 to i8*
\n
"
)
p
.
output
.
WriteString
(
" store volatile i8 %1, i8* %3, align 1
\n
"
)
p
.
output
.
WriteString
(
" ret void
\n
"
)
p
.
output
.
WriteString
(
"}
\n\n
"
)
p
.
output
.
WriteString
(
"define zeroext i8 @__avr_read_port__(i16 %0) {
\n
"
)
p
.
output
.
WriteString
(
" %2 = inttoptr i16 %0 to i8*
\n
"
)
p
.
output
.
WriteString
(
" %3 = load volatile i8, i8* %2, align 1
\n
"
)
p
.
output
.
WriteString
(
" ret i8 %3
\n
"
)
p
.
output
.
WriteString
(
"}
\n\n
"
)
default
:
}
...
...
internal/backends/compiler_llvm/compile_function.go
浏览文件 @
74a1e417
...
...
@@ -12,6 +12,10 @@ import (
)
func
(
p
*
Compiler
)
compileFunction
(
fn
*
ssa
.
Function
)
error
{
if
isTargetBuiltin
(
fn
.
LinkName
(),
p
.
target
)
||
isTargetBuiltin
(
fn
.
Name
(),
p
.
target
)
{
return
nil
}
// Translate return type.
var
retTyStr
string
rets
:=
fn
.
Signature
.
Results
()
...
...
@@ -47,10 +51,18 @@ func (p *Compiler) compileFunction(fn *ssa.Function) error {
}
// Emit a proper function name.
p
.
output
.
WriteString
(
"define "
)
if
len
(
fn
.
Blocks
)
==
0
{
p
.
output
.
WriteString
(
"declare "
)
}
else
{
p
.
output
.
WriteString
(
"define "
)
}
p
.
output
.
WriteString
(
retTyStr
)
p
.
output
.
WriteString
(
" @"
)
p
.
output
.
WriteString
(
getNormalName
(
fn
.
Pkg
.
Pkg
.
Path
()
+
"."
+
fn
.
Name
()))
if
len
(
fn
.
LinkName
())
>
0
{
p
.
output
.
WriteString
(
fn
.
LinkName
())
}
else
{
p
.
output
.
WriteString
(
getNormalName
(
fn
.
Pkg
.
Pkg
.
Path
()
+
"."
+
fn
.
Name
()))
}
p
.
output
.
WriteString
(
"("
)
// Translate arguments.
...
...
@@ -70,7 +82,12 @@ func (p *Compiler) compileFunction(fn *ssa.Function) error {
p
.
output
.
WriteString
(
", "
)
}
}
p
.
output
.
WriteString
(
") {
\n
"
)
if
len
(
fn
.
Blocks
)
==
0
{
p
.
output
.
WriteString
(
")
\n\n
"
)
return
nil
}
else
{
p
.
output
.
WriteString
(
") {
\n
"
)
}
// Translate Go SSA intermediate instructions.
for
i
,
b
:=
range
fn
.
Blocks
{
...
...
internal/backends/compiler_llvm/utils.go
浏览文件 @
74a1e417
...
...
@@ -303,6 +303,7 @@ func getNormalName(name string) string {
name
=
strings
.
ReplaceAll
(
name
,
"."
,
"__"
)
name
=
strings
.
ReplaceAll
(
name
,
"$"
,
"__"
)
name
=
strings
.
ReplaceAll
(
name
,
"/"
,
"__"
)
name
=
strings
.
ReplaceAll
(
name
,
"#"
,
"__"
)
return
name
}
...
...
@@ -315,3 +316,24 @@ func getRealType(ty types.Type) types.Type {
}
}
}
func
isTargetBuiltin
(
fn
string
,
target
string
)
bool
{
avr
:=
[]
string
{
"__avr_write_port__"
,
"__avr_read_port__"
}
other
:=
[]
string
{
"printf"
}
var
ts
[]
string
switch
getArch
(
target
)
{
case
"avr"
:
ts
=
avr
default
:
ts
=
other
}
for
_
,
v
:=
range
ts
{
if
v
==
fn
{
return
true
}
}
return
false
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录