提交 8c0d68aa 编写于 作者: B Ben Shi

llvm: implement translation of global variables.

上级 edb85342
......@@ -33,13 +33,18 @@ fn main {
test_struct1(13, 1, 0)
test_struct1(2, 1, 0)
test_pointer()
test_convert0()
test_convert1()
test_convert2()
test_convert3()
test_global_consts()
test_global_variables_0()
test_global_variables_1()
test_pointer(1)
test_pointer(-1)
bye()
}
......@@ -166,23 +171,6 @@ fn test_struct1(a int, b int, c int) {
}
}
fn test_pointer() {
p := new_int()
println(*p)
set_int(p)
println(*p)
}
fn new_int() *i32 {
var i i32
i = 42
return &i
}
fn set_int(p *i32) {
*p = 13
}
fn convert_i32_to_i16(a i32) i16 {
return i16(a)
}
......@@ -251,3 +239,57 @@ fn test_convert3() {
fn test_print(a i16, b u16, c i8, d u8, e f32) {
println(a, ", ", b, ", ", c, ", ", d, ", ", e/2)
}
const gbegin = 10
const gend = 20
fn test_global_consts() {
for i := gbegin; i < gend; i++ {
println(i, " - ", gbegin, " = ", i - gbegin)
}
}
type ty0 struct {
v0 int
v1 float64
}
var gv0 ty0 = ty0{5555, 3.1415926}
var gv1 [4]int = [4]int{81, 82, 17, 76}
fn test_global_variables_0() {
println("gv0: {", gv0.v0, ", ", gv0.v1, "}")
println("gv1: {", gv1[0], ", ", gv1[1], ", ", gv1[2], ", ", gv1[3], "}")
}
fn test_global_variables_1() {
gv0.v0 = 8888
gv0.v1 = 2.71828
gv1[0] += 2
gv1[1] += 3
gv1[2] += 4
gv1[3] += 5
println("gv0: {", gv0.v0, ", ", gv0.v1, "}")
println("gv1: {", gv1[0], ", ", gv1[1], ", ", gv1[2], ", ", gv1[3], "}")
}
var gint0 int = 100
var gint1 int = 200
fn get_int_addr(a int) *int {
if a > 0 {
return &gint0
} else {
return &gint1
}
}
fn set_int(a *int) {
*a += 10
}
fn test_pointer(a int) {
println(gint0, ", ", gint1)
p := get_int_addr(a)
set_int(p)
println(gint0, ", ", gint1)
}
......@@ -71,12 +71,21 @@ func (p *Compiler) compilePackage() error {
}
}
// Emit all global variables.
for _, gv := range gs {
p.output.WriteString("@")
p.output.WriteString(getNormalName(gv.Name()))
p.output.WriteString(" = global ")
tys := getTypeStr(gv.Type(), p.target)
p.output.WriteString(tys[0:(len(tys) - 1)])
p.output.WriteString(" zeroinitializer\n")
}
if len(gs) > 0 {
p.output.WriteString("\n")
}
// Generate LLVM-IR for each global function.
for _, v := range fns {
// TODO: Support the builtin function 'init'.
if v.Name() == "init" {
continue
}
if err := p.compileFunction(v); err != nil {
return err
}
......
......@@ -46,6 +46,13 @@ func (p *Compiler) compileFunction(fn *ssa.Function) error {
}
p.output.WriteString(") {\n")
// Initialize all global variables at the beginning of the main function.
if fn.Name() == "main" {
p.output.WriteString("__basic_block_init:\n")
p.output.WriteString(" call void @init()\n")
p.output.WriteString(" br label %__basic_block_0\n\n")
}
// Translate Go SSA intermediate instructions.
for i, b := range fn.Blocks {
p.output.WriteString(fmt.Sprintf("__basic_block_%d:\n", i))
......
......@@ -262,7 +262,16 @@ func getValueStr(val ssa.Value) string {
case *ssa.Parameter:
return "%" + val.Name()
case *ssa.Global:
return "@" + getNormalName(val.Name())
default:
return "%" + val.Name()
}
}
func getNormalName(name string) string {
name = strings.ReplaceAll(name, ".", "__")
name = strings.ReplaceAll(name, "$", "___")
return name
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册