Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wa-lang
wa
提交
5aebda55
wa
项目概览
wa-lang
/
wa
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
5aebda55
编写于
11月 05, 2022
作者:
B
Ben Shi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
llvm: implement translation of type convertion.
上级
0b1312ab
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
197 addition
and
1 deletion
+197
-1
_examples/misc/native_test.wa
_examples/misc/native_test.wa
+70
-0
internal/backends/compiler_llvm/compile_value.go
internal/backends/compiler_llvm/compile_value.go
+75
-0
internal/backends/compiler_llvm/utils.go
internal/backends/compiler_llvm/utils.go
+52
-1
未找到文件。
_examples/misc/native_test.wa
浏览文件 @
5aebda55
...
...
@@ -33,6 +33,11 @@ fn main {
test_pointer()
test_convert0()
test_convert1()
test_convert2()
test_convert3()
bye()
}
...
...
@@ -175,3 +180,68 @@ fn new_int() *i32 {
fn set_int(p: *i32) {
*p = 13
}
fn convert_i32_to_i16(a: i32) i16 {
return i16(a)
}
fn convert_i32_to_u16(a: i32) u16 {
return u16(a)
}
fn convert_i16_to_i32(a: i16) i32 {
return i32(a)
}
fn convert_u16_to_i32(a: u16) i32 {
return i32(a)
}
fn test_convert0() {
println(i32(convert_i32_to_i16(65537)))
println(u32(convert_i32_to_u16(65537)))
println(convert_i16_to_i32(100))
println(convert_i16_to_i32(-100))
println(convert_u16_to_i32(100))
println(convert_u16_to_i32(65530))
}
fn convert_f64_to_f32(a: f64) f32 {
return f32(a)
}
fn test_convert1() {
println(float64(convert_f64_to_f32(3.1415926535)))
}
fn convert_i16_to_f64(a: i16) f64 {
return f64(a)
}
fn convert_u16_to_f64(a: u16) f64 {
return f64(a)
}
fn test_convert2() {
println(convert_i16_to_f64(100))
println(convert_i16_to_f64(-100))
println(convert_u16_to_f64(100))
println(convert_u16_to_f64(65530))
}
fn convert_f64_to_i32(a: f64) i32 {
return i32(a)
}
fn convert_f64_to_u32(a: f64) u32 {
return u32(a)
}
fn test_convert3() {
println(convert_f64_to_i32(100.001))
println(convert_f64_to_u32(100.001))
println(convert_f64_to_i32(99.99))
println(convert_f64_to_u32(99.99))
println(convert_f64_to_i32(-100.001))
println(convert_f64_to_u32(-100.001))
}
internal/backends/compiler_llvm/compile_value.go
浏览文件 @
5aebda55
...
...
@@ -96,6 +96,11 @@ func (p *Compiler) compileValue(val ssa.Value) error {
p
.
output
.
WriteString
(
strconv
.
Itoa
(
val
.
Field
))
p
.
output
.
WriteString
(
"
\n
"
)
case
*
ssa
.
Convert
:
if
err
:=
p
.
compileConvert
(
val
);
err
!=
nil
{
return
err
}
default
:
p
.
output
.
WriteString
(
" ; "
+
val
.
Name
()
+
" = "
+
val
.
String
()
+
"
\n
"
)
// panic("unsupported Value '" + val.Name() + " = " + val.String() + "'")
...
...
@@ -104,6 +109,76 @@ func (p *Compiler) compileValue(val ssa.Value) error {
return
nil
}
func
(
p
*
Compiler
)
compileConvert
(
val
*
ssa
.
Convert
)
error
{
frIsFloat
,
frIsSigned
:=
checkType
(
val
.
X
.
Type
())
toIsFloat
,
toIsSigned
:=
checkType
(
val
.
Type
())
frSize
:=
getTypeSize
(
val
.
X
.
Type
(),
p
.
target
)
toSize
:=
getTypeSize
(
val
.
Type
(),
p
.
target
)
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
getValueStr
(
val
))
p
.
output
.
WriteString
(
" = "
)
switch
{
case
!
frIsFloat
&&
!
toIsFloat
:
// integral type -> integral type
switch
{
case
frSize
==
toSize
:
p
.
output
.
WriteString
(
"add "
)
p
.
output
.
WriteString
(
getTypeStr
(
val
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
getValueStr
(
val
.
X
))
p
.
output
.
WriteString
(
", 0
\n
"
)
return
nil
case
frSize
>
toSize
:
p
.
output
.
WriteString
(
"trunc "
)
case
frSize
<
toSize
:
if
!
toIsSigned
||
!
frIsSigned
{
p
.
output
.
WriteString
(
"zext "
)
}
else
{
p
.
output
.
WriteString
(
"sext "
)
}
default
:
panic
(
"unkown type convert: "
+
val
.
String
())
}
case
frIsFloat
&&
toIsFloat
:
// float point type -> float point type
switch
{
case
frSize
>
toSize
:
p
.
output
.
WriteString
(
"fptrunc "
)
case
frSize
<
toSize
:
p
.
output
.
WriteString
(
"fpext "
)
default
:
panic
(
"unkown type convert: "
+
val
.
String
())
}
case
!
frIsFloat
&&
toIsFloat
:
// integeral type -> float point type
if
frIsSigned
{
p
.
output
.
WriteString
(
"sitofp "
)
}
else
{
p
.
output
.
WriteString
(
"uitofp "
)
}
case
frIsFloat
&&
!
toIsFloat
:
//float point type -> integral type
if
toIsSigned
{
p
.
output
.
WriteString
(
"fptosi "
)
}
else
{
p
.
output
.
WriteString
(
"fptoui "
)
}
default
:
panic
(
"unkown type convert: "
+
val
.
String
())
}
p
.
output
.
WriteString
(
getTypeStr
(
val
.
X
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
getValueStr
(
val
.
X
))
p
.
output
.
WriteString
(
" to "
)
p
.
output
.
WriteString
(
getTypeStr
(
val
.
Type
(),
p
.
target
))
p
.
output
.
WriteString
(
"
\n
"
)
return
nil
}
func
(
p
*
Compiler
)
compileUnOp
(
val
*
ssa
.
UnOp
)
error
{
p
.
output
.
WriteString
(
" "
)
p
.
output
.
WriteString
(
getValueStr
(
val
))
...
...
internal/backends/compiler_llvm/utils.go
浏览文件 @
5aebda55
...
...
@@ -183,7 +183,58 @@ func getTypeStr(ty types.Type, target string) string {
return
getTypeStr
(
t
.
Underlying
(),
target
)
default
:
// TODO: support pointer, array and struct types
panic
(
"unknown type"
)
}
}
func
getTypeSize
(
ty
types
.
Type
,
target
string
)
int
{
// feasible types on different targets
defInt
:=
map
[
string
]
int
{
"avr"
:
2
,
"thumb"
:
2
,
"arm"
:
4
,
"aarch64"
:
8
,
"riscv32"
:
4
,
"riscv64"
:
8
,
"x86"
:
4
,
"x86_64"
:
8
,
}
// fixed types
expTy
:=
map
[
types
.
BasicKind
]
int
{
types
.
Bool
:
1
,
types
.
UntypedBool
:
1
,
types
.
Int8
:
1
,
types
.
Uint8
:
1
,
types
.
Int16
:
2
,
types
.
Uint16
:
2
,
types
.
Int32
:
4
,
types
.
Uint32
:
4
,
types
.
Int64
:
8
,
types
.
Uint64
:
8
,
types
.
Float32
:
4
,
types
.
Float64
:
8
,
types
.
UntypedFloat
:
4
,
}
switch
t
:=
ty
.
(
type
)
{
case
*
types
.
Basic
:
// return size of a fixed type
if
sz
,
ok
:=
expTy
[
t
.
Kind
()];
ok
{
return
sz
}
// return size of a feasible type
switch
t
.
Kind
()
{
case
types
.
Int
,
types
.
Uint
,
types
.
UntypedInt
:
if
sz
,
ok
:=
defInt
[
getArch
(
target
)];
ok
{
return
sz
}
return
8
// should never reach here
default
:
panic
(
"unknown basic type"
)
}
default
:
panic
(
"unknown type"
)
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录