diff --git a/go.mod b/go.mod index 1b5e614..4b2208c 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,13 @@ go 1.12 require ( github.com/BurntSushi/toml v0.3.1 - github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect - github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect - github.com/kr/pretty v0.1.0 - github.com/llir/llvm v0.3.0-pre6.0.20190109195651-59d9946db6ba - github.com/pkg/errors v0.8.1 - github.com/sergi/go-diff v1.0.0 + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect + github.com/llir/llvm v0.3.0 + github.com/sergi/go-diff v1.1.0 github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 - github.com/stretchr/testify v1.3.0 // indirect github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8 - golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc // indirect - golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb // indirect - golang.org/x/tools v0.0.0-20190109165630-d30e00c24034 // indirect + golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 // indirect + golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ffc7597 --- /dev/null +++ b/go.sum @@ -0,0 +1,59 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/llir/ll v0.0.0-20191229032745-05be70ade156 h1:tQ3EaDUy4rHvIyvuI2Yf1X2xPMVi4orBwX3H1NSWp74= +github.com/llir/ll v0.0.0-20191229032745-05be70ade156/go.mod h1:8W5HJz80PitAyPZUpOcljQxTu6LD5YKW1URTo+OjVoc= +github.com/llir/llvm v0.3.0 h1:A4lHTPerMXrHYWJZF80XsnerraV8PKEqhBG+4wedSHg= +github.com/llir/llvm v0.3.0/go.mod h1:yjHRZjO9xc1uLUS69qO2qYjS95XFdfd2odSdSnufS10= +github.com/mewmew/float v0.0.0-20191226120903-16bbe2fdd85e h1:KCD7E/8LKwDsC5ymlEWJ3xCiSPaCywrS/psToBMOBH4= +github.com/mewmew/float v0.0.0-20191226120903-16bbe2fdd85e/go.mod h1:O+xb+8ycBNHzJicFVs7GRWtruD4tVZI0huVnw5TM01E= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= +github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8 h1:RB0v+/pc8oMzPsN97aZYEwNuJ6ouRJ2uhjxemJ9zvrY= +github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8/go.mod h1:IlWNj9v/13q7xFbaK4mbyzMNwrZLaWSHx/aibKIZuIg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4 h1:Toz2IK7k8rbltAXwNAxKcn9OzqyNfMUhUNjz3sL0NMk= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/llvm/asm/asm.go b/llvm/asm/asm.go deleted file mode 100755 index 242191b..0000000 --- a/llvm/asm/asm.go +++ /dev/null @@ -1,70 +0,0 @@ -// Package asm implements a parser for LLVM IR assembly. -package asm - -import ( - "io" - "io/ioutil" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/asm/internal/irx" - "github.com/geode-lang/geode/llvm/asm/internal/lexer" - "github.com/geode-lang/geode/llvm/asm/internal/parser" - "github.com/geode-lang/geode/llvm/ir" - "github.com/pkg/errors" -) - -// ParseFile parses the given LLVM IR assembly file into an LLVM IR module. -func ParseFile(path string) (*ir.Module, error) { - buf, err := ioutil.ReadFile(path) - if err != nil { - return nil, errors.WithStack(err) - } - return ParseBytes(buf) -} - -// Parse parses the given LLVM IR assembly file into an LLVM IR module, reading -// from r. -func Parse(r io.Reader) (*ir.Module, error) { - buf, err := ioutil.ReadAll(r) - if err != nil { - return nil, errors.WithStack(err) - } - return ParseBytes(buf) -} - -// ParseBytes parses the given LLVM IR assembly file into an LLVM IR module, -// reading from b. -func ParseBytes(b []byte) (*ir.Module, error) { - module, err := parseBytes(b) - if err != nil { - return nil, errors.WithStack(err) - } - // Translate the AST of the module to an equivalent LLVM IR module. - m, err := irx.Translate(module) - if err != nil { - return nil, errors.WithStack(err) - } - return m, nil -} - -// ParseString parses the given LLVM IR assembly file into an LLVM IR module, -// reading from s. -func ParseString(s string) (*ir.Module, error) { - return ParseBytes([]byte(s)) -} - -// parseBytes parses the given LLVM IR assembly file into an AST, reading from -// b. -func parseBytes(b []byte) (*ast.Module, error) { - l := lexer.NewLexer(b) - p := parser.NewParser() - module, err := p.Parse(l) - if err != nil { - return nil, errors.WithStack(err) - } - m, ok := module.(*ast.Module) - if !ok { - return nil, errors.Errorf("invalid module type; expected *ast.Module, got %T", module) - } - return m, nil -} diff --git a/llvm/asm/example_test.go b/llvm/asm/example_test.go deleted file mode 100755 index 664c872..0000000 --- a/llvm/asm/example_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package asm_test - -import ( - "log" - - "github.com/kr/pretty" - "github.com/geode-lang/geode/llvm/asm" -) - -func Example() { - // Parse the LLVM IR assembly file `rand.ll`. - m, err := asm.ParseFile("testdata/rand.ll") - if err != nil { - log.Fatal(err) - } - // Pretty-print the data types of the parsed LLVM IR module. - pretty.Println(m) - // Output: - // - // &ir.Module{ - // DataLayout: "", - // TargetTriple: "", - // Types: nil, - // Globals: { - // &ir.Global{ - // Name: "seed", - // Typ: &types.PointerType{ - // Name: "", - // Elem: &types.IntType{Name:"", Size:32}, - // AddrSpace: 0, - // }, - // Content: &types.IntType{Name:"", Size:32}, - // Init: &constant.Int{ - // Typ: &types.IntType{(CYCLIC REFERENCE)}, - // X: &big.Int{}, - // }, - // IsConst: false, - // Metadata: { - // }, - // }, - // }, - // Funcs: { - // &ir.Function{ - // Parent: &ir.Module{(CYCLIC REFERENCE)}, - // Name: "abs", - // Typ: &types.PointerType{ - // Name: "", - // Elem: &types.FuncType{ - // Name: "", - // Ret: &types.IntType{Name:"", Size:32}, - // Params: { - // &types.Param{ - // Name: "x", - // Typ: &types.IntType{Name:"", Size:32}, - // }, - // }, - // Variadic: false, - // }, - // AddrSpace: 0, - // }, - // Sig: &types.FuncType{ - // Name: "", - // Ret: &types.IntType{Name:"", Size:32}, - // Params: { - // &types.Param{ - // Name: "x", - // Typ: &types.IntType{Name:"", Size:32}, - // }, - // }, - // Variadic: false, - // }, - // CallConv: 0x0, - // Blocks: nil, - // Metadata: { - // }, - // mu: sync.Mutex{}, - // }, - // &ir.Function{ - // Parent: &ir.Module{(CYCLIC REFERENCE)}, - // Name: "rand", - // Typ: &types.PointerType{ - // Name: "", - // Elem: &types.FuncType{ - // Name: "", - // Ret: &types.IntType{Name:"", Size:32}, - // Params: { - // }, - // Variadic: false, - // }, - // AddrSpace: 0, - // }, - // Sig: &types.FuncType{ - // Name: "", - // Ret: &types.IntType{Name:"", Size:32}, - // Params: { - // }, - // Variadic: false, - // }, - // CallConv: 0x0, - // Blocks: { - // &ir.BasicBlock{ - // Parent: &ir.Function{(CYCLIC REFERENCE)}, - // Name: "0", - // Insts: { - // &ir.InstLoad{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // Name: "1", - // Typ: &types.IntType{(CYCLIC REFERENCE)}, - // Src: &ir.Global{(CYCLIC REFERENCE)}, - // Metadata: { - // }, - // }, - // &ir.InstMul{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // Name: "2", - // X: &ir.InstLoad{(CYCLIC REFERENCE)}, - // Y: &constant.Int{ - // Typ: &types.IntType{Name:"", Size:32}, - // X: &big.Int{ - // neg: false, - // abs: {0x15a4e35}, - // }, - // }, - // Metadata: { - // }, - // }, - // &ir.InstAdd{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // Name: "3", - // X: &ir.InstMul{(CYCLIC REFERENCE)}, - // Y: &constant.Int{ - // Typ: &types.IntType{Name:"", Size:32}, - // X: &big.Int{ - // neg: false, - // abs: {0x1}, - // }, - // }, - // Metadata: { - // }, - // }, - // &ir.InstStore{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // Src: &ir.InstAdd{(CYCLIC REFERENCE)}, - // Dst: &ir.Global{(CYCLIC REFERENCE)}, - // Metadata: { - // }, - // }, - // &ir.InstCall{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // Name: "4", - // Callee: &ir.Function{(CYCLIC REFERENCE)}, - // Sig: &types.FuncType{(CYCLIC REFERENCE)}, - // Args: { - // &ir.InstAdd{(CYCLIC REFERENCE)}, - // }, - // CallConv: 0x0, - // Metadata: { - // }, - // }, - // }, - // Term: &ir.TermRet{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // X: &ir.InstCall{ - // Parent: &ir.BasicBlock{(CYCLIC REFERENCE)}, - // Name: "4", - // Callee: &ir.Function{(CYCLIC REFERENCE)}, - // Sig: &types.FuncType{(CYCLIC REFERENCE)}, - // Args: { - // &ir.InstAdd{(CYCLIC REFERENCE)}, - // }, - // CallConv: 0x0, - // Metadata: { - // }, - // }, - // Metadata: { - // }, - // }, - // }, - // }, - // Metadata: { - // }, - // mu: sync.Mutex{}, - // }, - // }, - // NamedMetadata: nil, - // Metadata: nil, - // } -} diff --git a/llvm/asm/internal/.gitignore b/llvm/asm/internal/.gitignore deleted file mode 100755 index 07ac7af..0000000 --- a/llvm/asm/internal/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -errors/errors.go -lexer/acttab.go -lexer/lexer.go -lexer/transitiontable.go -parser/action.go -parser/actiontable.go -parser/gototable.go -parser/parser.go -parser/productionstable.go -token/token.go -util/litconv.go -util/rune.go diff --git a/llvm/asm/internal/Makefile b/llvm/asm/internal/Makefile deleted file mode 100755 index d3b25fe..0000000 --- a/llvm/asm/internal/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -all: gen - -gen: ll.bnf - gocc -zip $< - -debug_lexer: ll.bnf - gocc -debug_lexer -v $< - -debug_parser: ll.bnf - gocc -debug_parser -v $< - -clean: - rm -f errors/errors.go - rm -f lexer/acttab.go - rm -f lexer/lexer.go - rm -f lexer/transitiontable.go - rm -f parser/action.go - rm -f parser/actiontable.go - rm -f parser/gototable.go - rm -f parser/parser.go - rm -f parser/productionstable.go - rm -f token/token.go - rm -f util/litconv.go - rm -f util/rune.go - -rmdir --ignore-fail-on-non-empty errors - -rmdir --ignore-fail-on-non-empty lexer - -rmdir --ignore-fail-on-non-empty parser - -rmdir --ignore-fail-on-non-empty token - -rmdir --ignore-fail-on-non-empty util - rm -f terminals.txt LR1_conflicts.txt LR1_sets.txt first.txt lexer_sets.txt - -.PHONY: gen debug_lexer debug_parser clean diff --git a/llvm/asm/internal/ast/asm_test.go b/llvm/asm/internal/ast/asm_test.go deleted file mode 100755 index 956b34e..0000000 --- a/llvm/asm/internal/ast/asm_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package ast_test - -import ( - "fmt" - "io/ioutil" - "testing" - - "github.com/geode-lang/geode/llvm/asm" - "github.com/sergi/go-diff/diffmatchpatch" -) - -func TestRoundTrip(t *testing.T) { - // Round-trip test of the parser. - golden := []struct { - path string - }{ - // Empty module. - {path: "../../testdata/empty.ll"}, - // Top-level declarations. - {path: "../../testdata/module.ll"}, - {path: "../../testdata/global.ll"}, - {path: "../../testdata/global_circular.ll"}, - {path: "../../testdata/func.ll"}, - {path: "../../testdata/metadata.ll"}, - // Types. - {path: "../../testdata/type.ll"}, - // Constants. - {path: "../../testdata/const.ll"}, - // Constant expressions. - {path: "../../testdata/expr_binary.ll"}, - {path: "../../testdata/expr_bitwise.ll"}, - {path: "../../testdata/expr_vector.ll"}, - {path: "../../testdata/expr_aggregate.ll"}, - {path: "../../testdata/expr_memory.ll"}, - {path: "../../testdata/expr_conversion.ll"}, - {path: "../../testdata/expr_other.ll"}, - // Instructions. - {path: "../../testdata/inst_binary.ll"}, - {path: "../../testdata/inst_bitwise.ll"}, - {path: "../../testdata/inst_vector.ll"}, - {path: "../../testdata/inst_aggregate.ll"}, - {path: "../../testdata/inst_memory.ll"}, - {path: "../../testdata/inst_conversion.ll"}, - {path: "../../testdata/inst_other.ll"}, - // Terminators. - {path: "../../testdata/term.ll"}, - // Pseudo-random number generator. - {path: "../../testdata/rand.ll"}, - // Inline assembly. - {path: "../../testdata/inline_asm.ll"}, - // Fixed bugs. - {path: "../../testdata/fixedbugs/issue_27.ll"}, - } - dmp := diffmatchpatch.New() - for _, g := range golden { - buf, err := ioutil.ReadFile(g.path) - if err != nil { - t.Errorf("%q: unable to read file; %v", g.path, err) - continue - } - input := string(buf) - m, err := asm.ParseString(input) - if err != nil { - t.Errorf("%q: unable to parse file; %v", g.path, err) - continue - } - want := input - // Read foo.ll.golden if present. - if buf, err := ioutil.ReadFile(g.path + ".golden"); err == nil { - want = string(buf) - } - got := m.String() - if want != got { - diffs := dmp.DiffMain(want, got, false) - fmt.Println(dmp.DiffPrettyText(diffs)) - t.Errorf("%q: module mismatch; expected `%v`, got `%v`", g.path, want, got) - continue - } - } -} diff --git a/llvm/asm/internal/ast/ast_test.go b/llvm/asm/internal/ast/ast_test.go deleted file mode 100755 index 2f39e67..0000000 --- a/llvm/asm/internal/ast/ast_test.go +++ /dev/null @@ -1,214 +0,0 @@ -package ast_test - -import "github.com/geode-lang/geode/llvm/asm/internal/ast" - -// Validate that the relevant types satisfy the ast.Constant interface. -var ( - // Simple constants. - _ ast.Constant = &ast.IntConst{} - _ ast.Constant = &ast.FloatConst{} - _ ast.Constant = &ast.NullConst{} - // Complex constants. - _ ast.Constant = &ast.VectorConst{} - _ ast.Constant = &ast.ArrayConst{} - _ ast.Constant = &ast.CharArrayConst{} - _ ast.Constant = &ast.StructConst{} - _ ast.Constant = &ast.ZeroInitializerConst{} - _ ast.Constant = &ast.UndefConst{} - // Global variable and function addresses - _ ast.Constant = &ast.Global{} - _ ast.Constant = &ast.Function{} -) - -// Validate that the relevant types satisfy the ast.Constant interface. -var ( - // Binary expressions - _ ast.Constant = &ast.ExprAdd{} - _ ast.Constant = &ast.ExprFAdd{} - _ ast.Constant = &ast.ExprSub{} - _ ast.Constant = &ast.ExprFSub{} - _ ast.Constant = &ast.ExprMul{} - _ ast.Constant = &ast.ExprFMul{} - _ ast.Constant = &ast.ExprUDiv{} - _ ast.Constant = &ast.ExprSDiv{} - _ ast.Constant = &ast.ExprFDiv{} - _ ast.Constant = &ast.ExprURem{} - _ ast.Constant = &ast.ExprSRem{} - _ ast.Constant = &ast.ExprFRem{} - // Bitwise expressions - _ ast.Constant = &ast.ExprShl{} - _ ast.Constant = &ast.ExprLShr{} - _ ast.Constant = &ast.ExprAShr{} - _ ast.Constant = &ast.ExprAnd{} - _ ast.Constant = &ast.ExprOr{} - _ ast.Constant = &ast.ExprXor{} - // Vector expressions - _ ast.Constant = &ast.ExprExtractElement{} - _ ast.Constant = &ast.ExprInsertElement{} - _ ast.Constant = &ast.ExprShuffleVector{} - // Aggregate expressions - _ ast.Constant = &ast.ExprExtractValue{} - _ ast.Constant = &ast.ExprInsertValue{} - // Memory expressions - _ ast.Constant = &ast.ExprGetElementPtr{} - // Conversion expressions - _ ast.Constant = &ast.ExprTrunc{} - _ ast.Constant = &ast.ExprZExt{} - _ ast.Constant = &ast.ExprSExt{} - _ ast.Constant = &ast.ExprFPTrunc{} - _ ast.Constant = &ast.ExprFPExt{} - _ ast.Constant = &ast.ExprFPToUI{} - _ ast.Constant = &ast.ExprFPToSI{} - _ ast.Constant = &ast.ExprUIToFP{} - _ ast.Constant = &ast.ExprSIToFP{} - _ ast.Constant = &ast.ExprPtrToInt{} - _ ast.Constant = &ast.ExprIntToPtr{} - _ ast.Constant = &ast.ExprBitCast{} - _ ast.Constant = &ast.ExprAddrSpaceCast{} - // Other expressions - _ ast.Constant = &ast.ExprICmp{} - _ ast.Constant = &ast.ExprFCmp{} - _ ast.Constant = &ast.ExprSelect{} -) - -// Validate that the relevant types satisfy the ast.Instruction interface. -var ( - // Binary instructions - _ ast.Instruction = &ast.InstAdd{} - _ ast.Instruction = &ast.InstFAdd{} - _ ast.Instruction = &ast.InstSub{} - _ ast.Instruction = &ast.InstFSub{} - _ ast.Instruction = &ast.InstMul{} - _ ast.Instruction = &ast.InstFMul{} - _ ast.Instruction = &ast.InstUDiv{} - _ ast.Instruction = &ast.InstSDiv{} - _ ast.Instruction = &ast.InstFDiv{} - _ ast.Instruction = &ast.InstURem{} - _ ast.Instruction = &ast.InstSRem{} - _ ast.Instruction = &ast.InstFRem{} - // Bitwise instructions - _ ast.Instruction = &ast.InstShl{} - _ ast.Instruction = &ast.InstLShr{} - _ ast.Instruction = &ast.InstAShr{} - _ ast.Instruction = &ast.InstAnd{} - _ ast.Instruction = &ast.InstOr{} - _ ast.Instruction = &ast.InstXor{} - // Vector instructions - _ ast.Instruction = &ast.InstExtractElement{} - _ ast.Instruction = &ast.InstInsertElement{} - _ ast.Instruction = &ast.InstShuffleVector{} - // Aggregate instructions - _ ast.Instruction = &ast.InstExtractValue{} - _ ast.Instruction = &ast.InstInsertValue{} - // Memory instructions - _ ast.Instruction = &ast.InstAlloca{} - _ ast.Instruction = &ast.InstLoad{} - _ ast.Instruction = &ast.InstStore{} - _ ast.Instruction = &ast.InstGetElementPtr{} - // Conversion instructions - _ ast.Instruction = &ast.InstTrunc{} - _ ast.Instruction = &ast.InstZExt{} - _ ast.Instruction = &ast.InstSExt{} - _ ast.Instruction = &ast.InstFPTrunc{} - _ ast.Instruction = &ast.InstFPExt{} - _ ast.Instruction = &ast.InstFPToUI{} - _ ast.Instruction = &ast.InstFPToSI{} - _ ast.Instruction = &ast.InstUIToFP{} - _ ast.Instruction = &ast.InstSIToFP{} - _ ast.Instruction = &ast.InstPtrToInt{} - _ ast.Instruction = &ast.InstIntToPtr{} - _ ast.Instruction = &ast.InstBitCast{} - _ ast.Instruction = &ast.InstAddrSpaceCast{} - // Other instructions - _ ast.Instruction = &ast.InstICmp{} - _ ast.Instruction = &ast.InstFCmp{} - _ ast.Instruction = &ast.InstPhi{} - _ ast.Instruction = &ast.InstSelect{} - _ ast.Instruction = &ast.InstCall{} -) - -// Validate that the relevant types satisfy the ast.Terminator interface. -var ( - // Terminators - _ ast.Terminator = &ast.TermRet{} - _ ast.Terminator = &ast.TermBr{} - _ ast.Terminator = &ast.TermCondBr{} - _ ast.Terminator = &ast.TermSwitch{} - _ ast.Terminator = &ast.TermUnreachable{} -) - -// Validate that the relevant types satisfy the ast.NamedValue interface. -var ( - _ ast.NamedValue = &ast.Global{} - _ ast.NamedValue = &ast.GlobalDummy{} - _ ast.NamedValue = &ast.Function{} - _ ast.NamedValue = &ast.Param{} - _ ast.NamedValue = &ast.BasicBlock{} - _ ast.NamedValue = &ast.LocalDummy{} - // Binary instructions - _ ast.NamedValue = &ast.InstAdd{} - _ ast.NamedValue = &ast.InstFAdd{} - _ ast.NamedValue = &ast.InstSub{} - _ ast.NamedValue = &ast.InstFSub{} - _ ast.NamedValue = &ast.InstMul{} - _ ast.NamedValue = &ast.InstFMul{} - _ ast.NamedValue = &ast.InstUDiv{} - _ ast.NamedValue = &ast.InstSDiv{} - _ ast.NamedValue = &ast.InstFDiv{} - _ ast.NamedValue = &ast.InstURem{} - _ ast.NamedValue = &ast.InstSRem{} - _ ast.NamedValue = &ast.InstFRem{} - // Bitwise instructions - _ ast.NamedValue = &ast.InstShl{} - _ ast.NamedValue = &ast.InstLShr{} - _ ast.NamedValue = &ast.InstAShr{} - _ ast.NamedValue = &ast.InstAnd{} - _ ast.NamedValue = &ast.InstOr{} - _ ast.NamedValue = &ast.InstXor{} - // Vector instructions - _ ast.NamedValue = &ast.InstExtractElement{} - _ ast.NamedValue = &ast.InstInsertElement{} - _ ast.NamedValue = &ast.InstShuffleVector{} - // Aggregate instructions - _ ast.NamedValue = &ast.InstExtractValue{} - _ ast.NamedValue = &ast.InstInsertValue{} - // Memory instructions - _ ast.NamedValue = &ast.InstAlloca{} - _ ast.NamedValue = &ast.InstLoad{} - _ ast.NamedValue = &ast.InstGetElementPtr{} - // Conversion instructions - _ ast.NamedValue = &ast.InstTrunc{} - _ ast.NamedValue = &ast.InstZExt{} - _ ast.NamedValue = &ast.InstSExt{} - _ ast.NamedValue = &ast.InstFPTrunc{} - _ ast.NamedValue = &ast.InstFPExt{} - _ ast.NamedValue = &ast.InstFPToUI{} - _ ast.NamedValue = &ast.InstFPToSI{} - _ ast.NamedValue = &ast.InstUIToFP{} - _ ast.NamedValue = &ast.InstSIToFP{} - _ ast.NamedValue = &ast.InstPtrToInt{} - _ ast.NamedValue = &ast.InstIntToPtr{} - _ ast.NamedValue = &ast.InstBitCast{} - _ ast.NamedValue = &ast.InstAddrSpaceCast{} - // Other instructions - _ ast.NamedValue = &ast.InstICmp{} - _ ast.NamedValue = &ast.InstFCmp{} - _ ast.NamedValue = &ast.InstPhi{} - _ ast.NamedValue = &ast.InstSelect{} - _ ast.NamedValue = &ast.InstCall{} -) - -// Validate that the relevant types satisfy the ast.Type interface. -var ( - _ ast.Type = &ast.VoidType{} - _ ast.Type = &ast.FuncType{} - _ ast.Type = &ast.IntType{} - _ ast.Type = &ast.FloatType{} - _ ast.Type = &ast.PointerType{} - _ ast.Type = &ast.VectorType{} - _ ast.Type = &ast.LabelType{} - _ ast.Type = &ast.MetadataType{} - _ ast.Type = &ast.ArrayType{} - _ ast.Type = &ast.StructType{} - _ ast.Type = &ast.NamedType{} -) diff --git a/llvm/asm/internal/ast/astutil/asm_test.go b/llvm/asm/internal/ast/astutil/asm_test.go deleted file mode 100755 index a45f0cf..0000000 --- a/llvm/asm/internal/ast/astutil/asm_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package astutil_test - -import ( - "fmt" - "io/ioutil" - "testing" - - "github.com/geode-lang/geode/llvm/asm" - "github.com/sergi/go-diff/diffmatchpatch" -) - -func TestRoundTrip(t *testing.T) { - // Round-trip test of the parser. - golden := []struct { - path string - }{ - // Empty module. - {path: "../../../testdata/empty.ll"}, - // Top-level declarations. - {path: "../../../testdata/module.ll"}, - {path: "../../../testdata/global.ll"}, - {path: "../../../testdata/global_circular.ll"}, - {path: "../../../testdata/func.ll"}, - {path: "../../../testdata/metadata.ll"}, - // Types. - {path: "../../../testdata/type.ll"}, - // Constants. - {path: "../../../testdata/const.ll"}, - // Constant expressions. - {path: "../../../testdata/expr_binary.ll"}, - {path: "../../../testdata/expr_bitwise.ll"}, - {path: "../../../testdata/expr_vector.ll"}, - {path: "../../../testdata/expr_aggregate.ll"}, - {path: "../../../testdata/expr_memory.ll"}, - {path: "../../../testdata/expr_conversion.ll"}, - {path: "../../../testdata/expr_other.ll"}, - // Instructions. - {path: "../../../testdata/inst_binary.ll"}, - {path: "../../../testdata/inst_bitwise.ll"}, - {path: "../../../testdata/inst_vector.ll"}, - {path: "../../../testdata/inst_aggregate.ll"}, - {path: "../../../testdata/inst_memory.ll"}, - {path: "../../../testdata/inst_conversion.ll"}, - {path: "../../../testdata/inst_other.ll"}, - // Terminators. - {path: "../../../testdata/term.ll"}, - // Pseudo-random number generator. - {path: "../../../testdata/rand.ll"}, - // Inline assembly. - {path: "../../../testdata/inline_asm.ll"}, - // Fixed bugs. - {path: "../../../testdata/fixedbugs/issue_27.ll"}, - } - dmp := diffmatchpatch.New() - for _, g := range golden { - buf, err := ioutil.ReadFile(g.path) - if err != nil { - t.Errorf("%q: unable to read file; %v", g.path, err) - continue - } - input := string(buf) - m, err := asm.ParseString(input) - if err != nil { - t.Errorf("%q: unable to parse file; %v", g.path, err) - continue - } - want := input - // Read foo.ll.golden if present. - if buf, err := ioutil.ReadFile(g.path + ".golden"); err == nil { - want = string(buf) - } - got := m.String() - if want != got { - diffs := dmp.DiffMain(want, got, false) - fmt.Println(dmp.DiffPrettyText(diffs)) - t.Errorf("%q: module mismatch; expected `%v`, got `%v`", g.path, want, got) - continue - } - } -} diff --git a/llvm/asm/internal/ast/astutil/walk.go b/llvm/asm/internal/ast/astutil/walk.go deleted file mode 100755 index 9d31fc9..0000000 --- a/llvm/asm/internal/ast/astutil/walk.go +++ /dev/null @@ -1,934 +0,0 @@ -// Note, the AST traversal implementation of this package is heavily inspired by -// go fix, which is governed by a BSD license. - -// Package astutil provides utility functions for interacting with ASTs of LLVM -// IR assembly. -package astutil - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" -) - -// Walk traverses the AST x, calling visit(y) for each node y in the tree but -// also with a pointer to each ast.Type, ast.Value, and *ast.BasicBlock, in a -// bottom-up traversal. -func Walk(x interface{}, visit func(interface{})) { - WalkBeforeAfter(x, nop, visit) -} - -// WalkFunc traverses the AST of the given function, calling visit(y) for each -// node y in the tree but also with a pointer to each ast.Type, ast.Value, and -// *ast.BasicBlock, in a bottom-up traversal. -func WalkFunc(f *ast.Function, visit func(interface{})) { - WalkFuncBeforeAfter(f, nop, visit) -} - -// nop performs no operation on the given AST. -func nop(x interface{}) { -} - -// WalkBeforeAfter traverses the AST x, calling before(y) before traversing y's -// children and after(y) afterward for each node y in the tree but also with a -// pointer to each ast.Type, ast.Value, and *ast.BasicBlock, in a bottom-up -// traversal. -func WalkBeforeAfter(x interface{}, before, after func(interface{})) { - w := &walker{ - visited: make(map[interface{}]bool), - } - w.walkBeforeAfter(x, before, after) -} - -// WalkFuncBeforeAfter traverses the AST of the given function, calling -// before(y) before traversing y's children and after(y) afterward for each node -// y in the tree but also with a pointer to each ast.Type, ast.Value, and -// *ast.BasicBlock, in a bottom-up traversal. -// -// Special precaution is taken during traversal to stay within the scope of the -// function. -func WalkFuncBeforeAfter(f *ast.Function, before, after func(interface{})) { - w := &walker{ - funcScope: true, - visited: make(map[interface{}]bool), - } - // Traverse child nodes of function, instead of f directly, as *ast.Function - // nodes are not traversed when staying within the scope of the function. - w.walkBeforeAfter(&f.Sig, before, after) - if f.Blocks != nil { - w.walkBeforeAfter(&f.Blocks, before, after) - } -} - -// A walker traverses ASTs of LLVM IR while preventing infinite loops. -type walker struct { - // Specifies whether to stay within the scope of the function during - // traversal. - funcScope bool - // visited keeps track of visited nodes to prevent infinite loops. - visited map[interface{}]bool -} - -// walkBeforeAfter traverses the AST x, calling before(y) before traversing y's -// children and after(y) afterward for each node y in the tree but also with a -// pointer to each ast.Type, ast.Value, and *ast.BasicBlock, in a bottom-up -// traversal. -func (w *walker) walkBeforeAfter(x interface{}, before, after func(interface{})) { - switch x.(type) { - case []*ast.Global, []*ast.Function, []*ast.Param, []*ast.NamedMetadata, []*ast.Metadata, []ast.MetadataNode, []*ast.AttachedMD, []ast.Type, []*ast.NamedType, []ast.Value, []ast.Constant, []*ast.BasicBlock, []ast.Instruction, []*ast.Incoming, []*ast.Case: - // unhashable type. - case *ast.Function: - if w.funcScope { - // *ast.Function nodes are not traversed when staying within the scope - // *of the function. - return - } - default: - // Prevent infinite loops. - - // TODO: Check if it is enough to only track *ast.NamedType to prevent inf - // loops. - if w.visited[x] { - return - } - w.visited[x] = true - } - - before(x) - - switch n := x.(type) { - // pointers to interfaces - case *ast.MetadataNode: - w.walkBeforeAfter(*n, before, after) - case *ast.Type: - w.walkBeforeAfter(*n, before, after) - case *ast.Value: - w.walkBeforeAfter(*n, before, after) - case *ast.NamedValue: - w.walkBeforeAfter(*n, before, after) - case *ast.Constant: - w.walkBeforeAfter(*n, before, after) - case *ast.Instruction: - w.walkBeforeAfter(*n, before, after) - case *ast.Terminator: - w.walkBeforeAfter(*n, before, after) - - // pointers to struct pointers - case **ast.Global: - w.walkBeforeAfter(*n, before, after) - case **ast.Function: - w.walkBeforeAfter(*n, before, after) - case **ast.Param: - w.walkBeforeAfter(*n, before, after) - case **ast.GlobalDummy: - w.walkBeforeAfter(*n, before, after) - case **ast.LocalDummy: - w.walkBeforeAfter(*n, before, after) - case **ast.InlineAsm: - w.walkBeforeAfter(*n, before, after) - case **ast.Metadata: - w.walkBeforeAfter(*n, before, after) - case **ast.MetadataString: - w.walkBeforeAfter(*n, before, after) - case **ast.MetadataValue: - w.walkBeforeAfter(*n, before, after) - case **ast.NamedMetadata: - w.walkBeforeAfter(*n, before, after) - case **ast.MetadataIDDummy: - w.walkBeforeAfter(*n, before, after) - case **ast.AttachedMD: - w.walkBeforeAfter(*n, before, after) - // Types - case **ast.VoidType: - w.walkBeforeAfter(*n, before, after) - case **ast.FuncType: - w.walkBeforeAfter(*n, before, after) - case **ast.IntType: - w.walkBeforeAfter(*n, before, after) - case **ast.FloatType: - w.walkBeforeAfter(*n, before, after) - case **ast.PointerType: - w.walkBeforeAfter(*n, before, after) - case **ast.VectorType: - w.walkBeforeAfter(*n, before, after) - case **ast.LabelType: - w.walkBeforeAfter(*n, before, after) - case **ast.MetadataType: - w.walkBeforeAfter(*n, before, after) - case **ast.ArrayType: - w.walkBeforeAfter(*n, before, after) - case **ast.StructType: - w.walkBeforeAfter(*n, before, after) - case **ast.NamedType: - w.walkBeforeAfter(*n, before, after) - case **ast.NamedTypeDummy: - w.walkBeforeAfter(*n, before, after) - // Constants - case **ast.IntConst: - w.walkBeforeAfter(*n, before, after) - case **ast.FloatConst: - w.walkBeforeAfter(*n, before, after) - case **ast.NullConst: - w.walkBeforeAfter(*n, before, after) - case **ast.VectorConst: - w.walkBeforeAfter(*n, before, after) - case **ast.ArrayConst: - w.walkBeforeAfter(*n, before, after) - case **ast.CharArrayConst: - w.walkBeforeAfter(*n, before, after) - case **ast.StructConst: - w.walkBeforeAfter(*n, before, after) - case **ast.ZeroInitializerConst: - w.walkBeforeAfter(*n, before, after) - case **ast.UndefConst: - w.walkBeforeAfter(*n, before, after) - // Constant expressions - case **ast.ExprAdd: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFAdd: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprSub: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFSub: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprMul: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFMul: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprUDiv: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprSDiv: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFDiv: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprURem: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprSRem: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFRem: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprShl: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprLShr: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprAShr: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprAnd: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprOr: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprXor: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprExtractElement: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprInsertElement: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprShuffleVector: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprExtractValue: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprInsertValue: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprGetElementPtr: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprTrunc: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprZExt: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprSExt: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFPTrunc: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFPExt: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFPToUI: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFPToSI: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprUIToFP: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprSIToFP: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprPtrToInt: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprIntToPtr: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprBitCast: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprAddrSpaceCast: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprICmp: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprFCmp: - w.walkBeforeAfter(*n, before, after) - case **ast.ExprSelect: - w.walkBeforeAfter(*n, before, after) - // Basic blocks. - case **ast.BasicBlock: - w.walkBeforeAfter(*n, before, after) - // Instructions - case **ast.InstAdd: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFAdd: - w.walkBeforeAfter(*n, before, after) - case **ast.InstSub: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFSub: - w.walkBeforeAfter(*n, before, after) - case **ast.InstMul: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFMul: - w.walkBeforeAfter(*n, before, after) - case **ast.InstUDiv: - w.walkBeforeAfter(*n, before, after) - case **ast.InstSDiv: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFDiv: - w.walkBeforeAfter(*n, before, after) - case **ast.InstURem: - w.walkBeforeAfter(*n, before, after) - case **ast.InstSRem: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFRem: - w.walkBeforeAfter(*n, before, after) - case **ast.InstShl: - w.walkBeforeAfter(*n, before, after) - case **ast.InstLShr: - w.walkBeforeAfter(*n, before, after) - case **ast.InstAShr: - w.walkBeforeAfter(*n, before, after) - case **ast.InstAnd: - w.walkBeforeAfter(*n, before, after) - case **ast.InstOr: - w.walkBeforeAfter(*n, before, after) - case **ast.InstXor: - w.walkBeforeAfter(*n, before, after) - case **ast.InstExtractElement: - w.walkBeforeAfter(*n, before, after) - case **ast.InstInsertElement: - w.walkBeforeAfter(*n, before, after) - case **ast.InstShuffleVector: - w.walkBeforeAfter(*n, before, after) - case **ast.InstExtractValue: - w.walkBeforeAfter(*n, before, after) - case **ast.InstInsertValue: - w.walkBeforeAfter(*n, before, after) - case **ast.InstAlloca: - w.walkBeforeAfter(*n, before, after) - case **ast.InstLoad: - w.walkBeforeAfter(*n, before, after) - case **ast.InstStore: - w.walkBeforeAfter(*n, before, after) - case **ast.InstGetElementPtr: - w.walkBeforeAfter(*n, before, after) - case **ast.InstTrunc: - w.walkBeforeAfter(*n, before, after) - case **ast.InstZExt: - w.walkBeforeAfter(*n, before, after) - case **ast.InstSExt: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFPTrunc: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFPExt: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFPToUI: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFPToSI: - w.walkBeforeAfter(*n, before, after) - case **ast.InstUIToFP: - w.walkBeforeAfter(*n, before, after) - case **ast.InstSIToFP: - w.walkBeforeAfter(*n, before, after) - case **ast.InstPtrToInt: - w.walkBeforeAfter(*n, before, after) - case **ast.InstIntToPtr: - w.walkBeforeAfter(*n, before, after) - case **ast.InstBitCast: - w.walkBeforeAfter(*n, before, after) - case **ast.InstAddrSpaceCast: - w.walkBeforeAfter(*n, before, after) - case **ast.InstICmp: - w.walkBeforeAfter(*n, before, after) - case **ast.InstFCmp: - w.walkBeforeAfter(*n, before, after) - case **ast.InstPhi: - w.walkBeforeAfter(*n, before, after) - case **ast.Incoming: - w.walkBeforeAfter(*n, before, after) - case **ast.InstSelect: - w.walkBeforeAfter(*n, before, after) - case **ast.InstCall: - w.walkBeforeAfter(*n, before, after) - // Terminators - case **ast.TermRet: - w.walkBeforeAfter(*n, before, after) - case **ast.TermBr: - w.walkBeforeAfter(*n, before, after) - case **ast.TermCondBr: - w.walkBeforeAfter(*n, before, after) - case **ast.TermSwitch: - w.walkBeforeAfter(*n, before, after) - case **ast.Case: - w.walkBeforeAfter(*n, before, after) - case **ast.TermUnreachable: - w.walkBeforeAfter(*n, before, after) - - // pointers to slices - case *[]*ast.NamedMetadata: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.Metadata: - w.walkBeforeAfter(*n, before, after) - case *[]ast.MetadataNode: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.AttachedMD: - w.walkBeforeAfter(*n, before, after) - case *[]ast.Type: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.NamedType: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.Global: - w.walkBeforeAfter(*n, before, after) - case *[]ast.Value: - w.walkBeforeAfter(*n, before, after) - case *[]ast.Constant: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.Function: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.Param: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.BasicBlock: - w.walkBeforeAfter(*n, before, after) - case *[]ast.Instruction: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.Case: - w.walkBeforeAfter(*n, before, after) - case *[]*ast.Incoming: - w.walkBeforeAfter(*n, before, after) - - // These are ordered and grouped to match ../../ll.bnf - case *ast.Module: - if n.Types != nil { - w.walkBeforeAfter(&n.Types, before, after) - } - if n.Globals != nil { - w.walkBeforeAfter(&n.Globals, before, after) - } - if n.Funcs != nil { - w.walkBeforeAfter(&n.Funcs, before, after) - } - if n.NamedMetadata != nil { - w.walkBeforeAfter(&n.NamedMetadata, before, after) - } - if n.Metadata != nil { - w.walkBeforeAfter(&n.Metadata, before, after) - } - case []*ast.Global: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.Global: - w.walkBeforeAfter(&n.Content, before, after) - if n.Init != nil { - w.walkBeforeAfter(&n.Init, before, after) - } - if n.Metadata != nil { - w.walkBeforeAfter(&n.Metadata, before, after) - } - case []*ast.Function: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.Function: - w.walkBeforeAfter(&n.Sig, before, after) - if n.Blocks != nil { - w.walkBeforeAfter(&n.Blocks, before, after) - } - if n.Metadata != nil { - w.walkBeforeAfter(&n.Metadata, before, after) - } - case []*ast.Param: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.Param: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.GlobalDummy: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.LocalDummy: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.InlineAsm: - w.walkBeforeAfter(&n.Type, before, after) - case []*ast.NamedMetadata: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case []*ast.Metadata: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.NamedMetadata: - w.walkBeforeAfter(&n.Metadata, before, after) - case *ast.Metadata: - w.walkBeforeAfter(&n.Nodes, before, after) - case *ast.MetadataString: - // nothing to do. - case *ast.MetadataValue: - w.walkBeforeAfter(&n.X, before, after) - case []ast.MetadataNode: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case []*ast.AttachedMD: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.AttachedMD: - w.walkBeforeAfter(&n.Metadata, before, after) - case *ast.MetadataIDDummy: - // nothing to do. - // Types - case []ast.Type: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.TypeDummy: - // nothing to do. - case *ast.VoidType: - // nothing to do. - case *ast.FuncType: - w.walkBeforeAfter(&n.Ret, before, after) - if n.Params != nil { - w.walkBeforeAfter(&n.Params, before, after) - } - case *ast.IntType: - // nothing to do. - case *ast.FloatType: - // nothing to do. - case *ast.PointerType: - w.walkBeforeAfter(&n.Elem, before, after) - case *ast.VectorType: - w.walkBeforeAfter(&n.Elem, before, after) - case *ast.LabelType: - // nothing to do. - case *ast.MetadataType: - // nothing to do. - case *ast.ArrayType: - w.walkBeforeAfter(&n.Elem, before, after) - case *ast.StructType: - if n.Fields != nil { - w.walkBeforeAfter(&n.Fields, before, after) - } - case []*ast.NamedType: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.NamedType: - if n.Def != nil { - w.walkBeforeAfter(&n.Def, before, after) - } - case *ast.NamedTypeDummy: - // nothing to do. - // Constants - case []ast.Value: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case []ast.Constant: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.IntConst: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.FloatConst: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.NullConst: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.VectorConst: - w.walkBeforeAfter(&n.Type, before, after) - if n.Elems != nil { - w.walkBeforeAfter(&n.Elems, before, after) - } - case *ast.ArrayConst: - w.walkBeforeAfter(&n.Type, before, after) - if n.Elems != nil { - w.walkBeforeAfter(&n.Elems, before, after) - } - case *ast.CharArrayConst: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.StructConst: - w.walkBeforeAfter(&n.Type, before, after) - if n.Fields != nil { - w.walkBeforeAfter(&n.Fields, before, after) - } - case *ast.ZeroInitializerConst: - w.walkBeforeAfter(&n.Type, before, after) - case *ast.UndefConst: - w.walkBeforeAfter(&n.Type, before, after) - // Constant expressions - case *ast.ExprAdd: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprFAdd: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprSub: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprFSub: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprMul: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprFMul: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprUDiv: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprSDiv: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprFDiv: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprURem: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprSRem: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprFRem: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprShl: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprLShr: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprAShr: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprAnd: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprOr: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprXor: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprExtractElement: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Index, before, after) - case *ast.ExprInsertElement: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Elem, before, after) - w.walkBeforeAfter(&n.Index, before, after) - case *ast.ExprShuffleVector: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - w.walkBeforeAfter(&n.Mask, before, after) - case *ast.ExprExtractValue: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - case *ast.ExprInsertValue: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Elem, before, after) - case *ast.ExprGetElementPtr: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.Elem, before, after) - w.walkBeforeAfter(&n.Src, before, after) - if n.Indices != nil { - w.walkBeforeAfter(&n.Indices, before, after) - } - case *ast.ExprTrunc: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprZExt: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprSExt: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprFPTrunc: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprFPExt: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprFPToUI: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprFPToSI: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprUIToFP: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprSIToFP: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprPtrToInt: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprIntToPtr: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprBitCast: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprAddrSpaceCast: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.ExprICmp: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprFCmp: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.ExprSelect: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.Cond, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - // Basic blocks. - case []*ast.BasicBlock: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.BasicBlock: - if n.Insts != nil { - w.walkBeforeAfter(&n.Insts, before, after) - } - w.walkBeforeAfter(&n.Term, before, after) - // Instructions - case []ast.Instruction: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.InstAdd: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstFAdd: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstSub: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstFSub: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstMul: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstFMul: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstUDiv: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstSDiv: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstFDiv: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstURem: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstSRem: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstFRem: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstShl: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstLShr: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstAShr: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstAnd: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstOr: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstXor: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstExtractElement: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Index, before, after) - case *ast.InstInsertElement: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Elem, before, after) - w.walkBeforeAfter(&n.Index, before, after) - case *ast.InstShuffleVector: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - w.walkBeforeAfter(&n.Mask, before, after) - case *ast.InstExtractValue: - w.walkBeforeAfter(&n.X, before, after) - case *ast.InstInsertValue: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Elem, before, after) - case *ast.InstAlloca: - w.walkBeforeAfter(&n.Elem, before, after) - if n.NElems != nil { - w.walkBeforeAfter(&n.NElems, before, after) - } - case *ast.InstLoad: - w.walkBeforeAfter(&n.Elem, before, after) - w.walkBeforeAfter(&n.Src, before, after) - case *ast.InstStore: - w.walkBeforeAfter(&n.Src, before, after) - w.walkBeforeAfter(&n.Dst, before, after) - case *ast.InstGetElementPtr: - w.walkBeforeAfter(&n.Elem, before, after) - w.walkBeforeAfter(&n.Src, before, after) - if n.Indices != nil { - w.walkBeforeAfter(&n.Indices, before, after) - } - case *ast.InstTrunc: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstZExt: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstSExt: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstFPTrunc: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstFPExt: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstFPToUI: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstFPToSI: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstUIToFP: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstSIToFP: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstPtrToInt: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstIntToPtr: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstBitCast: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstAddrSpaceCast: - w.walkBeforeAfter(&n.From, before, after) - w.walkBeforeAfter(&n.To, before, after) - case *ast.InstICmp: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstFCmp: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstPhi: - w.walkBeforeAfter(&n.Type, before, after) - if n.Incs != nil { - w.walkBeforeAfter(&n.Incs, before, after) - } - case []*ast.Incoming: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.Incoming: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Pred, before, after) - case *ast.InstSelect: - w.walkBeforeAfter(&n.Cond, before, after) - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Y, before, after) - case *ast.InstCall: - w.walkBeforeAfter(&n.Type, before, after) - w.walkBeforeAfter(&n.Callee, before, after) - if n.Args != nil { - w.walkBeforeAfter(&n.Args, before, after) - } - // Terminators - case *ast.TermRet: - if n.X != nil { - w.walkBeforeAfter(&n.X, before, after) - } - case *ast.TermBr: - w.walkBeforeAfter(&n.Target, before, after) - case *ast.TermCondBr: - w.walkBeforeAfter(&n.Cond, before, after) - w.walkBeforeAfter(&n.TargetTrue, before, after) - w.walkBeforeAfter(&n.TargetFalse, before, after) - case *ast.TermSwitch: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.TargetDefault, before, after) - if n.Cases != nil { - w.walkBeforeAfter(&n.Cases, before, after) - } - case []*ast.Case: - for i := range n { - w.walkBeforeAfter(&n[i], before, after) - } - case *ast.Case: - w.walkBeforeAfter(&n.X, before, after) - w.walkBeforeAfter(&n.Target, before, after) - case *ast.TermUnreachable: - // nothing to do. - - default: - panic(fmt.Errorf("support for type %T not yet implemented", x)) - } - - after(x) -} diff --git a/llvm/asm/internal/ast/block.go b/llvm/asm/internal/ast/block.go deleted file mode 100755 index 95cae7e..0000000 --- a/llvm/asm/internal/ast/block.go +++ /dev/null @@ -1,26 +0,0 @@ -package ast - -// A BasicBlock represents an LLVM IR basic block, which consists of a sequence -// of non-branching instructions, terminated by a control flow instruction (e.g. -// br or ret). -type BasicBlock struct { - // Label name of the basic block; or empty if unnamed basic block. - Name string - // Non-branching instructions of the basic block. - Insts []Instruction - // Terminator of the basic block. - Term Terminator -} - -// GetName returns the name of the value. -func (block *BasicBlock) GetName() string { - return block.Name -} - -// SetName sets the name of the value. -func (block *BasicBlock) SetName(name string) { - block.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*BasicBlock) isValue() {} diff --git a/llvm/asm/internal/ast/const_complex.go b/llvm/asm/internal/ast/const_complex.go deleted file mode 100755 index d1b43a5..0000000 --- a/llvm/asm/internal/ast/const_complex.go +++ /dev/null @@ -1,62 +0,0 @@ -package ast - -// VectorConst represents a vector constant. -type VectorConst struct { - // Vector type. - Type Type - // Vector elements. - Elems []Constant -} - -// ArrayConst represents an array constant. -type ArrayConst struct { - // Array type. - Type Type - // Array elements. - Elems []Constant -} - -// CharArrayConst represents a character array constant. -type CharArrayConst struct { - // Array type. - Type Type - // Array elements. - Lit string -} - -// StructConst represents a struct constant. -type StructConst struct { - // Struct type. - Type Type - // Struct fields. - Fields []Constant -} - -// ZeroInitializerConst represents a zeroinitializer constant. -type ZeroInitializerConst struct { - // Constant type. - Type Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*VectorConst) isValue() {} -func (*ArrayConst) isValue() {} -func (*CharArrayConst) isValue() {} -func (*StructConst) isValue() {} -func (*ZeroInitializerConst) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*VectorConst) isConstant() {} -func (*ArrayConst) isConstant() {} -func (*CharArrayConst) isConstant() {} -func (*StructConst) isConstant() {} -func (*ZeroInitializerConst) isConstant() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*VectorConst) isMetadataNode() {} -func (*ArrayConst) isMetadataNode() {} -func (*CharArrayConst) isMetadataNode() {} -func (*StructConst) isMetadataNode() {} -func (*ZeroInitializerConst) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/const_simple.go b/llvm/asm/internal/ast/const_simple.go deleted file mode 100755 index de8aaa1..0000000 --- a/llvm/asm/internal/ast/const_simple.go +++ /dev/null @@ -1,40 +0,0 @@ -package ast - -// IntConst represents an integer constant. -type IntConst struct { - // Integer type. - Type Type - // Constant literal value. - Lit string -} - -// FloatConst represents a floating-point constant. -type FloatConst struct { - // Floating-point type. - Type Type - // Constant literal value. - Lit string -} - -// NullConst represents a null pointer constant. -type NullConst struct { - // Pointer type. - Type Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*IntConst) isValue() {} -func (*FloatConst) isValue() {} -func (*NullConst) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*IntConst) isConstant() {} -func (*FloatConst) isConstant() {} -func (*NullConst) isConstant() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*IntConst) isMetadataNode() {} -func (*FloatConst) isMetadataNode() {} -func (*NullConst) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/const_undef.go b/llvm/asm/internal/ast/const_undef.go deleted file mode 100755 index afa8305..0000000 --- a/llvm/asm/internal/ast/const_undef.go +++ /dev/null @@ -1,18 +0,0 @@ -package ast - -// UndefConst represents an undef constant. -type UndefConst struct { - // Constant type. - Type Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*UndefConst) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*UndefConst) isConstant() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*UndefConst) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/constant.go b/llvm/asm/internal/ast/constant.go deleted file mode 100755 index 92f29ec..0000000 --- a/llvm/asm/internal/ast/constant.go +++ /dev/null @@ -1,44 +0,0 @@ -package ast - -// A Constant represents an LLVM IR constant; a value that is immutable at -// runtime, such as an integer or a floating point literal. -// -// Constant may have one of the following underlying types. -// -// Simple constants -// -// http://llvm.org/docs/LangRef.html#simple-constants -// -// *ast.IntConst -// *ast.FloatConst -// *ast.NullConst -// -// Complex constants -// -// http://llvm.org/docs/LangRef.html#complex-constants -// -// *ast.VectorConst -// *ast.ArrayConst -// *ast.StructConst -// *ast.ZeroInitializerConst -// -// Global variable and function addresses -// -// *ast.Global -// *ast.Function -// -// Undefined value constants -// -// *ast.UndefConst -// -// Constant expressions -// -// http://llvm.org/docs/LangRef.html#constant-expressions -// -// ast.ConstExpr -type Constant interface { - Value - // isConstant ensures that only constants can be assigned to the ast.Constant - // interface. - isConstant() -} diff --git a/llvm/asm/internal/ast/expr_aggregate.go b/llvm/asm/internal/ast/expr_aggregate.go deleted file mode 100755 index 41ea5de..0000000 --- a/llvm/asm/internal/ast/expr_aggregate.go +++ /dev/null @@ -1,57 +0,0 @@ -// === [ Aggregate expressions ] =============================================== -// -// References: -// http://llvm.org/docs/LangRef.html#aggregate-operations - -package ast - -// --- [ extractvalue ] ------------------------------------------------------ - -// ExprExtractValue represents an extractvalue expression. -// -// References: -// http://llvm.org/docs/LangRef.html#extractvalue-instruction -type ExprExtractValue struct { - // Type of the constant expression. - Type Type - // Aggregate constant. - X Constant - // Indices. - Indices []int64 -} - -// --- [ insertvalue ] ------------------------------------------------------- - -// ExprInsertValue represents an insertvalue expression. -// -// References: -// http://llvm.org/docs/LangRef.html#insertvalue-instruction -type ExprInsertValue struct { - // Type of the constant expression. - Type Type - // Aggregate constant. - X Constant - // Element to insert. - Elem Constant - // Indices. - Indices []int64 -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprExtractValue) isValue() {} -func (*ExprInsertValue) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprExtractValue) isConstant() {} -func (*ExprInsertValue) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprExtractValue) isConstExpr() {} -func (*ExprInsertValue) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprExtractValue) isMetadataNode() {} -func (*ExprInsertValue) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expr_binary.go b/llvm/asm/internal/ast/expr_binary.go deleted file mode 100755 index 1722b91..0000000 --- a/llvm/asm/internal/ast/expr_binary.go +++ /dev/null @@ -1,344 +0,0 @@ -// generated by gen.go using 'go generate'; DO NOT EDIT. - -// === [ Binary expressions ] ================================================== -// -// References: -// http://llvm.org/docs/LangRef.html#binary-operations - -package ast - -// --- [ add ] ----------------------------------------------------------------- - -// ExprAdd represents an addition expression. -// -// References: -// http://llvm.org/docs/LangRef.html#add-instruction -type ExprAdd struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprAdd) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprAdd) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprAdd) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprAdd) isMetadataNode() {} - -// --- [ fadd ] ---------------------------------------------------------------- - -// ExprFAdd represents a floating-point addition expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fadd-instruction -type ExprFAdd struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFAdd) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFAdd) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFAdd) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFAdd) isMetadataNode() {} - -// --- [ sub ] ----------------------------------------------------------------- - -// ExprSub represents a subtraction expression. -// -// References: -// http://llvm.org/docs/LangRef.html#sub-instruction -type ExprSub struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprSub) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprSub) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprSub) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprSub) isMetadataNode() {} - -// --- [ fsub ] ---------------------------------------------------------------- - -// ExprFSub represents a floating-point subtraction expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fsub-instruction -type ExprFSub struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFSub) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFSub) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFSub) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFSub) isMetadataNode() {} - -// --- [ mul ] ----------------------------------------------------------------- - -// ExprMul represents a multiplication expression. -// -// References: -// http://llvm.org/docs/LangRef.html#mul-instruction -type ExprMul struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprMul) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprMul) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprMul) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprMul) isMetadataNode() {} - -// --- [ fmul ] ---------------------------------------------------------------- - -// ExprFMul represents a floating-point multiplication expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fmul-instruction -type ExprFMul struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFMul) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFMul) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFMul) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFMul) isMetadataNode() {} - -// --- [ udiv ] ---------------------------------------------------------------- - -// ExprUDiv represents an unsigned division expression. -// -// References: -// http://llvm.org/docs/LangRef.html#udiv-instruction -type ExprUDiv struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprUDiv) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprUDiv) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprUDiv) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprUDiv) isMetadataNode() {} - -// --- [ sdiv ] ---------------------------------------------------------------- - -// ExprSDiv represents a signed division expression. -// -// References: -// http://llvm.org/docs/LangRef.html#sdiv-instruction -type ExprSDiv struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprSDiv) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprSDiv) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprSDiv) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprSDiv) isMetadataNode() {} - -// --- [ fdiv ] ---------------------------------------------------------------- - -// ExprFDiv represents a floating-point division expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fdiv-instruction -type ExprFDiv struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFDiv) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFDiv) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFDiv) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFDiv) isMetadataNode() {} - -// --- [ urem ] ---------------------------------------------------------------- - -// ExprURem represents an unsigned remainder expression. -// -// References: -// http://llvm.org/docs/LangRef.html#urem-instruction -type ExprURem struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprURem) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprURem) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprURem) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprURem) isMetadataNode() {} - -// --- [ srem ] ---------------------------------------------------------------- - -// ExprSRem represents a signed remainder expression. -// -// References: -// http://llvm.org/docs/LangRef.html#srem-instruction -type ExprSRem struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprSRem) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprSRem) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprSRem) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprSRem) isMetadataNode() {} - -// --- [ frem ] ---------------------------------------------------------------- - -// ExprFRem represents a floating-point remainder expression. -// -// References: -// http://llvm.org/docs/LangRef.html#frem-instruction -type ExprFRem struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFRem) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFRem) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFRem) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFRem) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expr_binary.tmpl b/llvm/asm/internal/ast/expr_binary.tmpl deleted file mode 100755 index db0f054..0000000 --- a/llvm/asm/internal/ast/expr_binary.tmpl +++ /dev/null @@ -1,38 +0,0 @@ -// generated by gen.go using 'go generate'; DO NOT EDIT. - -// {{ h1 .Desc }} -// -// References: -// {{ .URL }} - -package ast - -{{- range .Insts }} -// {{ lower .Name | h2 }} - -// Expr{{ .Name }} represents {{ .Desc }} expression. -// -// References: -// http://llvm.org/docs/LangRef.html#{{ lower .Name }}-instruction -type Expr{{ .Name }} struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Expr{{ .Name }}) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*Expr{{ .Name }}) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*Expr{{ .Name }}) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*Expr{{ .Name }}) isMetadataNode() {} -{{- end }} diff --git a/llvm/asm/internal/ast/expr_bitwise.go b/llvm/asm/internal/ast/expr_bitwise.go deleted file mode 100755 index 4b9ec9d..0000000 --- a/llvm/asm/internal/ast/expr_bitwise.go +++ /dev/null @@ -1,176 +0,0 @@ -// generated by gen.go using 'go generate'; DO NOT EDIT. - -// === [ Bitwise expressions ] ================================================= -// -// References: -// http://llvm.org/docs/LangRef.html#bitwise-binary-operations - -package ast - -// --- [ shl ] ----------------------------------------------------------------- - -// ExprShl represents a shift left expression. -// -// References: -// http://llvm.org/docs/LangRef.html#shl-instruction -type ExprShl struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprShl) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprShl) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprShl) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprShl) isMetadataNode() {} - -// --- [ lshr ] ---------------------------------------------------------------- - -// ExprLShr represents a logical shift right expression. -// -// References: -// http://llvm.org/docs/LangRef.html#lshr-instruction -type ExprLShr struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprLShr) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprLShr) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprLShr) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprLShr) isMetadataNode() {} - -// --- [ ashr ] ---------------------------------------------------------------- - -// ExprAShr represents an arithmetic shift right expression. -// -// References: -// http://llvm.org/docs/LangRef.html#ashr-instruction -type ExprAShr struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprAShr) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprAShr) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprAShr) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprAShr) isMetadataNode() {} - -// --- [ and ] ----------------------------------------------------------------- - -// ExprAnd represents an AND expression. -// -// References: -// http://llvm.org/docs/LangRef.html#and-instruction -type ExprAnd struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprAnd) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprAnd) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprAnd) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprAnd) isMetadataNode() {} - -// --- [ or ] ------------------------------------------------------------------ - -// ExprOr represents an OR expression. -// -// References: -// http://llvm.org/docs/LangRef.html#or-instruction -type ExprOr struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprOr) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprOr) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprOr) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprOr) isMetadataNode() {} - -// --- [ xor ] ----------------------------------------------------------------- - -// ExprXor represents an exclusive-OR expression. -// -// References: -// http://llvm.org/docs/LangRef.html#xor-instruction -type ExprXor struct { - // Type of the constant expression. - Type Type - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprXor) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprXor) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprXor) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprXor) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expr_conversion.go b/llvm/asm/internal/ast/expr_conversion.go deleted file mode 100755 index b88f00b..0000000 --- a/llvm/asm/internal/ast/expr_conversion.go +++ /dev/null @@ -1,398 +0,0 @@ -// generated by gen.go using 'go generate'; DO NOT EDIT. - -// === [ Conversion expressions ] ============================================== -// -// References: -// http://llvm.org/docs/LangRef.html#conversion-operations - -package ast - -// --- [ trunc ] --------------------------------------------------------------- - -// ExprTrunc represents a truncation expression. -// -// References: -// http://llvm.org/docs/LangRef.html#trunc-instruction -type ExprTrunc struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprTrunc) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprTrunc) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprTrunc) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprTrunc) isMetadataNode() {} - -// --- [ zext ] ---------------------------------------------------------------- - -// ExprZExt represents a zero extension expression. -// -// References: -// http://llvm.org/docs/LangRef.html#zext-instruction -type ExprZExt struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprZExt) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprZExt) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprZExt) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprZExt) isMetadataNode() {} - -// --- [ sext ] ---------------------------------------------------------------- - -// ExprSExt represents a sign extension expression. -// -// References: -// http://llvm.org/docs/LangRef.html#sext-instruction -type ExprSExt struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprSExt) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprSExt) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprSExt) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprSExt) isMetadataNode() {} - -// --- [ fptrunc ] ------------------------------------------------------------- - -// ExprFPTrunc represents a floating-point truncation expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fptrunc-instruction -type ExprFPTrunc struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFPTrunc) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFPTrunc) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFPTrunc) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFPTrunc) isMetadataNode() {} - -// --- [ fpext ] --------------------------------------------------------------- - -// ExprFPExt represents a floating-point extension expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fpext-instruction -type ExprFPExt struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFPExt) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFPExt) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFPExt) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFPExt) isMetadataNode() {} - -// --- [ fptoui ] -------------------------------------------------------------- - -// ExprFPToUI represents a floating-point to unsigned integer conversion expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fptoui-instruction -type ExprFPToUI struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFPToUI) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFPToUI) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFPToUI) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFPToUI) isMetadataNode() {} - -// --- [ fptosi ] -------------------------------------------------------------- - -// ExprFPToSI represents a floating-point to signed integer conversion expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fptosi-instruction -type ExprFPToSI struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprFPToSI) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprFPToSI) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprFPToSI) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprFPToSI) isMetadataNode() {} - -// --- [ uitofp ] -------------------------------------------------------------- - -// ExprUIToFP represents an unsigned integer to floating-point conversion expression. -// -// References: -// http://llvm.org/docs/LangRef.html#uitofp-instruction -type ExprUIToFP struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprUIToFP) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprUIToFP) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprUIToFP) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprUIToFP) isMetadataNode() {} - -// --- [ sitofp ] -------------------------------------------------------------- - -// ExprSIToFP represents a signed integer to floating-point conversion expression. -// -// References: -// http://llvm.org/docs/LangRef.html#sitofp-instruction -type ExprSIToFP struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprSIToFP) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprSIToFP) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprSIToFP) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprSIToFP) isMetadataNode() {} - -// --- [ ptrtoint ] ------------------------------------------------------------ - -// ExprPtrToInt represents a pointer to integer conversion expression. -// -// References: -// http://llvm.org/docs/LangRef.html#ptrtoint-instruction -type ExprPtrToInt struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprPtrToInt) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprPtrToInt) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprPtrToInt) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprPtrToInt) isMetadataNode() {} - -// --- [ inttoptr ] ------------------------------------------------------------ - -// ExprIntToPtr represents an integer to pointer conversion expression. -// -// References: -// http://llvm.org/docs/LangRef.html#inttoptr-instruction -type ExprIntToPtr struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprIntToPtr) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprIntToPtr) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprIntToPtr) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprIntToPtr) isMetadataNode() {} - -// --- [ bitcast ] ------------------------------------------------------------- - -// ExprBitCast represents a bitcast expression. -// -// References: -// http://llvm.org/docs/LangRef.html#bitcast-instruction -type ExprBitCast struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprBitCast) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprBitCast) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprBitCast) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprBitCast) isMetadataNode() {} - -// --- [ addrspacecast ] ------------------------------------------------------- - -// ExprAddrSpaceCast represents an address space cast expression. -// -// References: -// http://llvm.org/docs/LangRef.html#addrspacecast-instruction -type ExprAddrSpaceCast struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprAddrSpaceCast) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprAddrSpaceCast) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprAddrSpaceCast) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprAddrSpaceCast) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expr_conversion.tmpl b/llvm/asm/internal/ast/expr_conversion.tmpl deleted file mode 100755 index e413460..0000000 --- a/llvm/asm/internal/ast/expr_conversion.tmpl +++ /dev/null @@ -1,40 +0,0 @@ -// generated by gen.go using 'go generate'; DO NOT EDIT. - -// {{ h1 .Desc }} -// -// References: -// {{ .URL }} - -package ast - -{{- range .Insts }} -// {{ lower .Name | h2 }} - -// Expr{{ .Name }} represents {{ .Desc }} expression. -// -// References: -// http://llvm.org/docs/LangRef.html#{{ lower .Name }}-instruction -type Expr{{ .Name }} struct { - // Type of the constant expression. - Type Type - // Constant before conversion. - From Constant - // Type after conversion. - To Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Expr{{ .Name }}) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*Expr{{ .Name }}) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*Expr{{ .Name }}) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*Expr{{ .Name }}) isMetadataNode() {} -{{- end }} diff --git a/llvm/asm/internal/ast/expr_memory.go b/llvm/asm/internal/ast/expr_memory.go deleted file mode 100755 index bfffd09..0000000 --- a/llvm/asm/internal/ast/expr_memory.go +++ /dev/null @@ -1,38 +0,0 @@ -// === [ Memory expressions ] ================================================== -// -// References: -// http://llvm.org/docs/LangRef.html#memory-access-and-addressing-operations - -package ast - -// --- [ getelementptr ] ------------------------------------------------------- - -// ExprGetElementPtr represents a getelementptr expression. -// -// References: -// http://llvm.org/docs/LangRef.html#getelementptr-instruction -type ExprGetElementPtr struct { - // Type of the constant expression. - Type Type - // Source address element type. - Elem Type - // Source address. - Src Constant - // Element indices. - Indices []Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprGetElementPtr) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprGetElementPtr) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprGetElementPtr) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprGetElementPtr) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expr_other.go b/llvm/asm/internal/ast/expr_other.go deleted file mode 100755 index 1748b3f..0000000 --- a/llvm/asm/internal/ast/expr_other.go +++ /dev/null @@ -1,163 +0,0 @@ -// === [ Other expressions ] =================================================== -// -// References: -// http://llvm.org/docs/LangRef.html#other-operations - -package ast - -import "fmt" - -// --- [ icmp ] ---------------------------------------------------------------- - -// ExprICmp represents an icmp expression. -// -// References: -// http://llvm.org/docs/LangRef.html#icmp-instruction -type ExprICmp struct { - // Type of the constant expression. - Type Type - // Integer predicate. - Pred IntPred - // Operands. - X, Y Constant -} - -// IntPred represents the set of integer predicate of the icmp expression. -type IntPred int - -// Integer predicates. -const ( - IntEQ IntPred = iota + 1 // eq: equal - IntNE // ne: not equal - IntUGT // ugt: unsigned greater than - IntUGE // uge: unsigned greater than or equal - IntULT // ult: unsigned less than - IntULE // ule: unsigned less than or equal - IntSGT // sgt: signed greater than - IntSGE // sge: signed greater than or equal - IntSLT // slt: signed less than - IntSLE // sle: signed less than or equal -) - -// String returns the LLVM syntax representation of the integer predicate. -func (pred IntPred) String() string { - m := map[IntPred]string{ - IntEQ: "eq", - IntNE: "ne", - IntUGT: "ugt", - IntUGE: "uge", - IntULT: "ult", - IntULE: "ule", - IntSGT: "sgt", - IntSGE: "sge", - IntSLT: "slt", - IntSLE: "sle", - } - if s, ok := m[pred]; ok { - return s - } - return fmt.Sprintf("", int(pred)) -} - -// --- [ fcmp ] ---------------------------------------------------------------- - -// ExprFCmp represents an fcmp expression. -// -// References: -// http://llvm.org/docs/LangRef.html#fcmp-instruction -type ExprFCmp struct { - // Type of the constant expression. - Type Type - // Floating-point predicate. - Pred FloatPred - // Operands. - X, Y Constant -} - -// FloatPred represents the set of predicates of the fcmp expression. -type FloatPred int - -// Floating-point predicates. -const ( - FloatFalse FloatPred = iota + 1 // false: no comparison, always returns false - FloatOEQ // oeq: ordered and equal - FloatOGT // ogt: ordered and greater than - FloatOGE // oge: ordered and greater than or equal - FloatOLT // olt: ordered and less than - FloatOLE // ole: ordered and less than or equal - FloatONE // one: ordered and not equal - FloatORD // ord: ordered (no nans) - FloatUEQ // ueq: unordered or equal - FloatUGT // ugt: unordered or greater than - FloatUGE // uge: unordered or greater than or equal - FloatULT // ult: unordered or less than - FloatULE // ule: unordered or less than or equal - FloatUNE // une: unordered or not equal - FloatUNO // uno: unordered (either nans) - FloatTrue // true: no comparison, always returns true -) - -// String returns the LLVM syntax representation of the floating-point -// predicate. -func (pred FloatPred) String() string { - m := map[FloatPred]string{ - FloatFalse: "false", - FloatOEQ: "oeq", - FloatOGT: "ogt", - FloatOGE: "oge", - FloatOLT: "olt", - FloatOLE: "ole", - FloatONE: "one", - FloatORD: "ord", - FloatUEQ: "ueq", - FloatUGT: "ugt", - FloatUGE: "uge", - FloatULT: "ult", - FloatULE: "ule", - FloatUNE: "une", - FloatUNO: "uno", - FloatTrue: "true", - } - if s, ok := m[pred]; ok { - return s - } - return fmt.Sprintf("", int(pred)) -} - -// --- [ select ] -------------------------------------------------------------- - -// ExprSelect represents a select expression. -// -// References: -// http://llvm.org/docs/LangRef.html#select-instruction -type ExprSelect struct { - // Type of the constant expression. - Type Type - // Selection condition. - Cond Constant - // Operands. - X, Y Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprICmp) isValue() {} -func (*ExprFCmp) isValue() {} -func (*ExprSelect) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprICmp) isConstant() {} -func (*ExprFCmp) isConstant() {} -func (*ExprSelect) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprICmp) isConstExpr() {} -func (*ExprFCmp) isConstExpr() {} -func (*ExprSelect) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprICmp) isMetadataNode() {} -func (*ExprFCmp) isMetadataNode() {} -func (*ExprSelect) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expr_vector.go b/llvm/asm/internal/ast/expr_vector.go deleted file mode 100755 index 7ace661..0000000 --- a/llvm/asm/internal/ast/expr_vector.go +++ /dev/null @@ -1,78 +0,0 @@ -// === [ Vector expressions ] ================================================== -// -// References: -// http://llvm.org/docs/LangRef.html#vector-operations - -package ast - -// --- [ extractelement ] ------------------------------------------------------ - -// ExprExtractElement represents an extractelement expression. -// -// References: -// http://llvm.org/docs/LangRef.html#extractelement-instruction -type ExprExtractElement struct { - // Type of the constant expression. - Type Type - // Vector. - X Constant - // Index. - Index Constant -} - -// --- [ insertelement ] ------------------------------------------------------- - -// ExprInsertElement represents an insertelement expression. -// -// References: -// http://llvm.org/docs/LangRef.html#insertelement-instruction -type ExprInsertElement struct { - // Type of the constant expression. - Type Type - // Vector. - X Constant - // Element to insert. - Elem Constant - // Index. - Index Constant -} - -// --- [ shufflevector ] ------------------------------------------------------- - -// ExprShuffleVector represents a shufflevector expression. -// -// References: -// http://llvm.org/docs/LangRef.html#shufflevector-instruction -type ExprShuffleVector struct { - // Type of the constant expression. - Type Type - // Vector 1. - X Constant - // Vector 2. - Y Constant - // Shuffle mask. - Mask Constant -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*ExprExtractElement) isValue() {} -func (*ExprInsertElement) isValue() {} -func (*ExprShuffleVector) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*ExprExtractElement) isConstant() {} -func (*ExprInsertElement) isConstant() {} -func (*ExprShuffleVector) isConstant() {} - -// isConstExpr ensures that only constant expressions can be assigned to the -// ast.ConstExpr interface. -func (*ExprExtractElement) isConstExpr() {} -func (*ExprInsertElement) isConstExpr() {} -func (*ExprShuffleVector) isConstExpr() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*ExprExtractElement) isMetadataNode() {} -func (*ExprInsertElement) isMetadataNode() {} -func (*ExprShuffleVector) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/expression.go b/llvm/asm/internal/ast/expression.go deleted file mode 100755 index 6c1ecc9..0000000 --- a/llvm/asm/internal/ast/expression.go +++ /dev/null @@ -1,86 +0,0 @@ -package ast - -// A ConstExpr represents an LLVM IR constant expression. -// -// ConstExpr may have one of the following underlying types. -// -// Binary expressions -// -// http://llvm.org/docs/LangRef.html#binary-operations -// -// *ast.ExprAdd -// *ast.ExprFAdd -// *ast.ExprSub -// *ast.ExprFSub -// *ast.ExprMul -// *ast.ExprFMul -// *ast.ExprUDiv -// *ast.ExprSDiv -// *ast.ExprFDiv -// *ast.ExprURem -// *ast.ExprSRem -// *ast.ExprFRem -// -// Bitwise expressions -// -// http://llvm.org/docs/LangRef.html#bitwise-binary-operations -// -// *ast.ExprShl -// *ast.ExprLShr -// *ast.ExprAShr -// *ast.ExprAnd -// *ast.ExprOr -// *ast.ExprXor -// -// Vector expressions -// -// http://llvm.org/docs/LangRef.html#vector-operations -// -// *ast.ExprExtractElement -// *ast.ExprInsertElement -// *ast.ExprShuffleVector -// -// Aggregate expressions -// -// http://llvm.org/docs/LangRef.html#aggregate-operations -// -// *ast.ExprExtractValue -// *ast.ExprInsertValue -// -// Memory expressions -// -// http://llvm.org/docs/LangRef.html#memory-access-and-addressing-operations -// -// *ast.ExprGetElementPtr -// -// Conversion expressions -// -// http://llvm.org/docs/LangRef.html#conversion-operations -// -// *ast.ExprTrunc -// *ast.ExprZExt -// *ast.ExprSExt -// *ast.ExprFPTrunc -// *ast.ExprFPExt -// *ast.ExprFPToUI -// *ast.ExprFPToSI -// *ast.ExprUIToFP -// *ast.ExprSIToFP -// *ast.ExprPtrToInt -// *ast.ExprIntToPtr -// *ast.ExprBitCast -// *ast.ExprAddrSpaceCast -// -// Other expressions -// -// http://llvm.org/docs/LangRef.html#other-operations -// -// *ast.ExprICmp -// *ast.ExprFCmp -// *ast.ExprSelect -type ConstExpr interface { - Constant - // isConstExpr ensures that only constant expressions can be assigned to the - // ast.ConstExpr interface. - isConstExpr() -} diff --git a/llvm/asm/internal/ast/function.go b/llvm/asm/internal/ast/function.go deleted file mode 100755 index 6efaf42..0000000 --- a/llvm/asm/internal/ast/function.go +++ /dev/null @@ -1,166 +0,0 @@ -package ast - -import ( - "fmt" - "strconv" - "strings" - - "github.com/geode-lang/geode/llvm/enc" -) - -// A Function represents an LLVM IR function definition or external function -// declaration. The body of a function definition consists of a set of basic -// blocks, interconnected by control flow instructions. -type Function struct { - // Function name. - Name string - // Function signature. - Sig *FuncType - // Calling convention. - CallConv CallConv - // Basic blocks of the function; or nil if defined externally. - Blocks []*BasicBlock - // Metadata attached to the function. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (f *Function) GetName() string { - return f.Name -} - -// SetName sets the name of the value. -func (f *Function) SetName(name string) { - f.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Function) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*Function) isConstant() {} - -// AssignIDs assigns unique local IDs to unnamed basic blocks and local -// variables of the function. -func (f *Function) AssignIDs() { - id := 0 - setName := func(n NamedValue) { - name := n.GetName() - switch { - case isUnnamed(name): - n.SetName(strconv.Itoa(id)) - id++ - case isID(name): - want := strconv.Itoa(id) - if name != want { - panic(fmt.Errorf("invalid local ID in function %s; expected %s, got %s", enc.Global(f.Name), enc.Local(want), enc.Local(name))) - } - id++ - } - } - for _, param := range f.Sig.Params { - // Assign local IDs to unnamed parameters of function definitions. - if len(f.Blocks) > 0 { - setName(param) - } - } - for _, block := range f.Blocks { - // Assign local IDs to unnamed basic blocks. - setName(block) - for _, inst := range block.Insts { - n, ok := inst.(NamedValue) - if !ok { - continue - } - if inst, ok := inst.(*InstCall); ok { - if _, ok := inst.Type.(*VoidType); ok { - continue - } - if sig, ok := inst.Type.(*FuncType); ok { - if _, ok := sig.Ret.(*VoidType); ok { - continue - } - } - } - // Assign local IDs to unnamed local variables. - setName(n) - } - } -} - -// isUnnamed reports whether the given identifier is unnamed. -func isUnnamed(name string) bool { - return len(name) == 0 -} - -// isID reports whether the given identifier is an ID (e.g. "%42"). -func isID(name string) bool { - for _, r := range name { - if strings.IndexRune("0123456789", r) == -1 { - return false - } - } - return len(name) > 0 -} - -// CallConv represents the set of calling conventions. -type CallConv uint - -// TODO: Change calling convention enums to match the Haskell LLVM library. - -// Calling conventions. -const ( - CallConvNone CallConv = iota // no calling convention specified. - CallConvAMDGPU_CS // amdgpu_cs - CallConvAMDGPU_GS // amdgpu_gs - CallConvAMDGPU_Kernel // amdgpu_kernel - CallConvAMDGPU_PS // amdgpu_ps - CallConvAMDGPU_VS // amdgpu_vs - CallConvAnyReg // anyregcc - CallConvARM_AAPCS // arm_aapcscc - CallConvARM_AAPCS_VFP // arm_aapcs_vfpcc - CallConvARM_APCS // arm_apcscc - CallConvAVR_Builtin // cc 86 - CallConvAVR_Intr // avr_intrcc - CallConvAVR_Signal // avr_signalcc - CallConvC // ccc - CallConvCold // coldcc - CallConvCXX_Fast_TLS // cxx_fast_tlscc - CallConvFast // fastcc - CallConvGHC // ghccc - CallConvHHVM // hhvmcc - CallConvHHVM_C // hhvm_ccc - CallConvHiPE // cc 11 - CallConvIntel_OCL_BI // intel_ocl_bicc - CallConvMSP430_Intr // msp430_intrcc - CallConvPreserveAll // preserve_allcc - CallConvPreserveMost // preserve_mostcc - CallConvPTX_Device // ptx_device - CallConvPTX_Kernel // ptx_kernel - CallConvSPIR_Func // spir_func - CallConvSPIR_Kernel // spir_kernel - CallConvSwift // swiftcc - CallConvWebKit_JS // webkit_jscc - CallConvX86_64_SysV // x86_64_sysvcc - CallConvX86_64_Win64 // x86_64_win64cc - CallConvX86_FastCall // x86_fastcallcc - CallConvX86_Intr // x86_intrcc - CallConvX86_RegCall // x86_regcallcc - CallConvX86_StdCall // x86_stdcallcc - CallConvX86_ThisCall // x86_thiscallcc - CallConvX86_VectorCall // x86_vectorcallcc -) - -// InlineAsm represents an inline assembly statement. -type InlineAsm struct { - // Assembly instructions. - Asm string - // Comma-separated list of constraints. - Constraints string - // Function signature or return type of the inline assembly. - Type Type -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InlineAsm) isValue() {} diff --git a/llvm/asm/internal/ast/gen.go b/llvm/asm/internal/ast/gen.go deleted file mode 100755 index 286fbeb..0000000 --- a/llvm/asm/internal/ast/gen.go +++ /dev/null @@ -1,268 +0,0 @@ -//+build ignore - -// gen.go generates the data representations of binary, bitwise and conversion -// instructions and constant expressions. -package main - -import ( - "bytes" - "fmt" - "go/format" - "html/template" - "io/ioutil" - "log" - "path/filepath" - "strings" - - "github.com/pkg/errors" -) - -func main() { - binaryInsts := []*Instruction{ - { - Name: "Add", - Desc: "an addition", - }, - { - Name: "FAdd", - Desc: "a floating-point addition", - }, - { - Name: "Sub", - Desc: "a subtraction", - }, - { - Name: "FSub", - Desc: "a floating-point subtraction", - }, - { - Name: "Mul", - Desc: "a multiplication", - }, - { - Name: "FMul", - Desc: "a floating-point multiplication", - }, - { - Name: "UDiv", - Desc: "an unsigned division", - }, - { - Name: "SDiv", - Desc: "a signed division", - }, - { - Name: "FDiv", - Desc: "a floating-point division", - }, - { - Name: "URem", - Desc: "an unsigned remainder", - }, - { - Name: "SRem", - Desc: "a signed remainder", - }, - { - Name: "FRem", - Desc: "a floating-point remainder", - }, - } - bitwiseInsts := []*Instruction{ - { - Name: "Shl", - Desc: "a shift left", - }, - { - Name: "LShr", - Desc: "a logical shift right", - }, - { - Name: "AShr", - Desc: "an arithmetic shift right", - }, - { - Name: "And", - Desc: "an AND", - }, - { - Name: "Or", - Desc: "an OR", - }, - { - Name: "Xor", - Desc: "an exclusive-OR", - }, - } - conversionInsts := []*Instruction{ - { - Name: "Trunc", - Desc: "a truncation", - }, - { - Name: "ZExt", - Desc: "a zero extension", - }, - { - Name: "SExt", - Desc: "a sign extension", - }, - { - Name: "FPTrunc", - Desc: "a floating-point truncation", - }, - { - Name: "FPExt", - Desc: "a floating-point extension", - }, - { - Name: "FPToUI", - Desc: "a floating-point to unsigned integer conversion", - }, - { - Name: "FPToSI", - Desc: "a floating-point to signed integer conversion", - }, - { - Name: "UIToFP", - Desc: "an unsigned integer to floating-point conversion", - }, - { - Name: "SIToFP", - Desc: "a signed integer to floating-point conversion", - }, - { - Name: "PtrToInt", - Desc: "a pointer to integer conversion", - }, - { - Name: "IntToPtr", - Desc: "an integer to pointer conversion", - }, - { - Name: "BitCast", - Desc: "a bitcast", - }, - { - Name: "AddrSpaceCast", - Desc: "an address space cast", - }, - } - files := []*File{ - // Instructions. - { - Template: "inst_binary.tmpl", - Path: "inst_binary.go", - Desc: "Binary instructions", - URL: "http://llvm.org/docs/LangRef.html#binary-operations", - Insts: binaryInsts, - }, - { - Template: "inst_binary.tmpl", - Path: "inst_bitwise.go", - Desc: "Bitwise instructions", - URL: "http://llvm.org/docs/LangRef.html#bitwise-binary-operations", - Insts: bitwiseInsts, - }, - { - Template: "inst_conversion.tmpl", - Path: "inst_conversion.go", - Desc: "Conversion instructions", - URL: "http://llvm.org/docs/LangRef.html#conversion-operations", - Insts: conversionInsts, - }, - // Constant expressions. - { - Template: "expr_binary.tmpl", - Path: "expr_binary.go", - Desc: "Binary expressions", - URL: "http://llvm.org/docs/LangRef.html#binary-operations", - Insts: binaryInsts, - }, - { - Template: "expr_binary.tmpl", - Path: "expr_bitwise.go", - Desc: "Bitwise expressions", - URL: "http://llvm.org/docs/LangRef.html#bitwise-binary-operations", - Insts: bitwiseInsts, - }, - { - Template: "expr_conversion.tmpl", - Path: "expr_conversion.go", - Desc: "Conversion expressions", - URL: "http://llvm.org/docs/LangRef.html#conversion-operations", - Insts: conversionInsts, - }, - } - for _, file := range files { - if err := file.gen(); err != nil { - log.Fatalf("%+v", err) - } - } -} - -// A File represents a source file containing the instructions of a given -// category. -type File struct { - // Template path. - Template string - // File path. - Path string - // Instruction category description; e.g. `Binary instructions`. - Desc string - // URL to the corresponding section of the LLVM IR Language Reference Manual. - URL string - // Instructions. - Insts []*Instruction -} - -// An Instruction represents an LLVM IR instruction. -type Instruction struct { - // CamelCased instruction name; e.g. `ShL`. - Name string - // Instruction description; e.g. `a shift left`. - Desc string -} - -// gen generates a source file containing the instructions of the given -// category. -func (f *File) gen() error { - t := template.New(filepath.Base(f.Template)) - funcs := map[string]interface{}{ - "lower": strings.ToLower, - "h1": h1, - "h2": h2, - } - t.Funcs(funcs) - if _, err := t.ParseFiles(f.Template); err != nil { - return errors.WithStack(err) - } - buf := new(bytes.Buffer) - if err := t.Execute(buf, f); err != nil { - return errors.WithStack(err) - } - src, err := format.Source(buf.Bytes()) - if err != nil { - return errors.WithStack(err) - } - if err := ioutil.WriteFile(f.Path, src, 0644); err != nil { - return errors.WithStack(err) - } - return nil -} - -// header returns a header based on the given title and underline character. -func header(title string, c rune) string { - pad := 80 - len("// ") - len("=== [ ] ") - len(title) - return fmt.Sprintf("%s [ %s ] %s", strings.Repeat(string(c), 3), title, strings.Repeat(string(c), pad)) -} - -// h1 returns a level 1 header based on the given title. -func h1(title string) string { - return header(title, '=') -} - -// h2 returns a level 2 header based on the given title. -func h2(title string) string { - return header(title, '-') -} diff --git a/llvm/asm/internal/ast/global.go b/llvm/asm/internal/ast/global.go deleted file mode 100755 index 5e05cbf..0000000 --- a/llvm/asm/internal/ast/global.go +++ /dev/null @@ -1,60 +0,0 @@ -package ast - -// A Global represents an LLVM IR global variable definition or external global -// variable declaration. -type Global struct { - // Global variable name. - Name string - // Content type. - Content Type - // Initial value; or nil if defined externally. - Init Constant - // Immutability of the global variable. - Immutable bool - // Address space; or 0 for default address space. - AddrSpace int - // Metadata attached to the global variable. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (global *Global) GetName() string { - return global.Name -} - -// SetName sets the name of the value. -func (global *Global) SetName(name string) { - global.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Global) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*Global) isConstant() {} - -// GlobalDummy represents a dummy global identifier. -type GlobalDummy struct { - // Global name. - Name string - // Type associated with the global. - Type Type -} - -// GetName returns the name of the value. -func (global *GlobalDummy) GetName() string { - return global.Name -} - -// SetName sets the name of the value. -func (global *GlobalDummy) SetName(name string) { - global.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*GlobalDummy) isValue() {} - -// isConstant ensures that only constants can be assigned to the ast.Constant -// interface. -func (*GlobalDummy) isConstant() {} diff --git a/llvm/asm/internal/ast/inst_aggregate.go b/llvm/asm/internal/ast/inst_aggregate.go deleted file mode 100755 index 1979cc2..0000000 --- a/llvm/asm/internal/ast/inst_aggregate.go +++ /dev/null @@ -1,76 +0,0 @@ -// === [ Aggregate instructions ] ============================================== -// -// References: -// http://llvm.org/docs/LangRef.html#aggregate-operations - -package ast - -// --- [ extractvalue ] ------------------------------------------------------ - -// InstExtractValue represents an extractvalue instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#extractvalue-instruction -type InstExtractValue struct { - // Name of the local variable associated with the instruction. - Name string - // Aggregate value. - X Value - // Indices. - Indices []int64 - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstExtractValue) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstExtractValue) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstExtractValue) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstExtractValue) isInst() {} - -// --- [ insertvalue ] ------------------------------------------------------- - -// InstInsertValue represents an insertvalue instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#insertvalue-instruction -type InstInsertValue struct { - // Name of the local variable associated with the instruction. - Name string - // Aggregate value. - X Value - // Element to insert. - Elem Value - // Indices. - Indices []int64 - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstInsertValue) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstInsertValue) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstInsertValue) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstInsertValue) isInst() {} diff --git a/llvm/asm/internal/ast/inst_binary.go b/llvm/asm/internal/ast/inst_binary.go deleted file mode 100755 index f251411..0000000 --- a/llvm/asm/internal/ast/inst_binary.go +++ /dev/null @@ -1,392 +0,0 @@ -// Code generated by gen.go using 'go generate'; DO NOT EDIT. - -// === [ Binary instructions ] ================================================= -// -// References: -// http://llvm.org/docs/LangRef.html#binary-operations - -package ast - -// --- [ add ] ----------------------------------------------------------------- - -// InstAdd represents an addition instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#add-instruction -type InstAdd struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstAdd) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstAdd) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstAdd) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstAdd) isInst() {} - -// --- [ fadd ] ---------------------------------------------------------------- - -// InstFAdd represents a floating-point addition instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fadd-instruction -type InstFAdd struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFAdd) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFAdd) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFAdd) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFAdd) isInst() {} - -// --- [ sub ] ----------------------------------------------------------------- - -// InstSub represents a subtraction instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#sub-instruction -type InstSub struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstSub) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstSub) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstSub) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstSub) isInst() {} - -// --- [ fsub ] ---------------------------------------------------------------- - -// InstFSub represents a floating-point subtraction instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fsub-instruction -type InstFSub struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFSub) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFSub) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFSub) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFSub) isInst() {} - -// --- [ mul ] ----------------------------------------------------------------- - -// InstMul represents a multiplication instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#mul-instruction -type InstMul struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstMul) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstMul) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstMul) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstMul) isInst() {} - -// --- [ fmul ] ---------------------------------------------------------------- - -// InstFMul represents a floating-point multiplication instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fmul-instruction -type InstFMul struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFMul) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFMul) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFMul) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFMul) isInst() {} - -// --- [ udiv ] ---------------------------------------------------------------- - -// InstUDiv represents an unsigned division instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#udiv-instruction -type InstUDiv struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstUDiv) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstUDiv) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstUDiv) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstUDiv) isInst() {} - -// --- [ sdiv ] ---------------------------------------------------------------- - -// InstSDiv represents a signed division instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#sdiv-instruction -type InstSDiv struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstSDiv) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstSDiv) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstSDiv) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstSDiv) isInst() {} - -// --- [ fdiv ] ---------------------------------------------------------------- - -// InstFDiv represents a floating-point division instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fdiv-instruction -type InstFDiv struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFDiv) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFDiv) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFDiv) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFDiv) isInst() {} - -// --- [ urem ] ---------------------------------------------------------------- - -// InstURem represents an unsigned remainder instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#urem-instruction -type InstURem struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstURem) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstURem) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstURem) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstURem) isInst() {} - -// --- [ srem ] ---------------------------------------------------------------- - -// InstSRem represents a signed remainder instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#srem-instruction -type InstSRem struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstSRem) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstSRem) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstSRem) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstSRem) isInst() {} - -// --- [ frem ] ---------------------------------------------------------------- - -// InstFRem represents a floating-point remainder instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#frem-instruction -type InstFRem struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFRem) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFRem) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFRem) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFRem) isInst() {} diff --git a/llvm/asm/internal/ast/inst_binary.tmpl b/llvm/asm/internal/ast/inst_binary.tmpl deleted file mode 100755 index 409f0c1..0000000 --- a/llvm/asm/internal/ast/inst_binary.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -// Code generated by gen.go using 'go generate'; DO NOT EDIT. - -// {{ h1 .Desc }} -// -// References: -// {{ .URL }} - -package ast - -{{- range .Insts }} -// {{ lower .Name | h2 }} - -// Inst{{ .Name }} represents {{ .Desc }} instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#{{ lower .Name }}-instruction -type Inst{{ .Name }} struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *Inst{{ .Name }}) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *Inst{{ .Name }}) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Inst{{ .Name }}) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*Inst{{ .Name }}) isInst() {} -{{- end }} diff --git a/llvm/asm/internal/ast/inst_bitwise.go b/llvm/asm/internal/ast/inst_bitwise.go deleted file mode 100755 index 00a8391..0000000 --- a/llvm/asm/internal/ast/inst_bitwise.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by gen.go using 'go generate'; DO NOT EDIT. - -// === [ Bitwise instructions ] ================================================ -// -// References: -// http://llvm.org/docs/LangRef.html#bitwise-binary-operations - -package ast - -// --- [ shl ] ----------------------------------------------------------------- - -// InstShl represents a shift left instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#shl-instruction -type InstShl struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstShl) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstShl) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstShl) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstShl) isInst() {} - -// --- [ lshr ] ---------------------------------------------------------------- - -// InstLShr represents a logical shift right instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#lshr-instruction -type InstLShr struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstLShr) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstLShr) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstLShr) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstLShr) isInst() {} - -// --- [ ashr ] ---------------------------------------------------------------- - -// InstAShr represents an arithmetic shift right instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#ashr-instruction -type InstAShr struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstAShr) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstAShr) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstAShr) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstAShr) isInst() {} - -// --- [ and ] ----------------------------------------------------------------- - -// InstAnd represents an AND instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#and-instruction -type InstAnd struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstAnd) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstAnd) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstAnd) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstAnd) isInst() {} - -// --- [ or ] ------------------------------------------------------------------ - -// InstOr represents an OR instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#or-instruction -type InstOr struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstOr) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstOr) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstOr) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstOr) isInst() {} - -// --- [ xor ] ----------------------------------------------------------------- - -// InstXor represents an exclusive-OR instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#xor-instruction -type InstXor struct { - // Name of the local variable associated with the instruction. - Name string - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstXor) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstXor) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstXor) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstXor) isInst() {} diff --git a/llvm/asm/internal/ast/inst_conversion.go b/llvm/asm/internal/ast/inst_conversion.go deleted file mode 100755 index 7066b87..0000000 --- a/llvm/asm/internal/ast/inst_conversion.go +++ /dev/null @@ -1,450 +0,0 @@ -// Code generated by gen.go using 'go generate'; DO NOT EDIT. - -// === [ Conversion instructions ] ============================================= -// -// References: -// http://llvm.org/docs/LangRef.html#conversion-operations - -package ast - -// --- [ trunc ] --------------------------------------------------------------- - -// InstTrunc represents a truncation instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#trunc-instruction -type InstTrunc struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstTrunc) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstTrunc) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstTrunc) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstTrunc) isInst() {} - -// --- [ zext ] ---------------------------------------------------------------- - -// InstZExt represents a zero extension instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#zext-instruction -type InstZExt struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstZExt) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstZExt) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstZExt) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstZExt) isInst() {} - -// --- [ sext ] ---------------------------------------------------------------- - -// InstSExt represents a sign extension instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#sext-instruction -type InstSExt struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstSExt) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstSExt) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstSExt) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstSExt) isInst() {} - -// --- [ fptrunc ] ------------------------------------------------------------- - -// InstFPTrunc represents a floating-point truncation instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fptrunc-instruction -type InstFPTrunc struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFPTrunc) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFPTrunc) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFPTrunc) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFPTrunc) isInst() {} - -// --- [ fpext ] --------------------------------------------------------------- - -// InstFPExt represents a floating-point extension instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fpext-instruction -type InstFPExt struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFPExt) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFPExt) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFPExt) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFPExt) isInst() {} - -// --- [ fptoui ] -------------------------------------------------------------- - -// InstFPToUI represents a floating-point to unsigned integer conversion instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fptoui-instruction -type InstFPToUI struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFPToUI) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFPToUI) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFPToUI) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFPToUI) isInst() {} - -// --- [ fptosi ] -------------------------------------------------------------- - -// InstFPToSI represents a floating-point to signed integer conversion instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fptosi-instruction -type InstFPToSI struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFPToSI) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFPToSI) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstFPToSI) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstFPToSI) isInst() {} - -// --- [ uitofp ] -------------------------------------------------------------- - -// InstUIToFP represents an unsigned integer to floating-point conversion instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#uitofp-instruction -type InstUIToFP struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstUIToFP) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstUIToFP) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstUIToFP) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstUIToFP) isInst() {} - -// --- [ sitofp ] -------------------------------------------------------------- - -// InstSIToFP represents a signed integer to floating-point conversion instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#sitofp-instruction -type InstSIToFP struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstSIToFP) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstSIToFP) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstSIToFP) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstSIToFP) isInst() {} - -// --- [ ptrtoint ] ------------------------------------------------------------ - -// InstPtrToInt represents a pointer to integer conversion instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#ptrtoint-instruction -type InstPtrToInt struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstPtrToInt) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstPtrToInt) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstPtrToInt) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstPtrToInt) isInst() {} - -// --- [ inttoptr ] ------------------------------------------------------------ - -// InstIntToPtr represents an integer to pointer conversion instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#inttoptr-instruction -type InstIntToPtr struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstIntToPtr) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstIntToPtr) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstIntToPtr) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstIntToPtr) isInst() {} - -// --- [ bitcast ] ------------------------------------------------------------- - -// InstBitCast represents a bitcast instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#bitcast-instruction -type InstBitCast struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstBitCast) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstBitCast) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstBitCast) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstBitCast) isInst() {} - -// --- [ addrspacecast ] ------------------------------------------------------- - -// InstAddrSpaceCast represents an address space cast instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#addrspacecast-instruction -type InstAddrSpaceCast struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstAddrSpaceCast) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstAddrSpaceCast) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstAddrSpaceCast) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstAddrSpaceCast) isInst() {} diff --git a/llvm/asm/internal/ast/inst_conversion.tmpl b/llvm/asm/internal/ast/inst_conversion.tmpl deleted file mode 100755 index c5085f7..0000000 --- a/llvm/asm/internal/ast/inst_conversion.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by gen.go using 'go generate'; DO NOT EDIT. - -// {{ h1 .Desc }} -// -// References: -// {{ .URL }} - -package ast - -{{- range .Insts }} -// {{ lower .Name | h2 }} - -// Inst{{ .Name }} represents {{ .Desc }} instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#{{ lower .Name }}-instruction -type Inst{{ .Name }} struct { - // Name of the local variable associated with the instruction. - Name string - // Value before conversion. - From Value - // Type after conversion. - To Type - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *Inst{{ .Name }}) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *Inst{{ .Name }}) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Inst{{ .Name }}) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*Inst{{ .Name }}) isInst() {} -{{- end }} diff --git a/llvm/asm/internal/ast/inst_memory.go b/llvm/asm/internal/ast/inst_memory.go deleted file mode 100755 index afe7a19..0000000 --- a/llvm/asm/internal/ast/inst_memory.go +++ /dev/null @@ -1,123 +0,0 @@ -// === [ Memory instructions ] ================================================= -// -// References: -// http://llvm.org/docs/LangRef.html#memory-access-and-addressing-operations - -package ast - -// --- [ alloca ] -------------------------------------------------------------- - -// InstAlloca represents an alloca instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#alloca-instruction -type InstAlloca struct { - // Name of the local variable associated with the instruction. - Name string - // Element type. - Elem Type - // Number of elements; or nil if one element. - NElems Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstAlloca) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstAlloca) SetName(name string) { - inst.Name = name -} - -// --- [ load ] ---------------------------------------------------------------- - -// InstLoad represents a load instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#load-instruction -type InstLoad struct { - // Name of the local variable associated with the instruction. - Name string - // Element type. - Elem Type - // Source address. - Src Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstLoad) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstLoad) SetName(name string) { - inst.Name = name -} - -// --- [ store ] --------------------------------------------------------------- - -// InstStore represents a store instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#store-instruction -type InstStore struct { - // Source value. - Src Value - // Destination address. - Dst Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// --- [ fence ] --------------------------------------------------------------- - -// --- [ cmpxchg ] ------------------------------------------------------------- - -// --- [ atomicrmw ] ----------------------------------------------------------- - -// --- [ getelementptr ] ------------------------------------------------------- - -// InstGetElementPtr represents a getelementptr instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#getelementptr-instruction -type InstGetElementPtr struct { - // Name of the local variable associated with the instruction. - Name string - // Source address element type. - Elem Type - // Source address. - Src Value - // Element indices. - Indices []Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstGetElementPtr) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstGetElementPtr) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstAlloca) isValue() {} -func (*InstLoad) isValue() {} -func (*InstStore) isValue() {} -func (*InstGetElementPtr) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstAlloca) isInst() {} -func (*InstLoad) isInst() {} -func (*InstStore) isInst() {} -func (*InstGetElementPtr) isInst() {} diff --git a/llvm/asm/internal/ast/inst_other.go b/llvm/asm/internal/ast/inst_other.go deleted file mode 100755 index 25b75dc..0000000 --- a/llvm/asm/internal/ast/inst_other.go +++ /dev/null @@ -1,176 +0,0 @@ -// === [ Other instructions ] ================================================== -// -// References: -// http://llvm.org/docs/LangRef.html#other-operations - -package ast - -// --- [ icmp ] ---------------------------------------------------------------- - -// InstICmp represents an icmp instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#icmp-instruction -type InstICmp struct { - // Name of the local variable associated with the instruction. - Name string - // Integer predicate. - Pred IntPred - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstICmp) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstICmp) SetName(name string) { - inst.Name = name -} - -// --- [ fcmp ] ---------------------------------------------------------------- - -// InstFCmp represents an fcmp instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#fcmp-instruction -type InstFCmp struct { - // Name of the local variable associated with the instruction. - Name string - // Floating-point predicate. - Pred FloatPred - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstFCmp) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstFCmp) SetName(name string) { - inst.Name = name -} - -// --- [ phi ] ----------------------------------------------------------------- - -// InstPhi represents a phi instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#phi-instruction -type InstPhi struct { - // Name of the local variable associated with the instruction. - Name string - // Type of the instruction. - Type Type - // Incoming values. - Incs []*Incoming - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstPhi) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstPhi) SetName(name string) { - inst.Name = name -} - -// Incoming represents an incoming value of a phi instruction. -type Incoming struct { - // Incoming value. - X Value - // Predecessor basic block of the incoming value. - Pred NamedValue -} - -// --- [ select ] -------------------------------------------------------------- - -// InstSelect represents a select instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#select-instruction -type InstSelect struct { - // Name of the local variable associated with the instruction. - Name string - // Selection condition. - Cond Value - // Operands. - X, Y Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstSelect) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstSelect) SetName(name string) { - inst.Name = name -} - -// --- [ call ] ---------------------------------------------------------------- - -// InstCall represents a call instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#call-instruction -type InstCall struct { - // Name of the local variable associated with the instruction. - Name string - // Type of the instruction; or callee type signature. - Type Type - // Callee. - Callee Value - // Function arguments. - Args []Value - // Calling convention. - CallConv CallConv - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstCall) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstCall) SetName(name string) { - inst.Name = name -} - -// --- [ va_arg ] -------------------------------------------------------------- - -// --- [ landingpad ] ---------------------------------------------------------- - -// --- [ catchpad ] ------------------------------------------------------------ - -// --- [ cleanuppad ] ---------------------------------------------------------- - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstICmp) isValue() {} -func (*InstFCmp) isValue() {} -func (*InstPhi) isValue() {} -func (*InstSelect) isValue() {} -func (*InstCall) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstICmp) isInst() {} -func (*InstFCmp) isInst() {} -func (*InstPhi) isInst() {} -func (*InstSelect) isInst() {} -func (*InstCall) isInst() {} diff --git a/llvm/asm/internal/ast/inst_vector.go b/llvm/asm/internal/ast/inst_vector.go deleted file mode 100755 index 29bab19..0000000 --- a/llvm/asm/internal/ast/inst_vector.go +++ /dev/null @@ -1,112 +0,0 @@ -// === [ Vector instructions ] ================================================= -// -// References: -// http://llvm.org/docs/LangRef.html#vector-operations - -package ast - -// --- [ extractelement ] ------------------------------------------------------ - -// InstExtractElement represents an extractelement instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#extractelement-instruction -type InstExtractElement struct { - // Name of the local variable associated with the instruction. - Name string - // Vector. - X Value - // Index. - Index Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstExtractElement) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstExtractElement) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstExtractElement) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstExtractElement) isInst() {} - -// --- [ insertelement ] ------------------------------------------------------- - -// InstInsertElement represents an insertelement instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#insertelement-instruction -type InstInsertElement struct { - // Name of the local variable associated with the instruction. - Name string - // Vector. - X Value - // Element to insert. - Elem Value - // Index. - Index Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstInsertElement) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstInsertElement) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstInsertElement) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstInsertElement) isInst() {} - -// --- [ shufflevector ] ------------------------------------------------------- - -// InstShuffleVector represents a shufflevector instruction. -// -// References: -// http://llvm.org/docs/LangRef.html#shufflevector-instruction -type InstShuffleVector struct { - // Name of the local variable associated with the instruction. - Name string - // Vector 1. - X Value - // Vector 2. - Y Value - // Shuffle mask. - Mask Value - // Metadata attached to the instruction. - Metadata []*AttachedMD -} - -// GetName returns the name of the value. -func (inst *InstShuffleVector) GetName() string { - return inst.Name -} - -// SetName sets the name of the value. -func (inst *InstShuffleVector) SetName(name string) { - inst.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*InstShuffleVector) isValue() {} - -// isInst ensures that only instructions can be assigned to the ast.Instruction -// interface. -func (*InstShuffleVector) isInst() {} diff --git a/llvm/asm/internal/ast/instruction.go b/llvm/asm/internal/ast/instruction.go deleted file mode 100755 index bb47a16..0000000 --- a/llvm/asm/internal/ast/instruction.go +++ /dev/null @@ -1,90 +0,0 @@ -package ast - -// An Instruction represents a non-branching LLVM IR instruction. -// -// Instruction may have one of the following underlying types. -// -// Binary instructions -// -// http://llvm.org/docs/LangRef.html#binary-operations -// -// *ast.InstAdd -// *ast.InstFAdd -// *ast.InstSub -// *ast.InstFSub -// *ast.InstMul -// *ast.InstFMul -// *ast.InstUDiv -// *ast.InstSDiv -// *ast.InstFDiv -// *ast.InstURem -// *ast.InstSRem -// *ast.InstFRem -// -// Bitwise instructions -// -// http://llvm.org/docs/LangRef.html#bitwise-binary-operations -// -// *ast.InstShl -// *ast.InstLShr -// *ast.InstAShr -// *ast.InstAnd -// *ast.InstOr -// *ast.InstXor -// -// Vector instructions -// -// http://llvm.org/docs/LangRef.html#vector-operations -// -// *ast.InstExtractElement -// *ast.InstInsertElement -// *ast.InstShuffleVector -// -// Aggregate instructions -// -// http://llvm.org/docs/LangRef.html#aggregate-operations -// -// *ast.InstExtractValue -// *ast.InstInsertValue -// -// Memory instructions -// -// http://llvm.org/docs/LangRef.html#memory-access-and-addressing-operations -// -// *ast.InstAlloca -// *ast.InstLoad -// *ast.InstStore -// *ast.InstGetElementPtr -// -// Conversion instructions -// -// http://llvm.org/docs/LangRef.html#conversion-operations -// -// *ast.InstTrunc -// *ast.InstZExt -// *ast.InstSExt -// *ast.InstFPTrunc -// *ast.InstFPExt -// *ast.InstFPToUI -// *ast.InstFPToSI -// *ast.InstUIToFP -// *ast.InstSIToFP -// *ast.InstPtrToInt -// *ast.InstIntToPtr -// *ast.InstBitCast -// *ast.InstAddrSpaceCast -// -// Other instructions -// -// http://llvm.org/docs/LangRef.html#other-operations -// -// *ast.InstICmp -// *ast.InstFCmp -// *ast.InstPhi -// *ast.InstSelect -// *ast.InstCall -type Instruction interface { - // isInst ensures that only instructions can be assigned to the - // ast.Instruction interface. - isInst() -} diff --git a/llvm/asm/internal/ast/local.go b/llvm/asm/internal/ast/local.go deleted file mode 100755 index 0c5e0b6..0000000 --- a/llvm/asm/internal/ast/local.go +++ /dev/null @@ -1,22 +0,0 @@ -package ast - -// LocalDummy represents a dummy local identifier. -type LocalDummy struct { - // Local name. - Name string - // Type associated with the localIdent. - Type Type -} - -// GetName returns the name of the value. -func (local *LocalDummy) GetName() string { - return local.Name -} - -// SetName sets the name of the value. -func (local *LocalDummy) SetName(name string) { - local.Name = name -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*LocalDummy) isValue() {} diff --git a/llvm/asm/internal/ast/metadata.go b/llvm/asm/internal/ast/metadata.go deleted file mode 100755 index 8ca5910..0000000 --- a/llvm/asm/internal/ast/metadata.go +++ /dev/null @@ -1,98 +0,0 @@ -// === [ Metadata ] ============================================================ -// -// References: -// http://llvm.org/docs/LangRef.html#metadata - -package ast - -// A MetadataNode represents an LLVM IR metadata node. -// -// MetadataNode may have one of the following underlying types. -// -// *ast.Metadata -// *ast.MetadataString -// *ast.MetadataValue -// ast.Constant -type MetadataNode interface { - Value - // isMetadataNode ensures that only metadata nodes can be assigned to the - // ast.MetadataNode interface. - isMetadataNode() -} - -// --- [ metadata ] ------------------------------------------------------------ - -// Metadata represents a set of LLVM IR metadata nodes. -// -// Metadata may be referenced from instructions (e.g. call), and are thus -// considered LLVM IR values of metadata type. -type Metadata struct { - // Metadata ID; or empty if metadata literal. - ID string - // Metadata nodes. - Nodes []MetadataNode -} - -// --- [ metadata string ] ----------------------------------------------------- - -// A MetadataString represents an LLVM IR metadata string. -type MetadataString struct { - // String value. - Val string -} - -// --- [ metadata value ] ------------------------------------------------------ - -// A MetadataValue represents an LLVM IR metadata value. -type MetadataValue struct { - // Value. - X Value -} - -// --- [ named metadata ] ------------------------------------------------------ - -// NamedMetadata represents a named collection of metadata, which belongs to a -// module. -type NamedMetadata struct { - // Metadata name. - Name string - // Associated metadata; initially *ast.MetadataIDDummy and replaced with - // corresponding *ast.Metadata by astx.fixModule. - Metadata []MetadataNode -} - -// AttachedMD represents attached metadata. -type AttachedMD struct { - // Name associated with the attached metadata (e.g. !dbg). - Name string - // Metadata; may be *ast.MetadataIDDummy or *ast.Metadata during translation, - // *ast.MetadataIDDummy are later replaced with corresponding *ast.Metadata - // by astx.fixModule. - Metadata MetadataNode -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Metadata) isValue() {} -func (*MetadataString) isValue() {} -func (*MetadataValue) isValue() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*Metadata) isMetadataNode() {} -func (*MetadataString) isMetadataNode() {} -func (*MetadataValue) isMetadataNode() {} - -// ### [ dummy ] ############################################################### - -// MetadataIDDummy represents a dummy metadata ID. -type MetadataIDDummy struct { - // Metadata ID. - ID string -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*MetadataIDDummy) isValue() {} - -// isMetadataNode ensures that only metadata nodes can be assigned to the -// ast.MetadataNode interface. -func (*MetadataIDDummy) isMetadataNode() {} diff --git a/llvm/asm/internal/ast/module.go b/llvm/asm/internal/ast/module.go deleted file mode 100755 index d83c4b4..0000000 --- a/llvm/asm/internal/ast/module.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:generate go run gen.go - -// Package ast declares the types used to represent abstract syntax trees of -// LLVM IR modules. -package ast - -// A Module represents an LLVM IR module, which consists of top-level type -// definitions, global variables, functions, and metadata. -type Module struct { - // Data layout. - DataLayout string - // Target triple. - TargetTriple string - // Type definitions. - Types []*NamedType - // Global variables of the module. - Globals []*Global - // Functions of the module. - Funcs []*Function - // Named metadata of the module. - NamedMetadata []*NamedMetadata - // Metadata of the module. - Metadata []*Metadata -} diff --git a/llvm/asm/internal/ast/terminator.go b/llvm/asm/internal/ast/terminator.go deleted file mode 100755 index 160069f..0000000 --- a/llvm/asm/internal/ast/terminator.go +++ /dev/null @@ -1,119 +0,0 @@ -package ast - -// A Terminator represents an LLVM IR terminator. -// -// Terminator may have one of the following underlying types. -// -// Terminators -// -// http://llvm.org/docs/LangRef.html#terminator-instructions -// -// *ast.TermRet -// *ast.TermBr -// *ast.TermCondBr -// *ast.TermSwitch -// *ast.TermUnreachable -type Terminator interface { - // isTerm ensures that only terminators can be assigned to the ast.Terminator - // interface. - isTerm() -} - -// --- [ ret ] ----------------------------------------------------------------- - -// TermRet represents a ret terminator. -// -// References: -// http://llvm.org/docs/LangRef.html#ret-instruction -type TermRet struct { - // Return value; or nil if "void" return. - X Value - // Metadata attached to the terminator. - Metadata []*AttachedMD -} - -// --- [ br ] ------------------------------------------------------------------ - -// TermBr represents an unconditional br terminator. -// -// References: -// http://llvm.org/docs/LangRef.html#br-instruction -type TermBr struct { - // Target branch. - Target NamedValue - // Metadata attached to the terminator. - Metadata []*AttachedMD -} - -// --- [ conditional br ] ------------------------------------------------------ - -// TermCondBr represents a conditional br terminator. -// -// References: -// http://llvm.org/docs/LangRef.html#br-instruction -type TermCondBr struct { - // Branching condition. - Cond Value - // Target branch when condition is true. - TargetTrue NamedValue - // Target branch when condition is false. - TargetFalse NamedValue - // Metadata attached to the terminator. - Metadata []*AttachedMD -} - -// --- [ switch ] -------------------------------------------------------------- - -// TermSwitch represents a switch terminator. -// -// References: -// http://llvm.org/docs/LangRef.html#switch-instruction -type TermSwitch struct { - // Control variable. - X Value - // Default target branch. - TargetDefault NamedValue - // Switch cases. - Cases []*Case - // Metadata attached to the terminator. - Metadata []*AttachedMD -} - -// Case represents a case of a switch terminator. -type Case struct { - // Case comparand. - X *IntConst - // Case target branch. - Target NamedValue -} - -// --- [ indirectbr ] ---------------------------------------------------------- - -// --- [ invoke ] -------------------------------------------------------------- - -// --- [ resume ] -------------------------------------------------------------- - -// --- [ catchswitch ] --------------------------------------------------------- - -// --- [ catchret ] ------------------------------------------------------------ - -// --- [ cleanupret ] ---------------------------------------------------------- - -// --- [ unreachable ] --------------------------------------------------------- - -// TermUnreachable represents an unreachable terminator. -// -// References: -// http://llvm.org/docs/LangRef.html#unreachable-instruction -type TermUnreachable struct { - // Metadata attached to the terminator. - Metadata []*AttachedMD -} - -// isTerm ensures that only terminators can be assigned to the ast.Terminator -// interface. -func (*TermRet) isTerm() {} -func (*TermBr) isTerm() {} -func (*TermCondBr) isTerm() {} -func (*TermSwitch) isTerm() {} -func (*TermUnreachable) isTerm() {} diff --git a/llvm/asm/internal/ast/type_aggregate.go b/llvm/asm/internal/ast/type_aggregate.go deleted file mode 100755 index 18cefad..0000000 --- a/llvm/asm/internal/ast/type_aggregate.go +++ /dev/null @@ -1,34 +0,0 @@ -package ast - -// --- [ array ] --------------------------------------------------------------- - -// ArrayType represents an array type. -// -// References: -// http://llvm.org/docs/LangRef.html#array-type -type ArrayType struct { - // Element type. - Elem Type - // Array length. - Len int64 -} - -// --- [ struct ] -------------------------------------------------------------- - -// StructType represents a struct type. -// -// References: -// http://llvm.org/docs/LangRef.html#structure-type -type StructType struct { - // Struct fields. - Fields []Type - // Opaque struct type. - // - // References: - // http://llvm.org/docs/LangRef.html#opaque-structure-types - Opaque bool -} - -// isType ensures that only types can be assigned to the ast.Type interface. -func (*ArrayType) isType() {} -func (*StructType) isType() {} diff --git a/llvm/asm/internal/ast/type_named.go b/llvm/asm/internal/ast/type_named.go deleted file mode 100755 index cdc2cd6..0000000 --- a/llvm/asm/internal/ast/type_named.go +++ /dev/null @@ -1,27 +0,0 @@ -package ast - -// NamedType represents the type definition of a type alias or an identified -// struct type. -type NamedType struct { - // Type name. - Name string - // Type definition. - Def Type -} - -// GetName returns the name of the type. -func (t *NamedType) GetName() string { - return t.Name -} - -// isType ensures that only types can be assigned to the ast.Type interface. -func (*NamedType) isType() {} - -// NamedTypeDummy represents a dummy type identifier. -type NamedTypeDummy struct { - // Type name. - Name string -} - -// isType ensures that only types can be assigned to the ast.Type interface. -func (*NamedTypeDummy) isType() {} diff --git a/llvm/asm/internal/ast/type_other.go b/llvm/asm/internal/ast/type_other.go deleted file mode 100755 index d0464c4..0000000 --- a/llvm/asm/internal/ast/type_other.go +++ /dev/null @@ -1,70 +0,0 @@ -package ast - -// --- [ void ] ---------------------------------------------------------------- - -// VoidType represents a void type. -// -// References: -// http://llvm.org/docs/LangRef.html#void-type -type VoidType struct { -} - -// --- [ function ] ------------------------------------------------------------ - -// FuncType represents a function type. -// -// References: -// http://llvm.org/docs/LangRef.html#function-type -type FuncType struct { - // Return type. - Ret Type - // Function parameters. - Params []*Param - // Variadicity of the function type. - Variadic bool -} - -// A Param represents an LLVM IR function parameter. -type Param struct { - // Parameter name. - Name string - // Parameter type. - Type Type -} - -// GetName returns the name of the value. -func (param *Param) GetName() string { - return param.Name -} - -// SetName sets the name of the value. -func (param *Param) SetName(name string) { - param.Name = name -} - -// --- [ label ] --------------------------------------------------------------- - -// LabelType represents a label type, which is used for basic block values. -// -// References: -// http://llvm.org/docs/LangRef.html#label-type -type LabelType struct { -} - -// --- [ metadata ] ------------------------------------------------------------ - -// MetadataType represents a metadata type. -// -// References: -// http://llvm.org/docs/LangRef.html#metadata-type -type MetadataType struct { -} - -// isValue ensures that only values can be assigned to the ast.Value interface. -func (*Param) isValue() {} - -// isType ensures that only types can be assigned to the ast.Type interface. -func (*VoidType) isType() {} -func (*FuncType) isType() {} -func (*LabelType) isType() {} -func (*MetadataType) isType() {} diff --git a/llvm/asm/internal/ast/type_single.go b/llvm/asm/internal/ast/type_single.go deleted file mode 100755 index 5f0bcc6..0000000 --- a/llvm/asm/internal/ast/type_single.go +++ /dev/null @@ -1,89 +0,0 @@ -package ast - -import "fmt" - -// --- [ integer ] ------------------------------------------------------------- - -// IntType represents an integer type. -// -// References: -// http://llvm.org/docs/LangRef.html#integer-type -type IntType struct { - // Bit size. - Size int -} - -// --- [ floating-point ] ------------------------------------------------------ - -// FloatType represents a floating-point type. -// -// References: -// http://llvm.org/docs/LangRef.html#floating-point-types -type FloatType struct { - // Floating-point kind. - Kind FloatKind -} - -// FloatKind represents the set of floating-point kinds. -type FloatKind int - -// Floating point kinds. -const ( - FloatKindIEEE_16 FloatKind = iota // half: 16-bit floating point type - FloatKindIEEE_32 // float: 32-bit floating point type - FloatKindIEEE_64 // double: 64-bit floating point type - FloatKindIEEE_128 // fp128: 128-bit floating point type (112-bit mantissa) - FloatKindDoubleExtended_80 // x86_fp80: 80-bit floating point type (x87) - FloatKindDoubleDouble_128 // ppc_fp128: 128-bit floating point type (two 64-bits, PowerPC) -) - -// String returns the LLVM syntax representation of the floating-point kind. -func (kind FloatKind) String() string { - switch kind { - case FloatKindIEEE_16: - return "half" - case FloatKindIEEE_32: - return "float" - case FloatKindIEEE_64: - return "double" - case FloatKindIEEE_128: - return "fp128" - case FloatKindDoubleExtended_80: - return "x86_fp80" - case FloatKindDoubleDouble_128: - return "ppc_fp128" - } - return fmt.Sprintf("", int(kind)) -} - -// --- [ pointer ] ------------------------------------------------------------- - -// PointerType represents a pointer type. -// -// References: -// http://llvm.org/docs/LangRef.html#pointer-type -type PointerType struct { - // Element type. - Elem Type - // Address space; or 0 for default address space. - AddrSpace int -} - -// --- [ vector ] -------------------------------------------------------------- - -// VectorType represents a vector type. -// -// References: -// http://llvm.org/docs/LangRef.html#vector-type -type VectorType struct { - // Element type. - Elem Type - // Vector length. - Len int64 -} - -// isType ensures that only types can be assigned to the ast.Type interface. -func (*IntType) isType() {} -func (*FloatType) isType() {} -func (*PointerType) isType() {} -func (*VectorType) isType() {} diff --git a/llvm/asm/internal/ast/types.go b/llvm/asm/internal/ast/types.go deleted file mode 100755 index b9035b3..0000000 --- a/llvm/asm/internal/ast/types.go +++ /dev/null @@ -1,31 +0,0 @@ -package ast - -// A Type represents an LLVM IR type. -// -// Type may have one of the following underlying types. -// -// *ast.VoidType -// *ast.FuncType -// *ast.IntType -// *ast.FloatType -// *ast.PointerType -// *ast.VectorType -// *ast.LabelType -// *ast.MetadataType -// *ast.ArrayType -// *ast.StructType -// *ast.NamedType -// *ast.NamedTypeDummy -// *ast.TypeDummy -type Type interface { - // isType ensures that only types can be assigned to the ast.Type interface. - isType() -} - -// TypeDummy represents a dummy type; used when a type is unknown during -// parsing. -type TypeDummy struct { -} - -// isType ensures that only types can be assigned to the ast.Type interface. -func (*TypeDummy) isType() {} diff --git a/llvm/asm/internal/ast/value.go b/llvm/asm/internal/ast/value.go deleted file mode 100755 index ec51e0a..0000000 --- a/llvm/asm/internal/ast/value.go +++ /dev/null @@ -1,33 +0,0 @@ -package ast - -// A Value represents an LLVM IR value, which may be used as an operand of -// instructions and terminators. -// -// Value may have one of the following underlying types. -// -// ast.Constant -// ast.NamedValue -type Value interface { - // isValue ensures that only values can be assigned to the ast.Value - // interface. - isValue() -} - -// NamedValue represents a named LLVM IR value. -// -// NamedValue may have one of the following underlying types. -// -// *ast.Global -// *ast.GlobalDummy -// *ast.Function -// *ast.Param -// *ast.BasicBlock -// *ast.LocalDummy -// ast.Instruction -type NamedValue interface { - Value - // GetName returns the name of the value. - GetName() string - // SetName sets the name of the value. - SetName(name string) -} diff --git a/llvm/asm/internal/astx/asm_test.go b/llvm/asm/internal/astx/asm_test.go deleted file mode 100755 index 3e385a8..0000000 --- a/llvm/asm/internal/astx/asm_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package astx_test - -import ( - "fmt" - "io/ioutil" - "testing" - - "github.com/geode-lang/geode/llvm/asm" - "github.com/sergi/go-diff/diffmatchpatch" -) - -func TestRoundTrip(t *testing.T) { - // Round-trip test of the parser. - golden := []struct { - path string - }{ - // Empty module. - {path: "../../testdata/empty.ll"}, - // Top-level declarations. - {path: "../../testdata/module.ll"}, - {path: "../../testdata/global.ll"}, - {path: "../../testdata/global_circular.ll"}, - {path: "../../testdata/func.ll"}, - {path: "../../testdata/metadata.ll"}, - // Types. - {path: "../../testdata/type.ll"}, - // Constants. - {path: "../../testdata/const.ll"}, - // Constant expressions. - {path: "../../testdata/expr_binary.ll"}, - {path: "../../testdata/expr_bitwise.ll"}, - {path: "../../testdata/expr_vector.ll"}, - {path: "../../testdata/expr_aggregate.ll"}, - {path: "../../testdata/expr_memory.ll"}, - {path: "../../testdata/expr_conversion.ll"}, - {path: "../../testdata/expr_other.ll"}, - // Instructions. - {path: "../../testdata/inst_binary.ll"}, - {path: "../../testdata/inst_bitwise.ll"}, - {path: "../../testdata/inst_vector.ll"}, - {path: "../../testdata/inst_aggregate.ll"}, - {path: "../../testdata/inst_memory.ll"}, - {path: "../../testdata/inst_conversion.ll"}, - {path: "../../testdata/inst_other.ll"}, - // Terminators. - {path: "../../testdata/term.ll"}, - // Pseudo-random number generator. - {path: "../../testdata/rand.ll"}, - // Inline assembly. - {path: "../../testdata/inline_asm.ll"}, - // Fixed bugs. - {path: "../../testdata/fixedbugs/issue_27.ll"}, - } - dmp := diffmatchpatch.New() - for _, g := range golden { - buf, err := ioutil.ReadFile(g.path) - if err != nil { - t.Errorf("%q: unable to read file; %v", g.path, err) - continue - } - input := string(buf) - m, err := asm.ParseString(input) - if err != nil { - t.Errorf("%q: unable to parse file; %v", g.path, err) - continue - } - want := input - // Read foo.ll.golden if present. - if buf, err := ioutil.ReadFile(g.path + ".golden"); err == nil { - want = string(buf) - } - got := m.String() - if want != got { - diffs := dmp.DiffMain(want, got, false) - fmt.Println(dmp.DiffPrettyText(diffs)) - t.Errorf("%q: module mismatch; expected `%v`, got `%v`", g.path, want, got) - continue - } - } -} diff --git a/llvm/asm/internal/astx/astx.go b/llvm/asm/internal/astx/astx.go deleted file mode 100755 index 04a16b3..0000000 --- a/llvm/asm/internal/astx/astx.go +++ /dev/null @@ -1,3367 +0,0 @@ -// Package astx implements utility functions for generating abstract syntax -// trees of LLVM IR modules. -package astx - -import ( - "fmt" - "log" - "os" - "strconv" - "strings" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/asm/internal/token" - "github.com/geode-lang/geode/llvm/enc" - "github.com/pkg/errors" -) - -// TODO: Remove debug output. - -// dbg is a logger which prefixes debug messages with the file name and line -// number of callees. -var dbg = log.New(os.Stdout, "", log.Lshortfile) - -// === [ Modules ] ============================================================= - -// NewModule returns a new module based on the given top-level declarations. -func NewModule(decls interface{}) (*ast.Module, error) { - var ds []TopLevelDecl - switch decls := decls.(type) { - case []TopLevelDecl: - ds = decls - case nil: - // no top-level declarations. - default: - return nil, errors.Errorf("invalid top-level declaration list type; expected []astx.TopLevelDecl, got %T", decls) - } - m := &ast.Module{} - for _, d := range ds { - switch d := d.(type) { - case *DataLayout: - m.DataLayout = d.s - case *TargetTriple: - m.TargetTriple = d.s - case *ast.NamedType: - m.Types = append(m.Types, d) - case *ast.Global: - m.Globals = append(m.Globals, d) - case *ast.Function: - m.Funcs = append(m.Funcs, d) - case *ast.NamedMetadata: - m.NamedMetadata = append(m.NamedMetadata, d) - case *ast.Metadata: - m.Metadata = append(m.Metadata, d) - default: - dbg.Printf("support for %T not yet implemented", d) - } - } - m = fixModule(m) - return m, nil -} - -// TopLevelDecl represents a top-level declaration. -type TopLevelDecl interface{} - -// NewTopLevelDeclList returns a new top-level declaration list based on the -// given top-level declaration. -func NewTopLevelDeclList(decl interface{}) ([]TopLevelDecl, error) { - // Skip ignored top-level declaration; e.g. "source_filename". - if decl == nil { - return []TopLevelDecl{}, nil - } - d, ok := decl.(TopLevelDecl) - if !ok { - return nil, errors.Errorf("invalid top-level declaration type; expected astx.TopLevelDecl, got %T", decl) - } - return []TopLevelDecl{d}, nil -} - -// AppendTopLevelDecl appends the given top-level declaration to the top-level -// declaration list. -func AppendTopLevelDecl(decls, decl interface{}) ([]TopLevelDecl, error) { - ds, ok := decls.([]TopLevelDecl) - if !ok { - return nil, errors.Errorf("invalid top-level declaration list type; expected []astx.TopLevelDecl, got %T", decls) - } - // Skip ignored top-level declaration; e.g. "source_filename". - if decl == nil { - return ds, nil - } - d, ok := decl.(TopLevelDecl) - if !ok { - return nil, errors.Errorf("invalid top-level declaration type; expected astx.TopLevelDecl, got %T", decl) - } - return append(ds, d), nil -} - -// --- [ Target specifiers ] --------------------------------------------------- - -// DataLayout specifies the data layout of a module. -type DataLayout struct { - // Unquoted data layout string. - s string -} - -// NewDataLayout returns a new data layout string based on the given string -// token. -func NewDataLayout(triple interface{}) (*DataLayout, error) { - s, err := getTokenString(triple) - if err != nil { - return nil, errors.WithStack(err) - } - return &DataLayout{s: unquote(s)}, nil -} - -// TargetTriple specifies the target triple of a module. -type TargetTriple struct { - // Unquoted target triple string. - s string -} - -// NewTargetTriple returns a new target triple string based on the given string -// token. -func NewTargetTriple(triple interface{}) (*TargetTriple, error) { - s, err := getTokenString(triple) - if err != nil { - return nil, errors.WithStack(err) - } - return &TargetTriple{s: unquote(s)}, nil -} - -// --- [ Type definitions ] ---------------------------------------------------- - -// NewTypeDef returns a new type definition based on the given type name and -// definition. -func NewTypeDef(name, typ interface{}) (*ast.NamedType, error) { - n, ok := name.(*LocalIdent) - if !ok { - return nil, errors.Errorf("invalid type name type; expected *astx.LocalIdent, got %T", name) - } - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", typ) - } - return &ast.NamedType{Name: unquote(n.name), Def: t}, nil -} - -// NewTypeDefOpaque returns a new opaque struct type definition based on the -// given type name. -func NewTypeDefOpaque(name interface{}) (*ast.NamedType, error) { - n, ok := name.(*LocalIdent) - if !ok { - return nil, errors.Errorf("invalid type name type; expected *astx.LocalIdent, got %T", name) - } - t := &ast.StructType{Opaque: true} - return &ast.NamedType{Name: unquote(n.name), Def: t}, nil -} - -// --- [ Global variables ] ---------------------------------------------------- - -// NewGlobalDecl returns a new global variable declaration based on the given -// global variable name, address space, immutability, type and attached -// metadata. -func NewGlobalDecl(name, addrspace, immutable, typ, mds interface{}) (*ast.Global, error) { - n, ok := name.(*GlobalIdent) - if !ok { - return nil, errors.Errorf("invalid global name type; expected *astx.GlobalIdent, got %T", name) - } - var space int - if addrspace != nil { - x, err := getInt64(addrspace) - if err != nil { - return nil, errors.WithStack(err) - } - space = int(x) - } - imm, ok := immutable.(bool) - if !ok { - return nil, errors.Errorf("invalid immutability type; expected bool, got %T", immutable) - } - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid content type; expected ast.Type, got %T", typ) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.Global{Name: unquote(n.name), Content: t, Immutable: imm, AddrSpace: space, Metadata: metadata}, nil -} - -// NewGlobalDef returns a new global variable definition based on the given -// global variable name, address space, immutability, type, value and attached -// metadata. -func NewGlobalDef(name, addrspace, immutable, typ, val, mds interface{}) (*ast.Global, error) { - n, ok := name.(*GlobalIdent) - if !ok { - return nil, errors.Errorf("invalid global name type; expected *astx.GlobalIdent, got %T", name) - } - var space int - if addrspace != nil { - x, err := getInt64(addrspace) - if err != nil { - return nil, errors.WithStack(err) - } - space = int(x) - } - imm, ok := immutable.(bool) - if !ok { - return nil, errors.Errorf("invalid immutability type; expected bool, got %T", immutable) - } - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", typ) - } - init, err := NewValue(t, val) - if err != nil { - return nil, errors.WithStack(err) - } - i, ok := init.(ast.Constant) - if !ok { - return nil, errors.Errorf("invalid init type; expected ast.Constant, got %T", init) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.Global{Name: unquote(n.name), Content: t, Init: i, Immutable: imm, AddrSpace: space, Metadata: metadata}, nil -} - -// --- [ Functions ] ----------------------------------------------------------- - -// NewFuncDecl returns a new function declaration based on the given attached -// metadata and function header. -func NewFuncDecl(mds, header interface{}) (*ast.Function, error) { - f, ok := header.(*ast.Function) - if !ok { - return nil, errors.Errorf("invalid function header type; expected *ast.Function, got %T", header) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - f.Metadata = metadata - return f, nil -} - -// NewFuncHeader returns a new function header based on the given return type, -// function name and parameters. -func NewFuncHeader(callconv, ret, name, params interface{}) (*ast.Function, error) { - var cc ast.CallConv - switch callconv := callconv.(type) { - case ast.CallConv: - cc = callconv - case nil: - // no calling convention. - default: - return nil, errors.Errorf("invalid calling convention type; expected ast.CallConv or nil, got %T", callconv) - } - r, ok := ret.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid function return type; expected ast.Type, got %T", ret) - } - n, ok := name.(*GlobalIdent) - if !ok { - return nil, errors.Errorf("invalid function name type; expected *astx.GlobalIdent, got %T", name) - } - sig := &ast.FuncType{Ret: r} - switch ps := params.(type) { - case *Params: - for _, param := range ps.params { - sig.Params = append(sig.Params, param) - } - sig.Variadic = ps.variadic - case nil: - // no parameters. - default: - return nil, errors.Errorf("invalid function parameters type; expected *astx.Params or nil, got %T", params) - } - f := &ast.Function{ - Name: unquote(n.name), - Sig: sig, - CallConv: cc, - } - return f, nil -} - -// NewFuncDef returns a new function definition based on the given function -// header, attached metadata and body. -func NewFuncDef(header, mds, body interface{}) (*ast.Function, error) { - f, ok := header.(*ast.Function) - if !ok { - return nil, errors.Errorf("invalid function header type; expected *ast.Function, got %T", header) - } - blocks, ok := body.([]*ast.BasicBlock) - if !ok { - return nil, errors.Errorf("invalid function body type; expected []*ast.BasicBlock, got %T", body) - } - f.Blocks = blocks - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - f.Metadata = metadata - return f, nil -} - -// Params represents a function parameters specifier. -type Params struct { - // Function parameter types. - params []*ast.Param - // Variadicity of the function type. - variadic bool -} - -// NewParams returns a new function parameters specifier, based on the given -// function parameters and variadicity. -func NewParams(params interface{}, variadic bool) (*Params, error) { - switch params := params.(type) { - case []*ast.Param: - return &Params{params: params, variadic: variadic}, nil - case nil: - return &Params{variadic: variadic}, nil - default: - return nil, errors.Errorf("invalid function parameter list; expected []*ast.Param or nil, got %T", params) - } -} - -// NewParamList returns a new function parameter list based on the given -// function parameter. -func NewParamList(param interface{}) ([]*ast.Param, error) { - p, ok := param.(*ast.Param) - if !ok { - return nil, errors.Errorf("invalid function parameter type; expected *ast.Param, got %T", param) - } - return []*ast.Param{p}, nil -} - -// AppendParam appends the given parameter to the function parameter list. -func AppendParam(params, param interface{}) ([]*ast.Param, error) { - ps, ok := params.([]*ast.Param) - if !ok { - return nil, errors.Errorf("invalid function parameter list type; expected []*ast.Param, got %T", params) - } - p, ok := param.(*ast.Param) - if !ok { - return nil, errors.Errorf("invalid function parameter type; expected *ast.Param, got %T", param) - } - return append(ps, p), nil -} - -// NewParam returns a new function parameter based on the given parameter type -// and name. -func NewParam(typ, name interface{}) (*ast.Param, error) { - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", typ) - } - var n string - switch name := name.(type) { - case *LocalIdent: - n = name.name - case nil: - // unnamed function parameter. - default: - return nil, errors.Errorf("invalid local name type; expected *astx.LocalIdent or nil, got %T", name) - } - return &ast.Param{Name: n, Type: t}, nil -} - -// NewCallConv returns a new calling convention based on the given calling -// convention id. -func NewCallConv(id interface{}) (ast.CallConv, error) { - x, err := getInt64(id) - if err != nil { - return ast.CallConvNone, errors.WithStack(err) - } - // From src of v4.0. - // - // ref: include/llvm/IR/CallingConv.h - switch x { - case 0: - return ast.CallConvC, nil - case 8: - return ast.CallConvFast, nil - case 9: - return ast.CallConvCold, nil - case 10: - return ast.CallConvGHC, nil - case 11: - return ast.CallConvHiPE, nil - case 12: - return ast.CallConvWebKit_JS, nil - case 13: - return ast.CallConvAnyReg, nil - case 14: - return ast.CallConvPreserveMost, nil - case 15: - return ast.CallConvPreserveAll, nil - case 16: - return ast.CallConvSwift, nil - case 17: - return ast.CallConvCXX_Fast_TLS, nil - case 64: - return ast.CallConvX86_StdCall, nil - case 65: - return ast.CallConvX86_FastCall, nil - case 66: - return ast.CallConvARM_APCS, nil - case 67: - return ast.CallConvARM_AAPCS, nil - case 68: - return ast.CallConvARM_AAPCS_VFP, nil - case 69: - return ast.CallConvMSP430_Intr, nil - case 70: - return ast.CallConvX86_ThisCall, nil - case 71: - return ast.CallConvPTX_Kernel, nil - case 72: - return ast.CallConvPTX_Device, nil - case 75: - return ast.CallConvSPIR_Func, nil - case 76: - return ast.CallConvSPIR_Kernel, nil - case 77: - return ast.CallConvIntel_OCL_BI, nil - case 78: - return ast.CallConvX86_64_SysV, nil - case 79: - return ast.CallConvX86_64_Win64, nil - case 80: - return ast.CallConvX86_VectorCall, nil - case 81: - return ast.CallConvHHVM, nil - case 82: - return ast.CallConvHHVM_C, nil - case 83: - return ast.CallConvX86_Intr, nil - case 84: - return ast.CallConvAVR_Intr, nil - case 85: - return ast.CallConvAVR_Signal, nil - case 86: - return ast.CallConvAVR_Builtin, nil - case 87: - return ast.CallConvAMDGPU_VS, nil - case 88: - return ast.CallConvAMDGPU_GS, nil - case 89: - return ast.CallConvAMDGPU_PS, nil - case 90: - return ast.CallConvAMDGPU_CS, nil - case 91: - return ast.CallConvAMDGPU_Kernel, nil - case 92: - return ast.CallConvX86_RegCall, nil - default: - panic(fmt.Errorf("support for calling convention ID %d not yet implemented", x)) - } -} - -// NewInlineAsm returns a new inline assembly statement. -func NewInlineAsm(asm, constraints interface{}) (*ast.InlineAsm, error) { - a, err := getTokenString(asm) - if err != nil { - return nil, errors.WithStack(err) - } - a = enc.Unquote(a) - c, err := getTokenString(constraints) - if err != nil { - return nil, errors.WithStack(err) - } - c = enc.Unquote(c) - return &ast.InlineAsm{Asm: a, Constraints: c}, nil -} - -// --- [ Metadata definitions ] ------------------------------------------------ - -// NewNamedMetadataDef returns a new named metadata definition based on the -// given metadata name and definition. -func NewNamedMetadataDef(name, ids interface{}) (*ast.NamedMetadata, error) { - n, ok := name.(*MetadataName) - if !ok { - return nil, errors.Errorf("invalid metadata name type; expected *astx.MetadataName, got %T", name) - } - var is []*ast.MetadataIDDummy - switch ids := ids.(type) { - case []*ast.MetadataIDDummy: - is = ids - case nil: - // no metadata IDs. - default: - return nil, errors.Errorf("invalid metadata IDs type; expected []*astx.MetadataID, got %T", ids) - } - md := &ast.NamedMetadata{ - Name: unquote(n.name), - } - for _, i := range is { - dummy := &ast.MetadataIDDummy{ID: i.ID} - md.Metadata = append(md.Metadata, dummy) - } - return md, nil -} - -// NewMetadataIDList returns a new metadata ID list based on the given metadata -// ID. -func NewMetadataIDList(id interface{}) ([]*ast.MetadataIDDummy, error) { - i, ok := id.(*ast.MetadataIDDummy) - if !ok { - return nil, errors.Errorf("invalid metadata ID type; expected *astx.MetadataID, got %T", id) - } - return []*ast.MetadataIDDummy{i}, nil -} - -// AppendMetadataID appends the given metadata ID to the metadata ID list. -func AppendMetadataID(ids, id interface{}) ([]*ast.MetadataIDDummy, error) { - is, ok := ids.([]*ast.MetadataIDDummy) - if !ok { - return nil, errors.Errorf("invalid metadata ID list type; expected []*astx.MetadataID, got %T", ids) - } - i, ok := id.(*ast.MetadataIDDummy) - if !ok { - return nil, errors.Errorf("invalid metadata ID type; expected *astx.MetadataID, got %T", id) - } - return append(is, i), nil -} - -// NewMetadataDef returns a new metadata definition based on the given metadata -// id and definition. -func NewMetadataDef(id, md interface{}) (*ast.Metadata, error) { - i, ok := id.(*ast.MetadataIDDummy) - if !ok { - return nil, errors.Errorf("invalid metadata ID type; expected *astx.MetadataID, got %T", id) - } - m, ok := md.(*ast.Metadata) - if !ok { - return nil, errors.Errorf("invalid metadata type; expected *ast.Metadata, got %T", md) - } - metadata := &ast.Metadata{ - ID: i.ID, - Nodes: m.Nodes, - } - return metadata, nil -} - -// NewMetadata returns a new metadata based on the given metadata nodes. -func NewMetadata(nodes interface{}) (*ast.Metadata, error) { - if nodes == nil { - return &ast.Metadata{}, nil - } - ns, ok := nodes.([]ast.MetadataNode) - if !ok { - return nil, errors.Errorf("invalid metadata nodes type; expected []ast.MetadataNode, got %T", nodes) - } - metadata := &ast.Metadata{ - Nodes: ns, - } - return metadata, nil -} - -// NewMetadataNodeList returns a new metadata node list based on the given -// metadata node. -func NewMetadataNodeList(node interface{}) ([]ast.MetadataNode, error) { - n, ok := node.(ast.MetadataNode) - if !ok { - return nil, errors.Errorf("invalid metadata node type; expected ast.MetadataNode, got %T", node) - } - return []ast.MetadataNode{n}, nil -} - -// AppendMetadataNode appends the given metadata node to the metadata node list. -func AppendMetadataNode(nodes, node interface{}) ([]ast.MetadataNode, error) { - ns, ok := nodes.([]ast.MetadataNode) - if !ok { - return nil, errors.Errorf("invalid metadata node list type; expected []ast.MetadataNode, got %T", nodes) - } - n, ok := node.(ast.MetadataNode) - if !ok { - return nil, errors.Errorf("invalid metadata node type; expected ast.MetadataNode, got %T", node) - } - return append(ns, n), nil -} - -// NewMetadataString returns a new metadata string based on the given string token. -func NewMetadataString(val interface{}) (*ast.MetadataString, error) { - v, err := getTokenString(val) - if err != nil { - return nil, errors.WithStack(err) - } - v = enc.Unquote(v) - return &ast.MetadataString{Val: v}, nil -} - -// NewMetadataValue returns a new metadata value based on the given metadata -// node. -func NewMetadataValue(node interface{}) (ast.MetadataNode, error) { - switch n := node.(type) { - case *ast.LocalDummy: - return &ast.MetadataValue{X: n}, nil - case ast.Constant: - return &ast.MetadataValue{X: n}, nil - case ast.MetadataNode: - return n, nil - default: - return nil, errors.Errorf("invalid metadata node type; expected ast.MetadataNode, got %T", node) - } -} - -// === [ Identifiers ] ========================================================= - -// GlobalIdent represents a global identifier. -type GlobalIdent struct { - // Global identifier name the without "@" prefix. - name string -} - -// NewGlobalIdent returns a new global identifier based on the given global -// identifier token. -func NewGlobalIdent(ident interface{}) (*GlobalIdent, error) { - s, err := getTokenString(ident) - if err != nil { - return nil, errors.WithStack(err) - } - if !strings.HasPrefix(s, "@") { - return nil, errors.Errorf(`invalid global identifier %q; missing "@" prefix`, s) - } - s = s[1:] - return &GlobalIdent{name: s}, nil -} - -// LocalIdent represents a local identifier. -type LocalIdent struct { - // Local identifier name the without "%" prefix. - name string -} - -// NewLocalIdent returns a new local identifier based on the given local -// identifier token. -func NewLocalIdent(ident interface{}) (*LocalIdent, error) { - s, err := getTokenString(ident) - if err != nil { - return nil, errors.WithStack(err) - } - if !strings.HasPrefix(s, "%") { - return nil, errors.Errorf(`invalid local identifier %q; missing "%%" prefix`, s) - } - s = s[1:] - return &LocalIdent{name: s}, nil -} - -// LabelIdent represents a label identifier. -type LabelIdent struct { - // Label identifier name the without ":" suffix. - name string -} - -// NewLabelIdent returns a new label identifier based on the given label -// identifier token. -func NewLabelIdent(ident interface{}) (*LabelIdent, error) { - s, err := getTokenString(ident) - if err != nil { - return nil, errors.WithStack(err) - } - if !strings.HasSuffix(s, ":") { - return nil, errors.Errorf(`invalid label identifier %q; missing ":" suffix`, s) - } - s = s[:len(s)-1] - return &LabelIdent{name: s}, nil -} - -// MetadataName represents a metadata name. -type MetadataName struct { - // Metadata name the without "!" prefix. - name string -} - -// NewMetadataName returns a new metadata name based on the given metadata name -// token. -func NewMetadataName(name interface{}) (*MetadataName, error) { - s, err := getTokenString(name) - if err != nil { - return nil, errors.WithStack(err) - } - if !strings.HasPrefix(s, "!") { - return nil, errors.Errorf(`invalid metadata name %q; missing "!" prefix`, s) - } - s = s[1:] - return &MetadataName{name: s}, nil -} - -// NewMetadataID returns a new metadata id based on the given metadata id token. -func NewMetadataID(id interface{}) (*ast.MetadataIDDummy, error) { - s, err := getTokenString(id) - if err != nil { - return nil, errors.WithStack(err) - } - if !strings.HasPrefix(s, "!") { - return nil, errors.Errorf(`invalid metadata id %q; missing "!" prefix`, s) - } - s = s[1:] - return &ast.MetadataIDDummy{ID: s}, nil -} - -// === [ Types ] =============================================================== - -// NewTypeList returns a new type list based on the given type. -func NewTypeList(typ interface{}) ([]ast.Type, error) { - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", typ) - } - return []ast.Type{t}, nil -} - -// AppendType appends the given type to the type list. -func AppendType(typs, typ interface{}) ([]ast.Type, error) { - ts, ok := typs.([]ast.Type) - if !ok { - return nil, errors.Errorf("invalid type list type; expected []ast.Type, got %T", typs) - } - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", typ) - } - return append(ts, t), nil -} - -// NewIntType returns a new integer type based on the given integer type token. -func NewIntType(typeTok interface{}) (*ast.IntType, error) { - s, err := getTokenString(typeTok) - if err != nil { - return nil, errors.WithStack(err) - } - if !strings.HasPrefix(s, "i") { - return nil, errors.Errorf(`invalid integer type %q; missing "i" prefix`, s) - } - s = s[1:] - size, err := strconv.Atoi(s) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.IntType{Size: size}, nil -} - -// NewFuncType returns a new function type based on the given return type and -// function parameters. -func NewFuncType(ret, params interface{}) (*ast.FuncType, error) { - r, ok := ret.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid function return type; expected ast.Type, got %T", ret) - } - sig := &ast.FuncType{Ret: r} - switch ps := params.(type) { - case *Params: - for _, param := range ps.params { - sig.Params = append(sig.Params, param) - } - sig.Variadic = ps.variadic - case nil: - // no parameters. - default: - return nil, errors.Errorf("invalid function parameters type; expected *astx.Params or nil, got %T", params) - } - return sig, nil -} - -// NewPointerType returns a new pointer type based on the given element type and -// address space. -func NewPointerType(elem, addrspace interface{}) (*ast.PointerType, error) { - var space int - if addrspace != nil { - x, err := getInt64(addrspace) - if err != nil { - return nil, errors.WithStack(err) - } - space = int(x) - } - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - return &ast.PointerType{Elem: e, AddrSpace: space}, nil -} - -// NewVectorType returns a new vector type based on the given vector length and -// element type. -func NewVectorType(len, elem interface{}) (*ast.VectorType, error) { - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - l, err := getInt64(len) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.VectorType{Elem: e, Len: l}, nil -} - -// NewArrayType returns a new array type based on the given array length and -// element type. -func NewArrayType(len, elem interface{}) (*ast.ArrayType, error) { - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - l, err := getInt64(len) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ArrayType{Elem: e, Len: l}, nil -} - -// NewStructType returns a new struct type based on the given struct fields. -func NewStructType(fields interface{}) (*ast.StructType, error) { - var fs []ast.Type - switch fields := fields.(type) { - case []ast.Type: - fs = fields - case nil: - // no struct fields. - default: - return nil, errors.Errorf("invalid struct fields type; expected []ast.Type, got %T", fields) - } - return &ast.StructType{Fields: fs}, nil -} - -// NewTypeIdent returns a new type identifier based on the given local -// identifier. -func NewTypeIdent(name interface{}) (*ast.NamedTypeDummy, error) { - n, ok := name.(*LocalIdent) - if !ok { - return nil, errors.Errorf("invalid type name type; expected *astx.LocalIdent, got %T", name) - } - return &ast.NamedTypeDummy{Name: unquote(n.name)}, nil -} - -// === [ Values ] ============================================================== - -// NewValueList returns a new value list based on the given -// value. -func NewValueList(val interface{}) ([]ast.Value, error) { - v, ok := val.(ast.Value) - if !ok { - return nil, errors.Errorf("invalid value type; expected ast.Value, got %T", val) - } - return []ast.Value{v}, nil -} - -// AppendValue appends the given value to the value list. -func AppendValue(vals, val interface{}) ([]ast.Value, error) { - vs, ok := vals.([]ast.Value) - if !ok { - return nil, errors.Errorf("invalid value list type; expected []ast.Value, got %T", vals) - } - v, ok := val.(ast.Value) - if !ok { - return nil, errors.Errorf("invalid value type; expected ast.Value, got %T", val) - } - return append(vs, v), nil -} - -// NewValue returns a value based on the given type and value. -func NewValue(typ, val interface{}) (ast.Value, error) { - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid value type; expected ast.Type, got %T", typ) - } - switch val := val.(type) { - case *LocalIdent: - return &ast.LocalDummy{Name: val.name, Type: t}, nil - case *GlobalIdent: - return &ast.GlobalDummy{Name: val.name, Type: t}, nil - case *IntLit: - return &ast.IntConst{Type: t, Lit: val.lit}, nil - case *BoolLit: - return &ast.IntConst{Type: t, Lit: val.lit}, nil - case *FloatLit: - return &ast.FloatConst{Type: t, Lit: val.lit}, nil - case *NullLit: - return &ast.NullConst{Type: t}, nil - case *ZeroInitializerLit: - return &ast.ZeroInitializerConst{Type: t}, nil - case *UndefLit: - return &ast.UndefConst{Type: t}, nil - // Inline assmebly. - case *ast.InlineAsm: - val.Type = t - return val, nil - - // Replace *ast.TypeDummy with real type; as used by incoming values of phi - // instructions. - case *ast.GlobalDummy: - // Global dummy identifier type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid global dummy identifier type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.LocalDummy: - // Local dummy identifier type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid local dummy identifier type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.IntConst: - // Integer constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid integer constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.FloatConst: - // Floating-point constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid floating-point constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.NullConst: - // Null pointer constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid null pointer constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.VectorConst: - // Vector constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid vector constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ArrayConst: - // Array constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid array constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.CharArrayConst: - // Character array constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid character array constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.StructConst: - // Struct constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid struct constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ZeroInitializerConst: - // zeroinitializer constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid zeroinitializer constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.UndefConst: - // undef constant type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid undef constant type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Binary expressions - case *ast.ExprAdd: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid add expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFAdd: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fadd expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprSub: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid sub expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFSub: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fsub expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprMul: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid mul expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFMul: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fmul expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprUDiv: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid udiv expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprSDiv: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid sdiv expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFDiv: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fdiv expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprURem: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid urem expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprSRem: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid srem expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFRem: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid frem expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Bitwise expressions - case *ast.ExprShl: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid shl expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprLShr: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid lshr expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprAShr: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid ashr expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprAnd: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid and expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprOr: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid or expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprXor: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid xor expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Aggregate expressions - case *ast.ExprExtractValue: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid extractvalue expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprInsertValue: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid insertvalue expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Vector expressions - case *ast.ExprExtractElement: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid extractelement expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprInsertElement: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid insertelement expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprShuffleVector: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid shufflevector expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Memory expressions - case *ast.ExprGetElementPtr: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid getelementptr expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Conversion expressions - case *ast.ExprTrunc: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid trunc expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprZExt: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid zext expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprSExt: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid sext expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFPTrunc: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fptrunc expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFPExt: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fpext expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFPToUI: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fptoui expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFPToSI: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fptosi expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprUIToFP: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid uitofp expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprSIToFP: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid sitofp expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprPtrToInt: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid ptrtoint expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprIntToPtr: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid inttoptr expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprBitCast: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid bitcast expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprAddrSpaceCast: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid addrspacecast expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - // Other expressions - case *ast.ExprICmp: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid icmp expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprFCmp: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid fcmp expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - case *ast.ExprSelect: - // Constant expression type should be of dummy type. - if _, ok := val.Type.(*ast.TypeDummy); !ok { - return nil, errors.Errorf("invalid select expression type, expected *ast.TypeDummy, got %T", val.Type) - } - val.Type = t - return val, nil - - default: - panic(fmt.Errorf("support for value type %T not yet implemented", val)) - } -} - -// === [ Constants ] =========================================================== - -// NewConstantList returns a new constant list based on the given constant. -func NewConstantList(x interface{}) ([]ast.Constant, error) { - c, ok := x.(ast.Constant) - if !ok { - return nil, errors.Errorf("invalid constant type; expected ast.Constant, got %T", x) - } - return []ast.Constant{c}, nil -} - -// AppendConstant appends the given constant to the constant list. -func AppendConstant(xs, x interface{}) ([]ast.Constant, error) { - cs, ok := xs.([]ast.Constant) - if !ok { - return nil, errors.Errorf("invalid constant list type; expected []ast.Constant, got %T", xs) - } - c, ok := x.(ast.Constant) - if !ok { - return nil, errors.Errorf("invalid constant type; expected ast.Constant, got %T", x) - } - return append(cs, c), nil -} - -// NewConstant returns a constant based on the given type and value. -func NewConstant(typ, val interface{}) (ast.Constant, error) { - v, err := NewValue(typ, val) - if err != nil { - return nil, errors.WithStack(err) - } - c, ok := v.(ast.Constant) - if !ok { - return nil, errors.Errorf("invalid constant type; expected ast.Constant, got %T", v) - } - return c, nil -} - -// IntLit represents an integer literal. -type IntLit struct { - // Integer literal. - lit string -} - -// NewIntLit returns a new integer literal based on the given integer token. -func NewIntLit(tok interface{}) (*IntLit, error) { - s, err := getTokenString(tok) - if err != nil { - return nil, errors.WithStack(err) - } - return &IntLit{lit: s}, nil -} - -// BoolLit represents a boolean literal. -type BoolLit struct { - // Boolean literal. - lit string -} - -// NewBoolLit returns a new boolean literal based on the given boolean token. -func NewBoolLit(tok interface{}) (*BoolLit, error) { - s, err := getTokenString(tok) - if err != nil { - return nil, errors.WithStack(err) - } - return &BoolLit{lit: s}, nil -} - -// FloatLit represents an floating-point literal. -type FloatLit struct { - // Floating-point literal. - lit string -} - -// NewFloatLit returns a new floating-point literal based on the given floating-point token. -func NewFloatLit(tok interface{}) (*FloatLit, error) { - s, err := getTokenString(tok) - if err != nil { - return nil, errors.WithStack(err) - } - return &FloatLit{lit: s}, nil -} - -// NullLit represents a null literal. -type NullLit struct { -} - -// NewVectorConst returns a new vector constant based on the given elements. -func NewVectorConst(elems interface{}) (*ast.VectorConst, error) { - es, ok := elems.([]ast.Constant) - if !ok { - return nil, errors.Errorf("invalid vector elements type; expected []ast.Constant, got %T", elems) - } - return &ast.VectorConst{Type: &ast.TypeDummy{}, Elems: es}, nil -} - -// NewArrayConst returns a new array constant based on the given elements. -func NewArrayConst(elems interface{}) (*ast.ArrayConst, error) { - var es []ast.Constant - switch elems := elems.(type) { - case []ast.Constant: - es = elems - case nil: - // no array elements. - default: - return nil, errors.Errorf("invalid array elements type; expected []ast.Constant, got %T", elems) - } - return &ast.ArrayConst{Type: &ast.TypeDummy{}, Elems: es}, nil -} - -// NewCharArrayConst returns a new character array constant based on the given -// string. -func NewCharArrayConst(str interface{}) (*ast.CharArrayConst, error) { - s, err := getTokenString(str) - if err != nil { - return nil, errors.WithStack(err) - } - s = enc.Unquote(s) - c := &ast.CharArrayConst{Type: &ast.TypeDummy{}, Lit: s} - return c, nil -} - -// NewStructConst returns a new struct constant based on the given fields. -func NewStructConst(fields interface{}) (*ast.StructConst, error) { - var fs []ast.Constant - switch fields := fields.(type) { - case []ast.Constant: - fs = fields - case nil: - // no struct fields. - default: - return nil, errors.Errorf("invalid struct fields type; expected []ast.Constant, got %T", fields) - } - return &ast.StructConst{Type: &ast.TypeDummy{}, Fields: fs}, nil -} - -// ZeroInitializerLit represents a zeroinitializer literal. -type ZeroInitializerLit struct { -} - -// UndefLit represents an undef literal. -type UndefLit struct { -} - -// --- [ Binary expressions ] -------------------------------------------------- - -// NewAddExpr returns a new add expression based on the given type and operands. -func NewAddExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprAdd, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprAdd{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewFAddExpr returns a new fadd expression based on the given type and -// operands. -func NewFAddExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprFAdd, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprFAdd{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewSubExpr returns a new sub expression based on the given type and operands. -func NewSubExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprSub, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprSub{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewFSubExpr returns a new fsub expression based on the given type and -// operands. -func NewFSubExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprFSub, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprFSub{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewMulExpr returns a new mul expression based on the given type and operands. -func NewMulExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprMul, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprMul{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewFMulExpr returns a new fmul expression based on the given type and -// operands. -func NewFMulExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprFMul, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprFMul{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewUDivExpr returns a new udiv expression based on the given type and -// operands. -func NewUDivExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprUDiv, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprUDiv{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewSDivExpr returns a new sdiv expression based on the given type and -// operands. -func NewSDivExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprSDiv, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprSDiv{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewFDivExpr returns a new fdiv expression based on the given type and -// operands. -func NewFDivExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprFDiv, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprFDiv{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewURemExpr returns a new urem expression based on the given type and -// operands. -func NewURemExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprURem, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprURem{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewSRemExpr returns a new srem expression based on the given type and -// operands. -func NewSRemExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprSRem, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprSRem{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewFRemExpr returns a new frem expression based on the given type and -// operands. -func NewFRemExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprFRem, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprFRem{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// --- [ Bitwise expressions ] ------------------------------------------------- - -// NewShlExpr returns a new shl expression based on the given type and operands. -func NewShlExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprShl, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprShl{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewLShrExpr returns a new lshr expression based on the given type and -// operands. -func NewLShrExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprLShr, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprLShr{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewAShrExpr returns a new ashr expression based on the given type and -// operands. -func NewAShrExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprAShr, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprAShr{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewAndExpr returns a new and expression based on the given type and operands. -func NewAndExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprAnd, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprAnd{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewOrExpr returns a new or expression based on the given type and operands. -func NewOrExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprOr, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprOr{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// NewXorExpr returns a new xor expression based on the given type and operands. -func NewXorExpr(xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprXor, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprXor{Type: &ast.TypeDummy{}, X: x, Y: y}, nil -} - -// --- [ Vector expressions ] -------------------------------------------------- - -// NewExtractElementExpr returns a new extractelement expression based on the -// given vector and index. -func NewExtractElementExpr(xTyp, xVal, indexTyp, indexVal interface{}) (*ast.ExprExtractElement, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - index, err := NewConstant(indexTyp, indexVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprExtractElement{Type: &ast.TypeDummy{}, X: x, Index: index}, nil -} - -// NewInsertElementExpr returns a new insertelement expression based on the -// given vector, element and index. -func NewInsertElementExpr(xTyp, xVal, elemTyp, elemVal, indexTyp, indexVal interface{}) (*ast.ExprInsertElement, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - elem, err := NewConstant(elemTyp, elemVal) - if err != nil { - return nil, errors.WithStack(err) - } - index, err := NewConstant(indexTyp, indexVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprInsertElement{Type: &ast.TypeDummy{}, X: x, Elem: elem, Index: index}, nil -} - -// NewShuffleVectorExpr returns a new shufflevector expression based on the -// given vectors and shuffle mask. -func NewShuffleVectorExpr(xTyp, xVal, yTyp, yVal, maskTyp, maskVal interface{}) (*ast.ExprShuffleVector, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - mask, err := NewConstant(maskTyp, maskVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprShuffleVector{Type: &ast.TypeDummy{}, X: x, Y: y, Mask: mask}, nil -} - -// --- [ Aggregate expressions ] ---------------------------------------------- - -// NewExtractValueExpr returns a new extractvalue expression based on the -// given aggregate value and indices. -func NewExtractValueExpr(xTyp, xVal, indices interface{}) (*ast.ExprExtractValue, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - is, ok := indices.([]int64) - if !ok { - return nil, errors.Errorf("invalid indices type; expected []int64, got %T", indices) - } - if len(is) < 1 { - return nil, errors.Errorf("invalid indices length; expected > 0, got %d", len(is)) - } - return &ast.ExprExtractValue{Type: &ast.TypeDummy{}, X: x, Indices: is}, nil -} - -// NewInsertValueExpr returns a new insertvalue expression based on the -// given aggregate value, element and indices. -func NewInsertValueExpr(xTyp, xVal, elemTyp, elemVal, indices interface{}) (*ast.ExprInsertValue, error) { - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - elem, err := NewConstant(elemTyp, elemVal) - if err != nil { - return nil, errors.WithStack(err) - } - is, ok := indices.([]int64) - if !ok { - return nil, errors.Errorf("invalid indices type; expected []int64, got %T", indices) - } - if len(is) < 1 { - return nil, errors.Errorf("invalid indices length; expected > 0, got %d", len(is)) - } - return &ast.ExprInsertValue{Type: &ast.TypeDummy{}, X: x, Elem: elem, Indices: is}, nil -} - -// --- [ Memory expressions ] -------------------------------------------------- - -// NewGetElementPtrExpr returns a new getelementptr expression based on the -// given element type, source address type and value, and element indices. -func NewGetElementPtrExpr(elem, srcTyp, srcVal, indices interface{}) (*ast.ExprGetElementPtr, error) { - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - src, err := NewConstant(srcTyp, srcVal) - if err != nil { - return nil, errors.WithStack(err) - } - var is []ast.Constant - switch indices := indices.(type) { - case []ast.Constant: - is = indices - case nil: - // no indices. - default: - return nil, errors.Errorf("invalid indices type; expected []ast.Constant or nil, got %T", indices) - } - return &ast.ExprGetElementPtr{Type: &ast.TypeDummy{}, Elem: e, Src: src, Indices: is}, nil -} - -// --- [ Conversion expressions ] ---------------------------------------------- - -// NewTruncExpr returns a new trunc expression based on the given source value -// and target type. -func NewTruncExpr(fromTyp, fromVal, to interface{}) (*ast.ExprTrunc, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprTrunc{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewZExtExpr returns a new zext expression based on the given source value and -// target type. -func NewZExtExpr(fromTyp, fromVal, to interface{}) (*ast.ExprZExt, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprZExt{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewSExtExpr returns a new sext expression based on the given source value and -// target type. -func NewSExtExpr(fromTyp, fromVal, to interface{}) (*ast.ExprSExt, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprSExt{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewFPTruncExpr returns a new fptrunc expression based on the given source -// value and target type. -func NewFPTruncExpr(fromTyp, fromVal, to interface{}) (*ast.ExprFPTrunc, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprFPTrunc{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewFPExtExpr returns a new fpext expression based on the given source value -// and target type. -func NewFPExtExpr(fromTyp, fromVal, to interface{}) (*ast.ExprFPExt, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprFPExt{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewFPToUIExpr returns a new fptoui expression based on the given source value -// and target type. -func NewFPToUIExpr(fromTyp, fromVal, to interface{}) (*ast.ExprFPToUI, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprFPToUI{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewFPToSIExpr returns a new fptosi expression based on the given source value -// and target type. -func NewFPToSIExpr(fromTyp, fromVal, to interface{}) (*ast.ExprFPToSI, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprFPToSI{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewUIToFPExpr returns a new uitofp expression based on the given source value -// and target type. -func NewUIToFPExpr(fromTyp, fromVal, to interface{}) (*ast.ExprUIToFP, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprUIToFP{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewSIToFPExpr returns a new sitofp expression based on the given source value -// and target type. -func NewSIToFPExpr(fromTyp, fromVal, to interface{}) (*ast.ExprSIToFP, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprSIToFP{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewPtrToIntExpr returns a new ptrtoint expression based on the given source -// value and target type. -func NewPtrToIntExpr(fromTyp, fromVal, to interface{}) (*ast.ExprPtrToInt, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprPtrToInt{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewIntToPtrExpr returns a new inttoptr expression based on the given source -// value and target type. -func NewIntToPtrExpr(fromTyp, fromVal, to interface{}) (*ast.ExprIntToPtr, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprIntToPtr{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewBitCastExpr returns a new bitcast expression based on the given source -// value and target type. -func NewBitCastExpr(fromTyp, fromVal, to interface{}) (*ast.ExprBitCast, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprBitCast{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// NewAddrSpaceCastExpr returns a new addrspacecast expression based on the -// given source value and target type. -func NewAddrSpaceCastExpr(fromTyp, fromVal, to interface{}) (*ast.ExprAddrSpaceCast, error) { - from, err := NewConstant(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - return &ast.ExprAddrSpaceCast{Type: &ast.TypeDummy{}, From: from, To: t}, nil -} - -// --- [ Other expressions ] --------------------------------------------------- - -// NewICmpExpr returns a new icmp expression based on the given integer -// predicate, type and operands. -func NewICmpExpr(pred, xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprICmp, error) { - p, ok := pred.(ast.IntPred) - if !ok { - return nil, errors.Errorf("invalid integer predicate type; expected ast.IntPred, got %T", pred) - } - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprICmp{Type: &ast.TypeDummy{}, Pred: p, X: x, Y: y}, nil -} - -// NewFCmpExpr returns a new fcmp expression based on the given floating-point -// predicate, type and operands. -func NewFCmpExpr(pred, xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprFCmp, error) { - p, ok := pred.(ast.FloatPred) - if !ok { - return nil, errors.Errorf("invalid floating-point predicate type; expected ast.FloatPred, got %T", pred) - } - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprFCmp{Type: &ast.TypeDummy{}, Pred: p, X: x, Y: y}, nil -} - -// NewSelectExpr returns a new select expression based on the given selection -// condition type and value, and operands. -func NewSelectExpr(condTyp, condVal, xTyp, xVal, yTyp, yVal interface{}) (*ast.ExprSelect, error) { - cond, err := NewConstant(condTyp, condVal) - if err != nil { - return nil, errors.WithStack(err) - } - x, err := NewConstant(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewConstant(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.ExprSelect{Type: &ast.TypeDummy{}, Cond: cond, X: x, Y: y}, nil -} - -// === [ Basic blocks ] ======================================================== - -// NewBasicBlockList returns a new basic block list based on the given basic -// block. -func NewBasicBlockList(block interface{}) ([]*ast.BasicBlock, error) { - b, ok := block.(*ast.BasicBlock) - if !ok { - return nil, errors.Errorf("invalid basic block type; expected *ast.BasicBlock, got %T", block) - } - return []*ast.BasicBlock{b}, nil -} - -// AppendBasicBlock appends the given basic block to the basic block list. -func AppendBasicBlock(blocks, block interface{}) ([]*ast.BasicBlock, error) { - bs, ok := blocks.([]*ast.BasicBlock) - if !ok { - return nil, errors.Errorf("invalid basic block list type; expected []*ast.BasicBlock, got %T", blocks) - } - b, ok := block.(*ast.BasicBlock) - if !ok { - return nil, errors.Errorf("invalid basic block type; expected *ast.BasicBlock, got %T", block) - } - return append(bs, b), nil -} - -// NewBasicBlock returns a new basic block based on the given label name, non- -// branching instructions and terminator. -func NewBasicBlock(name, insts, term interface{}) (*ast.BasicBlock, error) { - block := &ast.BasicBlock{} - switch name := name.(type) { - case *LabelIdent: - block.Name = name.name - case nil: - // unnamed basic block. - default: - return nil, errors.Errorf("invalid label name type; expected *astx.LabelIdent or nil, got %T", name) - } - var is []ast.Instruction - switch insts := insts.(type) { - case []ast.Instruction: - is = insts - case nil: - // no instructions. - default: - return nil, errors.Errorf("invalid instruction list type; expected []ast.Instruction, got %T", insts) - } - t, ok := term.(ast.Terminator) - if !ok { - return nil, errors.Errorf("invalid terminator type; expected ast.Terminator, got %T", term) - } - block.Insts = is - block.Term = t - return block, nil -} - -// === [ Instructions ] ======================================================== - -// NewInstructionList returns a new instruction list based on the given -// instruction. -func NewInstructionList(inst interface{}) ([]ast.Instruction, error) { - // TODO: Remove once all instructions in the BNF are supported. - if inst == nil { - return []ast.Instruction{}, nil - } - i, ok := inst.(ast.Instruction) - if !ok { - return nil, errors.Errorf("invalid instruction type; expected ast.Instruction, got %T", inst) - } - return []ast.Instruction{i}, nil -} - -// AppendInstruction appends the given instruction to the instruction list. -func AppendInstruction(insts, inst interface{}) ([]ast.Instruction, error) { - is, ok := insts.([]ast.Instruction) - if !ok { - return nil, errors.Errorf("invalid instruction list type; expected []ast.Instruction, got %T", insts) - } - // TODO: Remove once all instructions in the BNF are supported. - if inst == nil { - return is, nil - } - i, ok := inst.(ast.Instruction) - if !ok { - return nil, errors.Errorf("invalid instruction type; expected ast.Instruction, got %T", inst) - } - return append(is, i), nil -} - -// NewNamedInstruction returns a named instruction based on the given local -// variable name and instruction. -func NewNamedInstruction(name, inst interface{}) (ast.Instruction, error) { - // namedInstruction represents a namedInstruction instruction. - type namedInstruction interface { - ast.Instruction - ast.NamedValue - } - n, ok := name.(*LocalIdent) - if !ok { - return nil, errors.Errorf("invalid local variable name type; expected *astx.LocalIdent, got %T", name) - } - i, ok := inst.(namedInstruction) - if !ok { - return nil, errors.Errorf("invalid instruction type; expected namedInstruction, got %T", inst) - } - i.SetName(unquote(n.name)) - return i, nil -} - -// --- [ Binary instructions ] ------------------------------------------------- - -// NewAddInst returns a new add instruction based on the given type, operands -// and attached metadata. -func NewAddInst(typ, xVal, yVal, mds interface{}) (*ast.InstAdd, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstAdd{X: x, Y: y, Metadata: metadata}, nil -} - -// NewFAddInst returns a new fadd instruction based on the given type, operands -// and attached metadata. -func NewFAddInst(typ, xVal, yVal, mds interface{}) (*ast.InstFAdd, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFAdd{X: x, Y: y, Metadata: metadata}, nil -} - -// NewSubInst returns a new sub instruction based on the given type, operands -// and attached metadata. -func NewSubInst(typ, xVal, yVal, mds interface{}) (*ast.InstSub, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstSub{X: x, Y: y, Metadata: metadata}, nil -} - -// NewFSubInst returns a new fsub instruction based on the given type, operands -// and attached metadata. -func NewFSubInst(typ, xVal, yVal, mds interface{}) (*ast.InstFSub, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFSub{X: x, Y: y, Metadata: metadata}, nil -} - -// NewMulInst returns a new mul instruction based on the given type, operands -// and attached metadata. -func NewMulInst(typ, xVal, yVal, mds interface{}) (*ast.InstMul, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstMul{X: x, Y: y, Metadata: metadata}, nil -} - -// NewFMulInst returns a new fmul instruction based on the given type, operands -// and attached metadata. -func NewFMulInst(typ, xVal, yVal, mds interface{}) (*ast.InstFMul, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFMul{X: x, Y: y, Metadata: metadata}, nil -} - -// NewUDivInst returns a new udiv instruction based on the given type, operands -// and attached metadata. -func NewUDivInst(typ, xVal, yVal, mds interface{}) (*ast.InstUDiv, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstUDiv{X: x, Y: y, Metadata: metadata}, nil -} - -// NewSDivInst returns a new sdiv instruction based on the given type, operands -// and attached metadata. -func NewSDivInst(typ, xVal, yVal, mds interface{}) (*ast.InstSDiv, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstSDiv{X: x, Y: y, Metadata: metadata}, nil -} - -// NewFDivInst returns a new fdiv instruction based on the given type, operands -// and attached metadata. -func NewFDivInst(typ, xVal, yVal, mds interface{}) (*ast.InstFDiv, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFDiv{X: x, Y: y, Metadata: metadata}, nil -} - -// NewURemInst returns a new urem instruction based on the given type, operands -// and attached metadata. -func NewURemInst(typ, xVal, yVal, mds interface{}) (*ast.InstURem, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstURem{X: x, Y: y, Metadata: metadata}, nil -} - -// NewSRemInst returns a new srem instruction based on the given type, operands -// and attached metadata. -func NewSRemInst(typ, xVal, yVal, mds interface{}) (*ast.InstSRem, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstSRem{X: x, Y: y, Metadata: metadata}, nil -} - -// NewFRemInst returns a new frem instruction based on the given type, operands -// and attached metadata. -func NewFRemInst(typ, xVal, yVal, mds interface{}) (*ast.InstFRem, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFRem{X: x, Y: y, Metadata: metadata}, nil -} - -// --- [ Bitwise instructions ] ------------------------------------------------ - -// NewShlInst returns a new shl instruction based on the given type, operands -// and attached metadata. -func NewShlInst(typ, xVal, yVal, mds interface{}) (*ast.InstShl, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstShl{X: x, Y: y, Metadata: metadata}, nil -} - -// NewLShrInst returns a new lshr instruction based on the given type, operands -// and attached metadata. -func NewLShrInst(typ, xVal, yVal, mds interface{}) (*ast.InstLShr, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstLShr{X: x, Y: y, Metadata: metadata}, nil -} - -// NewAShrInst returns a new ashr instruction based on the given type, operands -// and attached metadata. -func NewAShrInst(typ, xVal, yVal, mds interface{}) (*ast.InstAShr, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstAShr{X: x, Y: y, Metadata: metadata}, nil -} - -// NewAndInst returns a new and instruction based on the given type, operands -// and attached metadata. -func NewAndInst(typ, xVal, yVal, mds interface{}) (*ast.InstAnd, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstAnd{X: x, Y: y, Metadata: metadata}, nil -} - -// NewOrInst returns a new or instruction based on the given type, operands and -// attached metadata. -func NewOrInst(typ, xVal, yVal, mds interface{}) (*ast.InstOr, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstOr{X: x, Y: y, Metadata: metadata}, nil -} - -// NewXorInst returns a new xor instruction based on the given type, operands -// and attached metadata. -func NewXorInst(typ, xVal, yVal, mds interface{}) (*ast.InstXor, error) { - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstXor{X: x, Y: y, Metadata: metadata}, nil -} - -// --- [ Vector instructions ] ------------------------------------------------- - -// NewExtractElementInst returns a new extractelement instruction based on the -// given vector, index and attached metadata. -func NewExtractElementInst(xTyp, xVal, indexTyp, indexVal, mds interface{}) (*ast.InstExtractElement, error) { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - index, err := NewValue(indexTyp, indexVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstExtractElement{X: x, Index: index, Metadata: metadata}, nil -} - -// NewInsertElementInst returns a new insertelement instruction based on the -// given vector, element, index and attached metadata. -func NewInsertElementInst(xTyp, xVal, elemTyp, elemVal, indexTyp, indexVal, mds interface{}) (*ast.InstInsertElement, error) { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - elem, err := NewValue(elemTyp, elemVal) - if err != nil { - return nil, errors.WithStack(err) - } - index, err := NewValue(indexTyp, indexVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstInsertElement{X: x, Elem: elem, Index: index, Metadata: metadata}, nil -} - -// NewShuffleVectorInst returns a new shufflevector instruction based on the -// given vectors, shuffle mask and attached metadata. -func NewShuffleVectorInst(xTyp, xVal, yTyp, yVal, maskTyp, maskVal, mds interface{}) (*ast.InstShuffleVector, error) { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - mask, err := NewValue(maskTyp, maskVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstShuffleVector{X: x, Y: y, Mask: mask, Metadata: metadata}, nil -} - -// --- [ Aggregate instructions ] ---------------------------------------------- - -// NewExtractValueInst returns a new extractvalue instruction based on the -// given aggregate value, indices and attached metadata. -func NewExtractValueInst(xTyp, xVal, indices, mds interface{}) (*ast.InstExtractValue, error) { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - is, ok := indices.([]int64) - if !ok { - return nil, errors.Errorf("invalid indices type; expected []int64, got %T", indices) - } - if len(is) < 1 { - return nil, errors.Errorf("invalid indices length; expected > 0, got %d", len(is)) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstExtractValue{X: x, Indices: is, Metadata: metadata}, nil -} - -// NewIntLitList returns a new integer literal list based on the given integer -// literal. -func NewIntLitList(i interface{}) ([]int64, error) { - x, err := getInt64(i) - if err != nil { - return nil, errors.WithStack(err) - } - return []int64{x}, nil -} - -// AppendIntLit appends the given integer literal to the integer literal list. -func AppendIntLit(is, i interface{}) ([]int64, error) { - xs, ok := is.([]int64) - if !ok { - return nil, errors.Errorf("invalid integer literal list type; expected []int64, got %T", is) - } - x, err := getInt64(i) - if err != nil { - return nil, errors.WithStack(err) - } - return append(xs, x), nil -} - -// NewInsertValueInst returns a new insertvalue instruction based on the -// given aggregate value, element, indices and attached metadata. -func NewInsertValueInst(xTyp, xVal, elemTyp, elemVal, indices, mds interface{}) (*ast.InstInsertValue, error) { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - elem, err := NewValue(elemTyp, elemVal) - if err != nil { - return nil, errors.WithStack(err) - } - is, ok := indices.([]int64) - if !ok { - return nil, errors.Errorf("invalid indices type; expected []int64, got %T", indices) - } - if len(is) < 1 { - return nil, errors.Errorf("invalid indices length; expected > 0, got %d", len(is)) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstInsertValue{X: x, Elem: elem, Indices: is, Metadata: metadata}, nil -} - -// --- [ Memory instructions ] ------------------------------------------------- - -// NewAllocaInst returns a new alloca instruction based on the given element -// type, number of elements and attached metadata. -func NewAllocaInst(elem, nelems, mds interface{}) (*ast.InstAlloca, error) { - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - inst := &ast.InstAlloca{Elem: e} - switch nelems := nelems.(type) { - case ast.Value: - inst.NElems = nelems - case nil: - // no nelems. - default: - return nil, errors.Errorf("invalid number of elements type; expected ast.Value or nil, got %T", nelems) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - inst.Metadata = metadata - return inst, nil -} - -// NewLoadInst returns a new load instruction based on the given element type, -// source address type, value and attached metadata. -func NewLoadInst(elem, srcTyp, srcVal, mds interface{}) (*ast.InstLoad, error) { - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - src, err := NewValue(srcTyp, srcVal) - if err != nil { - return nil, errors.WithStack(err) - } - // Store e in InstLoad to evaluate against src.Type().Elem() after type - // resolution. - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstLoad{Elem: e, Src: src, Metadata: metadata}, nil -} - -// NewStoreInst returns a new store instruction based on the given element type, -// source address type, value and attached metadata. -func NewStoreInst(srcTyp, srcVal, dstTyp, dstVal, mds interface{}) (*ast.InstStore, error) { - src, err := NewValue(srcTyp, srcVal) - if err != nil { - return nil, errors.WithStack(err) - } - dst, err := NewValue(dstTyp, dstVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstStore{Src: src, Dst: dst, Metadata: metadata}, nil -} - -// NewGetElementPtrInst returns a new getelementptr instruction based on the -// given element type, source address type and value, element indices and -// attached metadata. -func NewGetElementPtrInst(elem, srcTyp, srcVal, indices, mds interface{}) (*ast.InstGetElementPtr, error) { - e, ok := elem.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid element type; expected ast.Type, got %T", elem) - } - src, err := NewValue(srcTyp, srcVal) - if err != nil { - return nil, errors.WithStack(err) - } - var is []ast.Value - switch indices := indices.(type) { - case []ast.Value: - is = indices - case nil: - // no indices. - default: - return nil, errors.Errorf("invalid indices type; expected []ast.Value or nil, got %T", indices) - } - // Store e in InstGetElementPtr to evaluate against src.Type().Elem() after - // type resolution. - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstGetElementPtr{Elem: e, Src: src, Indices: is, Metadata: metadata}, nil -} - -// --- [ Conversion instructions ] --------------------------------------------- - -// NewTruncInst returns a new trunc instruction based on the given source value, -// target type and attached metadata. -func NewTruncInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstTrunc, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstTrunc{From: from, To: t, Metadata: metadata}, nil -} - -// NewZExtInst returns a new zext instruction based on the given source value, -// target type and attached metadata. -func NewZExtInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstZExt, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstZExt{From: from, To: t, Metadata: metadata}, nil -} - -// NewSExtInst returns a new sext instruction based on the given source value, -// target type and attached metadata. -func NewSExtInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstSExt, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstSExt{From: from, To: t, Metadata: metadata}, nil -} - -// NewFPTruncInst returns a new fptrunc instruction based on the given source -// value, target type and attached metadata. -func NewFPTruncInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstFPTrunc, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFPTrunc{From: from, To: t, Metadata: metadata}, nil -} - -// NewFPExtInst returns a new fpext instruction based on the given source value, -// target type and attached metadata. -func NewFPExtInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstFPExt, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFPExt{From: from, To: t, Metadata: metadata}, nil -} - -// NewFPToUIInst returns a new fptoui instruction based on the given source -// value, target type and attached metadata. -func NewFPToUIInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstFPToUI, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFPToUI{From: from, To: t, Metadata: metadata}, nil -} - -// NewFPToSIInst returns a new fptosi instruction based on the given source -// value, target type and attached metadata. -func NewFPToSIInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstFPToSI, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFPToSI{From: from, To: t, Metadata: metadata}, nil -} - -// NewUIToFPInst returns a new uitofp instruction based on the given source -// value, target type and attached metadata. -func NewUIToFPInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstUIToFP, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstUIToFP{From: from, To: t, Metadata: metadata}, nil -} - -// NewSIToFPInst returns a new sitofp instruction based on the given source -// value, target type and attached metadata. -func NewSIToFPInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstSIToFP, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstSIToFP{From: from, To: t, Metadata: metadata}, nil -} - -// NewPtrToIntInst returns a new ptrtoint instruction based on the given source -// value, target type and attached metadata. -func NewPtrToIntInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstPtrToInt, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstPtrToInt{From: from, To: t, Metadata: metadata}, nil -} - -// NewIntToPtrInst returns a new inttoptr instruction based on the given source -// value, target type and attached metadata. -func NewIntToPtrInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstIntToPtr, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstIntToPtr{From: from, To: t, Metadata: metadata}, nil -} - -// NewBitCastInst returns a new bitcast instruction based on the given source -// value, target type and attached metadata. -func NewBitCastInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstBitCast, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstBitCast{From: from, To: t, Metadata: metadata}, nil -} - -// NewAddrSpaceCastInst returns a new addrspacecast instruction based on the -// given source value, target type and attached metadata. -func NewAddrSpaceCastInst(fromTyp, fromVal, to, mds interface{}) (*ast.InstAddrSpaceCast, error) { - from, err := NewValue(fromTyp, fromVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := to.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", to) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstAddrSpaceCast{From: from, To: t, Metadata: metadata}, nil -} - -// --- [ Other instructions ] -------------------------------------------------- - -// NewICmpInst returns a new icmp instruction based on the given integer -// predicate, type, operands and attached metadata. -func NewICmpInst(pred, typ, xVal, yVal, mds interface{}) (*ast.InstICmp, error) { - p, ok := pred.(ast.IntPred) - if !ok { - return nil, errors.Errorf("invalid integer predicate type; expected ast.IntPred, got %T", pred) - } - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstICmp{Pred: p, X: x, Y: y, Metadata: metadata}, nil -} - -// NewFCmpInst returns a new fcmp instruction based on the given floating-point -// predicate, type, operands and attached metadata. -func NewFCmpInst(pred, typ, xVal, yVal, mds interface{}) (*ast.InstFCmp, error) { - p, ok := pred.(ast.FloatPred) - if !ok { - return nil, errors.Errorf("invalid floating-point predicate type; expected ast.FloatPred, got %T", pred) - } - x, err := NewValue(typ, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(typ, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstFCmp{Pred: p, X: x, Y: y, Metadata: metadata}, nil -} - -// NewPhiInst returns a new phi instruction based on the given incoming values -// and attached metadata. -func NewPhiInst(typ, incs, mds interface{}) (*ast.InstPhi, error) { - t, ok := typ.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid type; expected ast.Type, got %T", typ) - } - is, ok := incs.([]*ast.Incoming) - if !ok { - return nil, errors.Errorf("invalid incoming value list type; expected []*ast.Incoming, got %T", incs) - } - for _, inc := range is { - x, err := NewValue(t, inc.X) - if err != nil { - return nil, errors.WithStack(err) - } - inc.X = x - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstPhi{Type: t, Incs: is, Metadata: metadata}, nil -} - -// NewIncomingList returns a new incoming value list based on the given incoming -// value. -func NewIncomingList(inc interface{}) ([]*ast.Incoming, error) { - i, ok := inc.(*ast.Incoming) - if !ok { - return nil, errors.Errorf("invalid incoming value type; expected *ast.Incoming, got %T", inc) - } - return []*ast.Incoming{i}, nil -} - -// AppendIncoming appends the given incoming value to the incoming value list. -func AppendIncoming(incs, inc interface{}) ([]*ast.Incoming, error) { - is, ok := incs.([]*ast.Incoming) - if !ok { - return nil, errors.Errorf("invalid incoming value list type; expected []*ast.Incoming, got %T", incs) - } - i, ok := inc.(*ast.Incoming) - if !ok { - return nil, errors.Errorf("invalid incoming value type; expected *ast.Incoming, got %T", inc) - } - return append(is, i), nil -} - -// NewIncoming returns a new incoming value based on the given value and -// predecessor basic block. -func NewIncoming(x, pred interface{}) (*ast.Incoming, error) { - xx, err := NewValue(&ast.TypeDummy{}, x) - if err != nil { - return nil, errors.WithStack(err) - } - pp, err := NewValue(&ast.TypeDummy{}, pred) - if err != nil { - return nil, errors.WithStack(err) - } - p, ok := pp.(ast.NamedValue) - if !ok { - return nil, errors.Errorf("invalid predecessor type; expected ast.NamedValue, got %T", pp) - } - return &ast.Incoming{X: xx, Pred: p}, nil -} - -// NewSelectInst returns a new select instruction based on the given selection -// condition type and value, operands and attached metadata. -func NewSelectInst(condTyp, condVal, xTyp, xVal, yTyp, yVal, mds interface{}) (*ast.InstSelect, error) { - cond, err := NewValue(condTyp, condVal) - if err != nil { - return nil, errors.WithStack(err) - } - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - y, err := NewValue(yTyp, yVal) - if err != nil { - return nil, errors.WithStack(err) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstSelect{Cond: cond, X: x, Y: y, Metadata: metadata}, nil -} - -// NewCallInst returns a new call instruction based on the given return type, -// callee name, function arguments and attached metadata. -func NewCallInst(callconv, retTyp, callee, args, mds interface{}) (*ast.InstCall, error) { - cconv, ok := callconv.(ast.CallConv) - if !ok { - return nil, errors.Errorf("invalid calling convention type; expected ast.CallConv, got %T", callconv) - } - r, ok := retTyp.(ast.Type) - if !ok { - return nil, errors.Errorf("invalid return type; expected ast.Type, got %T", retTyp) - } - // Ad-hoc solution to update the type of bitcast expressions used as callees - // in call instructions. Note, the LLVM IR syntax of call instructions does - // not pertain all type information of the callee value use. E.g. - // - // %42 = call i32 bitcast (i32 (...)* @open to i32 (i8*, i32, ...)*)(i8* %41, i32 0) - calleeType := r - if cc, ok := callee.(*ast.ExprBitCast); ok { - ccType, ok := cc.To.(*ast.PointerType) - if !ok { - return nil, errors.Errorf("invalid to type of callee bitcast expression; expected *ast.PointerType, got %T", cc.To) - } - if _, ok := ccType.Elem.(*ast.FuncType); !ok { - return nil, errors.Errorf("invalid to type of callee type pointer elem; expected *ast.FuncType, got %T", ccType.Elem) - } - // Infer the proper type of retType. - if rTyp, ok := retTyp.(*ast.FuncType); ok { - calleeType = &ast.PointerType{Elem: rTyp} - } else { - // Ignore retType if containing incomplete type information. - calleeType = ccType - } - } - c, err := NewValue(calleeType, callee) - if err != nil { - return nil, errors.WithStack(err) - } - var as []ast.Value - switch args := args.(type) { - case []ast.Value: - as = args - case nil: - // no arguments. - default: - return nil, errors.Errorf("invalid function arguments type; expected []ast.Value or nil, got %T", args) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.InstCall{Type: r, Callee: c, Args: as, CallConv: cconv, Metadata: metadata}, nil -} - -// === [ Terminators ] ========================================================= - -// --- [ ret ] ----------------------------------------------------------------- - -// NewRetTerm returns a new ret terminator based on the given return type, -// value and attached metadata. -func NewRetTerm(xTyp, xVal, mds interface{}) (*ast.TermRet, error) { - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - if xTyp != nil && xVal != nil { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.TermRet{X: x, Metadata: metadata}, nil - } - return &ast.TermRet{Metadata: metadata}, nil -} - -// --- [ br ] ------------------------------------------------------------------ - -// NewBrTerm returns a new unconditional br terminator based on the given target -// branch and attached metadata. -func NewBrTerm(targetTyp, targetVal, mds interface{}) (*ast.TermBr, error) { - target, err := NewValue(targetTyp, targetVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := target.(ast.NamedValue) - if !ok { - return nil, errors.Errorf("invalid target branch type; expected ast.NamedValue, got %T", target) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.TermBr{Target: t, Metadata: metadata}, nil -} - -// --- [ conditional br ] ------------------------------------------------------ - -// NewCondBrTerm returns a new conditional br terminator based on the given -// branching condition type and value, conditional target branches and attached -// metadata. -func NewCondBrTerm(condTyp, condVal, targetTrueTyp, targetTrueVal, targetFalseTyp, targetFalseVal, mds interface{}) (*ast.TermCondBr, error) { - cond, err := NewValue(condTyp, condVal) - if err != nil { - return nil, errors.WithStack(err) - } - targetTrue, err := NewValue(targetTrueTyp, targetTrueVal) - if err != nil { - return nil, errors.WithStack(err) - } - tTrue, ok := targetTrue.(ast.NamedValue) - if !ok { - return nil, errors.Errorf("invalid true target branch type; expected ast.NamedValue, got %T", targetTrue) - } - targetFalse, err := NewValue(targetFalseTyp, targetFalseVal) - if err != nil { - return nil, errors.WithStack(err) - } - tFalse, ok := targetFalse.(ast.NamedValue) - if !ok { - return nil, errors.Errorf("invalid false target branch type; expected ast.NamedValue, got %T", targetFalse) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.TermCondBr{Cond: cond, TargetTrue: tTrue, TargetFalse: tFalse, Metadata: metadata}, nil -} - -// --- [ switch ] -------------------------------------------------------------- - -// NewSwitchTerm returns a new switch terminator based on the given control -// variable type and value, default target branch, switch cases and attached -// metadata. -func NewSwitchTerm(xTyp, xVal, targetDefaultTyp, targetDefaultVal, cases, mds interface{}) (*ast.TermSwitch, error) { - x, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - targetDefault, err := NewValue(targetDefaultTyp, targetDefaultVal) - if err != nil { - return nil, errors.WithStack(err) - } - tDefault, ok := targetDefault.(ast.NamedValue) - if !ok { - return nil, errors.Errorf("invalid default target branch type; expected ast.NamedValue, got %T", targetDefault) - } - var cs []*ast.Case - switch cases := cases.(type) { - case []*ast.Case: - cs = cases - case nil: - // no cases. - default: - return nil, errors.Errorf("invalid switch cases type; expected []*ast.Case or nil, got %T", cases) - } - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.TermSwitch{X: x, TargetDefault: tDefault, Cases: cs, Metadata: metadata}, nil -} - -// NewCaseList returns a new switch case list based on the given case. -func NewCaseList(switchCase interface{}) ([]*ast.Case, error) { - c, ok := switchCase.(*ast.Case) - if !ok { - return nil, errors.Errorf("invalid switch case type; expected *ast.Case, got %T", switchCase) - } - return []*ast.Case{c}, nil -} - -// AppendCase appends the given case to the switch case list. -func AppendCase(cases, switchCase interface{}) ([]*ast.Case, error) { - cs, ok := cases.([]*ast.Case) - if !ok { - return nil, errors.Errorf("invalid switch case list type; expected []*ast.Case, got %T", cases) - } - c, ok := switchCase.(*ast.Case) - if !ok { - return nil, errors.Errorf("invalid switch case type; expected *ast.Case, got %T", switchCase) - } - return append(cs, c), nil -} - -// NewCase returns a new switch case based on the given case comparand, target -// branch and attached metadata. -func NewCase(xTyp, xVal, targetTyp, targetVal interface{}) (*ast.Case, error) { - xValue, err := NewValue(xTyp, xVal) - if err != nil { - return nil, errors.WithStack(err) - } - x, ok := xValue.(*ast.IntConst) - if !ok { - return nil, errors.Errorf("invalid case comparand type; expected *ast.IntConst, got %T", xValue) - } - target, err := NewValue(targetTyp, targetVal) - if err != nil { - return nil, errors.WithStack(err) - } - t, ok := target.(ast.NamedValue) - if !ok { - return nil, errors.Errorf("invalid target branch type; expected ast.NamedValue, got %T", target) - } - return &ast.Case{X: x, Target: t}, nil -} - -// NewUnreachableTerm returns a new unreachable terminator based on the given -// attached metadata. -func NewUnreachableTerm(mds interface{}) (*ast.TermUnreachable, error) { - metadata, err := uniqueMetadata(mds) - if err != nil { - return nil, errors.WithStack(err) - } - return &ast.TermUnreachable{Metadata: metadata}, nil -} - -// ### [ Helper functions ] #################################################### - -// getTokenString returns the string literal of the given token. -func getTokenString(tok interface{}) (string, error) { - t, ok := tok.(*token.Token) - if !ok { - return "", errors.Errorf("invalid token type; expected *token.Token, got %T", tok) - } - return string(t.Lit), nil -} - -// getInt64 returns the int64 representation of the given integer literal. -func getInt64(lit interface{}) (int64, error) { - l, ok := lit.(*IntLit) - if !ok { - return 0, errors.Errorf("invalid integer literal type; expected *astx.IntLit, got %T", lit) - } - n, err := strconv.ParseInt(l.lit, 10, 64) - if err != nil { - return 0, errors.WithStack(err) - } - return n, nil -} - -// NewAttachedMDList returns a new attached metadata list based on the given -// attached metadata. -func NewAttachedMDList(md interface{}) ([]*ast.AttachedMD, error) { - m, ok := md.(*ast.AttachedMD) - if !ok { - return nil, errors.Errorf("invalid attached metadata type; expected *ast.AttachedMD, got %T", md) - } - return []*ast.AttachedMD{m}, nil -} - -// AppendAttachedMD appends the given attached metadata to the attached metadata -// list. -func AppendAttachedMD(mds, md interface{}) ([]*ast.AttachedMD, error) { - ms, ok := mds.([]*ast.AttachedMD) - if !ok { - return nil, errors.Errorf("invalid attached metadata list type; expected []*ast.AttachedMD, got %T", mds) - } - m, ok := md.(*ast.AttachedMD) - if !ok { - return nil, errors.Errorf("invalid attached metadata type; expected *ast.AttachedMD, got %T", md) - } - return append(ms, m), nil -} - -// NewAttachedMD returns a new attached metadata based on the given metadata -// name and metadata. -func NewAttachedMD(name, md interface{}) (*ast.AttachedMD, error) { - n, ok := name.(*MetadataName) - if !ok { - return nil, errors.Errorf("invalid metadata name type; expected *astx.MetadataName, got %T", name) - } - var node ast.MetadataNode - switch md := md.(type) { - case *ast.Metadata: - node = md - case *ast.MetadataIDDummy: - node = md - default: - return nil, errors.Errorf("invalid metadata type; expected *ast.Metadata or *ast.MetadataIDDummy, got %T", md) - } - return &ast.AttachedMD{Name: unquote(n.name), Metadata: node}, nil -} - -// unquote returns the unquoted version of the given string, if quoted, and the -// original string otherwise. -func unquote(s string) string { - if strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`) { - return enc.Unquote(s) - } - return s -} - -// uniqueMetadata returns the unique metadata of a value based on the given list -// of attached metadata. -func uniqueMetadata(mds interface{}) ([]*ast.AttachedMD, error) { - var ms []*ast.AttachedMD - switch mds := mds.(type) { - case []*ast.AttachedMD: - ms = mds - case nil: - // no attached metadata. - return nil, nil - default: - return nil, errors.Errorf("invalid attached metadata list type; expected []*ast.AttachedMD or nil, got %T", mds) - } - unique := make(map[string]ast.MetadataNode) - var metadata []*ast.AttachedMD - for _, md := range ms { - if prev, ok := unique[md.Name]; ok { - return nil, errors.Errorf("attached metadata for metadata name %q already present; previous `%v`, new `%v`", md.Name, prev, md.Metadata) - } - unique[md.Name] = md.Metadata - metadata = append(metadata, md) - } - return metadata, nil -} diff --git a/llvm/asm/internal/astx/fix.go b/llvm/asm/internal/astx/fix.go deleted file mode 100755 index 9bbda07..0000000 --- a/llvm/asm/internal/astx/fix.go +++ /dev/null @@ -1,366 +0,0 @@ -// Fix dummy values as follows. -// -// Per module. -// -// 1. Index type definitions. -// 2. Index global variables. -// 3. Index functions. -// 4. Index metadata. -// 5. Fix type definitions. -// 6. Resolve named types. -// 7. Resolve global identifiers. -// 8. Resolve metadata nodes. -// -// Per function. -// -// 1. Assign unique local IDs to unnamed basic blocks and instructions. -// 2. Index basic blocks. -// 3. Index function parameters. -// 4. Index local variables produced by instructions. -// 5. Resolve local identifiers. - -package astx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/asm/internal/ast/astutil" - "github.com/geode-lang/geode/llvm/enc" -) - -// === [ Modules ] ============================================================= - -// fixModule replaces dummy values within the given module with their real -// values. -func fixModule(m *ast.Module) *ast.Module { - fix := &fixer{ - globals: make(map[string]ast.NamedValue), - types: make(map[string]*ast.NamedType), - metadata: make(map[string]*ast.Metadata), - } - - // Index type definitions. - for _, typ := range m.Types { - name := typ.Name - if _, ok := fix.types[name]; ok { - panic(fmt.Errorf("type name %q already present; old `%v`, new `%v`", name, fix.types[name], typ)) - } - fix.types[name] = typ - } - - // Index global variables. - for _, global := range m.Globals { - name := global.Name - if _, ok := fix.globals[name]; ok { - panic(fmt.Errorf("global identifier %q already present; old `%v`, new `%v`", name, fix.globals[name], global)) - } - fix.globals[name] = global - } - - // Index functions. - for _, f := range m.Funcs { - name := f.Name - if _, ok := fix.globals[name]; ok { - panic(fmt.Errorf("global identifier %q already present; old `%v`, new `%v`", name, fix.globals[name], f)) - } - fix.globals[name] = f - } - - // Index metadata. - for _, md := range m.Metadata { - id := md.ID - if _, ok := fix.metadata[id]; ok { - panic(fmt.Errorf("metadata ID %q already present; old `%v`, new `%v`", id, fix.metadata[id], md)) - } - fix.metadata[id] = md - } - - // Fix type definitions. - for _, typ := range m.Types { - typ.Def = fix.fixType(typ.Def) - } - - // Resolve named types. - resolveTypes := func(node interface{}) { - p, ok := node.(*ast.Type) - if !ok { - return - } - old, ok := (*p).(*ast.NamedTypeDummy) - if !ok { - return - } - typ := fix.getType(old.Name) - if typ.Def == nil { - panic(fmt.Errorf("invalid type definition %q; expected underlying definition, got nil", typ.Name)) - } - *p = typ - } - astutil.Walk(m, resolveTypes) - - // Resolve values of global identifiers. - resolveGlobals := func(node interface{}) { - p, ok := node.(*ast.Value) - if !ok { - return - } - old, ok := (*p).(*ast.GlobalDummy) - if !ok { - return - } - global := fix.getGlobal(old.Name) - // TODO: Validate type of old and new global. - *p = global - } - astutil.Walk(m, resolveGlobals) - - // Resolve named values of global identifiers. - resolveNamedGlobals := func(node interface{}) { - p, ok := node.(*ast.NamedValue) - if !ok { - return - } - old, ok := (*p).(*ast.GlobalDummy) - if !ok { - return - } - global := fix.getGlobal(old.Name) - // TODO: Validate type of old and new global. - *p = global - } - astutil.Walk(m, resolveNamedGlobals) - - // Resolve constants of global identifiers. - resolveConstantGlobals := func(node interface{}) { - p, ok := node.(*ast.Constant) - if !ok { - return - } - old, ok := (*p).(*ast.GlobalDummy) - if !ok { - return - } - global := fix.getGlobal(old.Name) - g, ok := global.(ast.Constant) - if !ok { - panic(fmt.Errorf("invalid global type of %q; expected ast.Constant, got %T", global.GetName(), global)) - } - // TODO: Validate type of old and new global. - *p = g - } - astutil.Walk(m, resolveConstantGlobals) - - // Fix functions. - for _, f := range m.Funcs { - fix.fixFunc(f) - } - - // Resolve metadata nodes. - resolveMetadataNodes := func(node interface{}) { - switch p := node.(type) { - case *ast.MetadataNode: - if old, ok := (*p).(*ast.MetadataIDDummy); ok { - metadata := fix.getMetadata(old.ID) - *p = metadata - } - case *ast.Value: - if old, ok := (*p).(*ast.MetadataIDDummy); ok { - metadata := fix.getMetadata(old.ID) - *p = metadata - } - } - } - astutil.Walk(m, resolveMetadataNodes) - - return m -} - -// === [ Type definitions ] ==================================================== - -// fixType replaces dummy types within the given type with their real types. -func (fix *fixer) fixType(old ast.Type) ast.Type { - switch old := old.(type) { - case *ast.VoidType: - // nothing to do. - case *ast.FuncType: - old.Ret = fix.fixType(old.Ret) - for _, param := range old.Params { - param.Type = fix.fixType(param.Type) - } - case *ast.IntType: - // nothing to do. - case *ast.FloatType: - // nothing to do. - case *ast.PointerType: - old.Elem = fix.fixType(old.Elem) - case *ast.VectorType: - old.Elem = fix.fixType(old.Elem) - case *ast.LabelType: - // nothing to do. - case *ast.MetadataType: - // nothing to do. - case *ast.ArrayType: - old.Elem = fix.fixType(old.Elem) - case *ast.StructType: - for i, field := range old.Fields { - old.Fields[i] = fix.fixType(field) - } - case *ast.NamedType: - if old.Def == nil { - old.Def = fix.getType(old.Name) - } - case *ast.NamedTypeDummy: - return fix.getType(old.Name) - default: - panic(fmt.Errorf("support for type %T not yet implemented", old)) - } - return old -} - -// === [ Functions ] =========================================================== - -// fixFunc replaces dummy values within the given function with their real -// values. -func (fix *fixer) fixFunc(f *ast.Function) { - // Early exit if function declaration. - if len(f.Blocks) < 1 { - return - } - - // Reset locals. - fix.locals = make(map[string]ast.NamedValue) - - // Assign unique local IDs to unnamed basic blocks and instructions. - f.AssignIDs() - - // Index basic blocks. - for _, block := range f.Blocks { - name := block.Name - if _, ok := fix.locals[name]; ok { - panic(fmt.Errorf("basic block label %q already present for function %s; old `%v`, new `%v`", name, enc.Global(f.Name), fix.locals[name], block)) - } - fix.locals[name] = block - } - - // Index function parameters. - for _, param := range f.Sig.Params { - name := param.Name - if _, ok := fix.locals[name]; ok { - panic(fmt.Errorf("function parameter name %q already present for function %s; old `%v`, new `%v`", name, enc.Global(f.Name), fix.locals[name], param)) - } - fix.locals[name] = param - } - - // Index local variables produced by instructions. - for _, block := range f.Blocks { - for _, inst := range block.Insts { - if inst, ok := inst.(ast.NamedValue); ok { - // Ignore local value if of type void. - if inst, ok := inst.(*ast.InstCall); ok { - if _, ok := inst.Type.(*ast.VoidType); ok { - continue - } - if sig, ok := inst.Type.(*ast.FuncType); ok { - if _, ok := sig.Ret.(*ast.VoidType); ok { - continue - } - } - } - name := inst.GetName() - if _, ok := fix.locals[name]; ok { - panic(fmt.Errorf("instruction name %q already present for function %s; old `%v`, new `%v`", name, enc.Global(f.Name), fix.locals[name], inst)) - } - fix.locals[name] = inst - } - } - } - - // Resolve values of local identifiers. - resolveLocals := func(node interface{}) { - p, ok := node.(*ast.Value) - if !ok { - return - } - old, ok := (*p).(*ast.LocalDummy) - if !ok { - return - } - local := fix.getLocal(old.Name) - // TODO: Validate type of old and new local. - *p = local - } - astutil.WalkFunc(f, resolveLocals) - - // Resolve named values of local identifiers. - resolveNamedLocals := func(node interface{}) { - p, ok := node.(*ast.NamedValue) - if !ok { - return - } - old, ok := (*p).(*ast.LocalDummy) - if !ok { - return - } - local := fix.getLocal(old.Name) - // TODO: Validate type of old and new local. - *p = local - } - astutil.WalkFunc(f, resolveNamedLocals) -} - -// ### [ Helper functions ] #################################################### - -// A fixer keeps track of global and local identifiers to replace dummy values -// with their real values. -type fixer struct { - // Per module. - - // types maps from type identifiers to their real types. - types map[string]*ast.NamedType - // globals maps global identifiers to their real values. - globals map[string]ast.NamedValue - // metadata maps metadata IDs to their real metadata. - metadata map[string]*ast.Metadata - - // Per function. - - // locals maps local identifiers to their real values. - locals map[string]ast.NamedValue -} - -// getType returns the type of the given type name. -func (fix *fixer) getType(name string) *ast.NamedType { - typ, ok := fix.types[name] - if !ok { - panic(fmt.Errorf("unable to locate type name %q", name)) - } - return typ -} - -// getGlobal returns the global value of the given global identifier. -func (fix *fixer) getGlobal(name string) ast.NamedValue { - global, ok := fix.globals[name] - if !ok { - panic(fmt.Errorf("unable to locate global identifier %q", name)) - } - return global -} - -// getMetadata returns the metadata of the given metadata ID. -func (fix *fixer) getMetadata(id string) *ast.Metadata { - metadata, ok := fix.metadata[id] - if !ok { - panic(fmt.Errorf("unable to locate metadata ID %q", enc.Metadata(id))) - } - return metadata -} - -// getLocal returns the local value of the given local identifier. -func (fix *fixer) getLocal(name string) ast.NamedValue { - local, ok := fix.locals[name] - if !ok { - panic(fmt.Errorf("unable to locate local identifier %q", name)) - } - return local -} diff --git a/llvm/asm/internal/irx/asm_test.go b/llvm/asm/internal/irx/asm_test.go deleted file mode 100755 index 544f8bf..0000000 --- a/llvm/asm/internal/irx/asm_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package irx_test - -import ( - "fmt" - "io/ioutil" - "testing" - - "github.com/geode-lang/geode/llvm/asm" - "github.com/sergi/go-diff/diffmatchpatch" -) - -func TestRoundTrip(t *testing.T) { - // Round-trip test of the parser. - golden := []struct { - path string - }{ - // Empty module. - {path: "../../testdata/empty.ll"}, - // Top-level declarations. - {path: "../../testdata/module.ll"}, - {path: "../../testdata/global.ll"}, - {path: "../../testdata/global_circular.ll"}, - {path: "../../testdata/func.ll"}, - {path: "../../testdata/metadata.ll"}, - // Types. - {path: "../../testdata/type.ll"}, - // Constants. - {path: "../../testdata/const.ll"}, - // Constant expressions. - {path: "../../testdata/expr_binary.ll"}, - {path: "../../testdata/expr_bitwise.ll"}, - {path: "../../testdata/expr_vector.ll"}, - {path: "../../testdata/expr_aggregate.ll"}, - {path: "../../testdata/expr_memory.ll"}, - {path: "../../testdata/expr_conversion.ll"}, - {path: "../../testdata/expr_other.ll"}, - // Instructions. - {path: "../../testdata/inst_binary.ll"}, - {path: "../../testdata/inst_bitwise.ll"}, - {path: "../../testdata/inst_vector.ll"}, - {path: "../../testdata/inst_aggregate.ll"}, - {path: "../../testdata/inst_memory.ll"}, - {path: "../../testdata/inst_conversion.ll"}, - {path: "../../testdata/inst_other.ll"}, - // Terminators. - {path: "../../testdata/term.ll"}, - // Pseudo-random number generator. - {path: "../../testdata/rand.ll"}, - // Inline assembly. - {path: "../../testdata/inline_asm.ll"}, - // Fixed bugs. - {path: "../../testdata/fixedbugs/issue_27.ll"}, - {path: "../../testdata/fixedbugs/issue_28.ll"}, - } - dmp := diffmatchpatch.New() - for _, g := range golden { - buf, err := ioutil.ReadFile(g.path) - if err != nil { - t.Errorf("%q: unable to read file; %v", g.path, err) - continue - } - input := string(buf) - m, err := asm.ParseString(input) - if err != nil { - t.Errorf("%q: unable to parse file; %v", g.path, err) - continue - } - want := input - // Read foo.ll.golden if present. - if buf, err := ioutil.ReadFile(g.path + ".golden"); err == nil { - want = string(buf) - } - got := m.String() - if want != got { - diffs := dmp.DiffMain(want, got, false) - fmt.Println(dmp.DiffPrettyText(diffs)) - t.Errorf("%q: module mismatch; expected `%v`, got `%v`", g.path, want, got) - continue - } - } -} diff --git a/llvm/asm/internal/irx/constant.go b/llvm/asm/internal/irx/constant.go deleted file mode 100755 index edf77c5..0000000 --- a/llvm/asm/internal/irx/constant.go +++ /dev/null @@ -1,462 +0,0 @@ -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/ir" - "github.com/geode-lang/geode/llvm/ir/constant" - "github.com/geode-lang/geode/llvm/ir/types" - "github.com/pkg/errors" -) - -// irConstant returns the corresponding LLVM IR constant of the given constant. -func (m *Module) irConstant(old ast.Constant) constant.Constant { - switch old := old.(type) { - // Simple constants - case *ast.IntConst: - return constant.NewIntFromString(old.Lit, m.irType(old.Type)) - case *ast.FloatConst: - return constant.NewFloatFromString(old.Lit, m.irType(old.Type)) - case *ast.NullConst: - return constant.NewNull(m.irType(old.Type)) - - // Complex constants - case *ast.VectorConst: - var elems []constant.Constant - for _, oldElem := range old.Elems { - elems = append(elems, m.irConstant(oldElem)) - } - c := constant.NewVector(elems...) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("vector type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ArrayConst: - // Handle empty array constants. - if len(old.Elems) == 0 { - typ := m.irType(old.Type) - t, ok := typ.(*types.ArrayType) - if !ok { - panic(errors.Errorf("invalid array type; expected *types.ArrayType, got %T", typ)) - } - if t.Len != 0 { - panic(errors.Errorf("invalid number of array elements; expected 0, got %d", t.Len)) - } - c := &constant.Array{ - Typ: t, - } - return c - } - var elems []constant.Constant - for _, oldElem := range old.Elems { - elems = append(elems, m.irConstant(oldElem)) - } - c := constant.NewArray(elems...) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("array type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.CharArrayConst: - // Handle empty character array constants. - if len(old.Lit) == 0 { - typ := m.irType(old.Type) - t, ok := typ.(*types.ArrayType) - if !ok { - panic(errors.Errorf("invalid array type; expected *types.ArrayType, got %T", typ)) - } - if t.Len != 0 { - panic(errors.Errorf("invalid number of array elements; expected 0, got %d", t.Len)) - } - c := &constant.Array{ - Typ: t, - CharArray: true, - } - return c - } - var elems []constant.Constant - for i := 0; i < len(old.Lit); i++ { - b := int64(old.Lit[i]) - elem := constant.NewInt(b, types.I8) - elems = append(elems, elem) - } - c := constant.NewArray(elems...) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("character array type mismatch; expected `%v`, got `%v`", want, got)) - } - c.CharArray = true - return c - case *ast.StructConst: - var fields []constant.Constant - for _, oldField := range old.Fields { - fields = append(fields, m.irConstant(oldField)) - } - c := constant.NewStruct(fields...) - got := c.Typ - oldType := m.irType(old.Type) - want, ok := oldType.(*types.StructType) - if !ok { - panic(fmt.Errorf("invalid struct type; expected *types.StructType, got %T", oldType)) - } - // TODO: Figure out how to validate the bodies of got and want. After name - // is copied from want to got, only name identity is used for type - // equality. - got.Name = want.Name - if !got.Equal(want) { - err := errors.Errorf("struct type mismatch; expected `%v`, got `%v`", want, got) - m.errs = append(m.errs, err) - } - return c - case *ast.ZeroInitializerConst: - return constant.NewZeroInitializer(m.irType(old.Type)) - case *ast.UndefConst: - return constant.NewUndef(m.irType(old.Type)) - - // Global variable and function addresses - case *ast.Global: - // TODO: Validate old.Type against type of resolved global? - // Not possible currently, as globals have already been resolved by astx. - // Consider postponing global resolution until irx, so that - // *ast.GlobalDummy.Type may be compared against global.Type. - v := m.getGlobal(old.Name) - global, ok := v.(*ir.Global) - if !ok { - panic(fmt.Errorf("invalid global type; expected *ir.Global, got %T", v)) - } - return global - case *ast.Function: - // TODO: Validate old.Type against type of resolved function? - // Not possible currently, as globals have already been resolved by astx. - // Consider postponing global resolution until irx, so that - // *ast.GlobalDummy.Type may be compared against f.Type. - v := m.getGlobal(old.Name) - f, ok := v.(*ir.Function) - if !ok { - panic(fmt.Errorf("invalid function type; expected *ir.Function, got %T", v)) - } - return f - - // Binary expressions - case *ast.ExprAdd: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewAdd(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("add expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFAdd: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewFAdd(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fadd expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprSub: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewSub(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("sub expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFSub: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewFSub(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fsub expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprMul: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewMul(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("mul expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFMul: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewFMul(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fmul expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprUDiv: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewUDiv(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("udiv expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprSDiv: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewSDiv(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("sdiv expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFDiv: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewFDiv(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fdiv expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprURem: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewURem(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("urem expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprSRem: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewSRem(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("srem expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFRem: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewFRem(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("frem expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - // Bitwise expressions - case *ast.ExprShl: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewShl(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("shl expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprLShr: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewLShr(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("lshr expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprAShr: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewAShr(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("ashr expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprAnd: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewAnd(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("and expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprOr: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewOr(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("or expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprXor: - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewXor(x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("xor expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - // Aggregate expressions - case *ast.ExprExtractValue: - x := m.irConstant(old.X) - c := constant.NewExtractValue(x, old.Indices) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("extractvalue expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprInsertValue: - x, elem := m.irConstant(old.X), m.irConstant(old.Elem) - c := constant.NewInsertValue(x, elem, old.Indices) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("insertvalue expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - // Vector expressions - case *ast.ExprExtractElement: - x, index := m.irConstant(old.X), m.irConstant(old.Index) - c := constant.NewExtractElement(x, index) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("extractelement expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprInsertElement: - x, elem, index := m.irConstant(old.X), m.irConstant(old.Elem), m.irConstant(old.Index) - c := constant.NewInsertElement(x, elem, index) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("insertelement expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprShuffleVector: - x, y, mask := m.irConstant(old.X), m.irConstant(old.Y), m.irConstant(old.Mask) - c := constant.NewShuffleVector(x, y, mask) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("shufflevector expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - // Memory expressions - case *ast.ExprGetElementPtr: - src := m.irConstant(old.Src) - if srcType, ok := src.Type().(*types.PointerType); !ok { - panic(errors.Errorf("invalid source type; expected *types.PointerType, got %T", src.Type())) - } else if got, want := srcType.Elem, m.irType(old.Elem); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("source element type mismatch; expected `%v`, got `%v`", want, got)) - } - var indices []constant.Constant - for _, oldIndex := range old.Indices { - index := m.irConstant(oldIndex) - indices = append(indices, index) - } - c := constant.NewGetElementPtr(src, indices...) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("getelementptr expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - // Conversion expressions - case *ast.ExprTrunc: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewTrunc(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("trunc expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprZExt: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewZExt(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("zext expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprSExt: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewSExt(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("sext expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFPTrunc: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewFPTrunc(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fptrunc expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFPExt: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewFPExt(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fpext expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFPToUI: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewFPToUI(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fptoui expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFPToSI: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewFPToSI(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fptosi expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprUIToFP: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewUIToFP(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("uitofp expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprSIToFP: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewSIToFP(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("sitofp expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprPtrToInt: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewPtrToInt(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("ptrtoint expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprIntToPtr: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewIntToPtr(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("inttoptr expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprBitCast: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewBitCast(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("bitcast expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprAddrSpaceCast: - from := m.irConstant(old.From) - to := m.irType(old.To) - c := constant.NewAddrSpaceCast(from, to) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("addrspacecast expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - // Other expressions - case *ast.ExprICmp: - cond := constant.IntPred(irIntPred(old.Pred)) - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewICmp(cond, x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("icmp expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprFCmp: - cond := constant.FloatPred(irFloatPred(old.Pred)) - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewFCmp(cond, x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("fcmp expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - case *ast.ExprSelect: - cond := m.irConstant(old.Cond) - x, y := m.irConstant(old.X), m.irConstant(old.Y) - c := constant.NewSelect(cond, x, y) - if got, want := c.Type(), m.irType(old.Type); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("select expression type mismatch; expected `%v`, got `%v`", want, got)) - } - return c - - default: - panic(fmt.Errorf("support for constant %T not yet implemented", old)) - } -} diff --git a/llvm/asm/internal/irx/inst.go b/llvm/asm/internal/irx/inst.go deleted file mode 100755 index 9170a0c..0000000 --- a/llvm/asm/internal/irx/inst.go +++ /dev/null @@ -1,937 +0,0 @@ -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/enc" - "github.com/geode-lang/geode/llvm/ir" - "github.com/geode-lang/geode/llvm/ir/constant" - "github.com/geode-lang/geode/llvm/ir/types" - "github.com/geode-lang/geode/llvm/ir/value" - "github.com/pkg/errors" -) - -// --- [ Binary instructions ] ------------------------------------------------- - -// instAdd resolves the given add instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instAdd(old *ast.InstAdd, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstAdd) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstAdd, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFAdd resolves the given fadd instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFAdd(old *ast.InstFAdd, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFAdd) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFAdd, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instSub resolves the given sub instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instSub(old *ast.InstSub, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstSub) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstSub, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFSub resolves the given fsub instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFSub(old *ast.InstFSub, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFSub) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFSub, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instMul resolves the given mul instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instMul(old *ast.InstMul, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstMul) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstMul, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFMul resolves the given fmul instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFMul(old *ast.InstFMul, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFMul) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFMul, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instUDiv resolves the given udiv instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instUDiv(old *ast.InstUDiv, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstUDiv) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstUDiv, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instSDiv resolves the given sdiv instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instSDiv(old *ast.InstSDiv, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstSDiv) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstSDiv, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFDiv resolves the given fdiv instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFDiv(old *ast.InstFDiv, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFDiv) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFDiv, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instURem resolves the given urem instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instURem(old *ast.InstURem, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstURem) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstURem, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instSRem resolves the given srem instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instSRem(old *ast.InstSRem, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstSRem) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstSRem, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFRem resolves the given frem instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFRem(old *ast.InstFRem, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFRem) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFRem, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// --- [ Bitwise instructions ] ------------------------------------------------ - -// instShl resolves the given shl instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instShl(old *ast.InstShl, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstShl) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstShl, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instLShr resolves the given lshr instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instLShr(old *ast.InstLShr, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstLShr) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstLShr, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instAShr resolves the given ashr instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instAShr(old *ast.InstAShr, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstAShr) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstAShr, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instAnd resolves the given and instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instAnd(old *ast.InstAnd, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstAnd) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstAnd, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instOr resolves the given or instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instOr(old *ast.InstOr, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstOr) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstOr, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instXor resolves the given xor instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instXor(old *ast.InstXor, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstXor) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstXor, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// --- [ Vector instructions ] ------------------------------------------------- - -// instExtractElement resolves the given extractelement instruction, by -// recursively resolving its operands. The boolean return value indicates -// success. -func (m *Module) instExtractElement(old *ast.InstExtractElement, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Index) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstExtractElement) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstExtractElement, got %T", enc.Local(old.Name), v)) - } - x := m.irValue(old.X) - t, ok := x.Type().(*types.VectorType) - if !ok { - panic(fmt.Errorf("invalid vector type; expected *types.VectorType, got %T", x.Type())) - } - inst.Typ = t.Elem - inst.X = x - inst.Index = m.irValue(old.Index) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instInsertElement resolves the given insertelement instruction, by -// recursively resolving its operands. The boolean return value indicates -// success. -func (m *Module) instInsertElement(old *ast.InstInsertElement, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Elem, old.Index) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstInsertElement) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstInsertElement, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Elem = m.irValue(old.Elem) - inst.Index = m.irValue(old.Index) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instShuffleVector resolves the given shufflevector instruction, by -// recursively resolving its operands. The boolean return value indicates -// success. -func (m *Module) instShuffleVector(old *ast.InstShuffleVector, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstShuffleVector) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstShuffleVector, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Mask = m.irValue(old.Mask) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// --- [ Aggregate instructions ] ---------------------------------------------- - -// instExtractValue resolves the given extractvalue instruction, by recursively -// resolving its operands. The boolean return value indicates success. -func (m *Module) instExtractValue(old *ast.InstExtractValue, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstExtractValue) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstExtractValue, got %T", enc.Local(old.Name), v)) - } - x := m.irValue(old.X) - typ := aggregateElemType(x.Type(), old.Indices) - inst.Typ = typ - inst.X = x - inst.Indices = old.Indices - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instInsertValue resolves the given insertvalue instruction, by recursively -// resolving its operands. The boolean return value indicates success. -func (m *Module) instInsertValue(old *ast.InstInsertValue, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Elem) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstInsertValue) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstInsertValue, got %T", enc.Local(old.Name), v)) - } - inst.X = m.irValue(old.X) - inst.Elem = m.irValue(old.Elem) - inst.Indices = old.Indices - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// --- [ Memory instructions ] ------------------------------------------------- - -// instAlloca resolves the given alloca instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instAlloca(old *ast.InstAlloca, resolved, unresolved map[ast.NamedValue]value.Named) bool { - // TODO: Validate if a non-nil check is needed for nelems. - if isUnresolved(unresolved, old.NElems) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstAlloca) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstAlloca, got %T", enc.Local(old.Name), v)) - } - elem := m.irType(old.Elem) - typ := types.NewPointer(elem) - inst.Typ = typ - inst.Elem = elem - if old.NElems != nil { - inst.NElems = m.irValue(old.NElems) - } - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instLoad resolves the given load instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instLoad(old *ast.InstLoad, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.Src) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstLoad) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstLoad, got %T", enc.Local(old.Name), v)) - } - src := m.irValue(old.Src) - srcType, ok := src.Type().(*types.PointerType) - if !ok { - panic(fmt.Errorf("invalid source type; expected *types.PointerType, got %T", src.Type())) - } - typ := srcType.Elem - if got, want := typ, m.irType(old.Elem); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("source element type mismatch; expected `%v`, got `%v`", want, got)) - } - inst.Typ = typ - inst.Src = src - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instGetElementPtr resolves the given getelementptr instruction, by -// recursively resolving its operands. The boolean return value indicates -// success. -func (m *Module) instGetElementPtr(old *ast.InstGetElementPtr, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.Src) || isUnresolved(unresolved, old.Indices...) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstGetElementPtr) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstGetElementPtr, got %T", enc.Local(old.Name), v)) - } - src := m.irValue(old.Src) - srcType, ok := src.Type().(*types.PointerType) - if !ok { - m.errs = append(m.errs, errors.Errorf("invalid source type; expected *types.PointerType, got %T", src.Type())) - } - elem := srcType.Elem - if got, want := elem, m.irType(old.Elem); !got.Equal(want) { - m.errs = append(m.errs, errors.Errorf("source element type mismatch; expected `%v`, got `%v`", want, got)) - } - var indices []value.Value - for _, oldIndex := range old.Indices { - index := m.irValue(oldIndex) - indices = append(indices, index) - } - e := elem - for i, index := range indices { - if i == 0 { - // Ignore checking the 0th index as it simply follows the pointer of - // src. - // - // ref: http://llvm.org/docs/GetElementPtr.html#why-is-the-extra-0-index-required - continue - } - switch t := e.(type) { - case *types.PointerType: - // ref: http://llvm.org/docs/GetElementPtr.html#what-is-dereferenced-by-gep - panic("unable to index into element of pointer type; for more information, see http://llvm.org/docs/GetElementPtr.html#what-is-dereferenced-by-gep") - case *types.VectorType: - e = t.Elem - case *types.ArrayType: - e = t.Elem - case *types.StructType: - idx, ok := index.(*constant.Int) - if !ok { - panic(fmt.Errorf("invalid index type for structure element; expected *constant.Int, got %T", index)) - } - e = t.Fields[idx.Int64()] - default: - panic(fmt.Errorf("support for indexing element type %T not yet implemented", e)) - } - } - typ := types.NewPointer(e) - inst.Typ = typ - inst.Elem = elem - inst.Src = src - inst.Indices = indices - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// --- [ Conversion instructions ] --------------------------------------------- - -// instTrunc resolves the given trunc instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instTrunc(old *ast.InstTrunc, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstTrunc) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstTrunc, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instZExt resolves the given zext instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instZExt(old *ast.InstZExt, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstZExt) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstZExt, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instSExt resolves the given sext instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instSExt(old *ast.InstSExt, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstSExt) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstSExt, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFPTrunc resolves the given fptrunc instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instFPTrunc(old *ast.InstFPTrunc, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFPTrunc) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFPTrunc, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFPExt resolves the given fpext instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFPExt(old *ast.InstFPExt, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFPExt) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFPExt, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFPToUI resolves the given fptoui instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instFPToUI(old *ast.InstFPToUI, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFPToUI) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFPToUI, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFPToSI resolves the given fptosi instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instFPToSI(old *ast.InstFPToSI, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFPToSI) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFPToSI, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instUIToFP resolves the given uitofp instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instUIToFP(old *ast.InstUIToFP, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstUIToFP) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstUIToFP, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instSIToFP resolves the given sitofp instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instSIToFP(old *ast.InstSIToFP, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstSIToFP) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstSIToFP, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instPtrToInt resolves the given ptrtoint instruction, by recursively -// resolving its operands. The boolean return value indicates success. -func (m *Module) instPtrToInt(old *ast.InstPtrToInt, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstPtrToInt) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstPtrToInt, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instIntToPtr resolves the given inttoptr instruction, by recursively -// resolving its operands. The boolean return value indicates success. -func (m *Module) instIntToPtr(old *ast.InstIntToPtr, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstIntToPtr) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstIntToPtr, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instBitCast resolves the given bitcast instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instBitCast(old *ast.InstBitCast, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstBitCast) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstBitCast, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instAddrSpaceCast resolves the given addrspacecast instruction, by -// recursively resolving its operands. The boolean return value indicates -// success. -func (m *Module) instAddrSpaceCast(old *ast.InstAddrSpaceCast, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.From) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstAddrSpaceCast) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstAddrSpaceCast, got %T", enc.Local(old.Name), v)) - } - inst.From = m.irValue(old.From) - inst.To = m.irType(old.To) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// --- [ Other instructions ] -------------------------------------------------- - -// instICmp resolves the given icmp instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instICmp(old *ast.InstICmp, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstICmp) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstICmp, got %T", enc.Local(old.Name), v)) - } - pred := irIntPred(old.Pred) - x := m.irValue(old.X) - y := m.irValue(old.Y) - var typ types.Type = types.I1 - if t, ok := x.Type().(*types.VectorType); ok { - typ = types.NewVector(types.I1, t.Len) - } - inst.Typ = typ - inst.Pred = pred - inst.X = x - inst.Y = y - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instFCmp resolves the given fcmp instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instFCmp(old *ast.InstFCmp, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstFCmp) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstFCmp, got %T", enc.Local(old.Name), v)) - } - pred := irFloatPred(old.Pred) - x := m.irValue(old.X) - y := m.irValue(old.Y) - var typ types.Type = types.I1 - if t, ok := x.Type().(*types.VectorType); ok { - typ = types.NewVector(types.I1, t.Len) - } - inst.Typ = typ - inst.Pred = pred - inst.X = x - inst.Y = y - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instPhi resolves the given phi instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instPhi(old *ast.InstPhi, resolved, unresolved map[ast.NamedValue]value.Named) bool { - // Note, to prevent infinite loops in the type-checker, PHI-instructions are - // not checked to see if they contain unresolved values. This is fine as the - // PHI type is computed from old.Typ anyways, so it does not need to be - // inferred from the operands of the PHI-instruction. - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstPhi) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstPhi, got %T", enc.Local(old.Name), v)) - } - inst.Typ = m.irType(old.Type) - for _, oldInc := range old.Incs { - x := m.irValue(oldInc.X) - v := m.getLocal(oldInc.Pred.GetName()) - pred, ok := v.(*ir.BasicBlock) - if !ok { - panic(fmt.Errorf("invalid basic block type; expected *ir.BasicBlock, got %T", v)) - } - inc := &ir.Incoming{ - X: x, - Pred: pred, - } - inst.Incs = append(inst.Incs, inc) - } - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instSelect resolves the given select instruction, by recursively resolving -// its operands. The boolean return value indicates success. -func (m *Module) instSelect(old *ast.InstSelect, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.Cond, old.X, old.Y) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstSelect) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstSelect, got %T", enc.Local(old.Name), v)) - } - inst.Cond = m.irValue(old.Cond) - inst.X = m.irValue(old.X) - inst.Y = m.irValue(old.Y) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// instCall resolves the given call instruction, by recursively resolving its -// operands. The boolean return value indicates success. -func (m *Module) instCall(old *ast.InstCall, resolved, unresolved map[ast.NamedValue]value.Named) bool { - if isUnresolved(unresolved, old.Callee) || isUnresolved(unresolved, old.Args...) { - return false - } - v := m.getLocal(old.Name) - inst, ok := v.(*ir.InstCall) - if !ok { - panic(fmt.Errorf("invalid instruction type for instruction %s; expected *ir.InstCall, got %T", enc.Local(old.Name), v)) - } - var ( - typ *types.PointerType - sig *types.FuncType - ) - var args []value.Value - for _, oldArg := range old.Args { - arg := m.irValue(oldArg) - args = append(args, arg) - } - callee := m.irValue(old.Callee) - if c, ok := callee.(*ir.InlineAsm); ok { - switch t := c.Typ.(type) { - case *types.FuncType: - sig = t - default: - // Result type stored in t, get parameters for function signature from - // arguments. Not perfect, but the best we can do. In particular, this - // approach is known to fail for variadic parameters. - var params []*types.Param - for _, arg := range args { - param := types.NewParam("", arg.Type()) - params = append(params, param) - } - sig = types.NewFunc(t, params...) - } - typ = types.NewPointer(sig) - } else { - var ok bool - typ, ok = callee.Type().(*types.PointerType) - if !ok { - panic(fmt.Errorf("invalid callee type, expected *types.PointerType, got %T", callee.Type())) - } - sig, ok = typ.Elem.(*types.FuncType) - if !ok { - panic(fmt.Errorf("invalid callee signature type, expected *types.FuncType, got %T", typ.Elem)) - } - } - inst.Callee = callee - inst.Sig = sig - // TODO: Validate old.Type against inst.Sig. - inst.Args = args - inst.CallConv = ir.CallConv(old.CallConv) - inst.Metadata = m.irMetadata(old.Metadata) - return true -} - -// ### [ Helper functions ] #################################################### - -// isUnresolved reports whether the given value is unresolved. -func isUnresolved(unresolved map[ast.NamedValue]value.Named, vs ...ast.Value) bool { - for _, v := range vs { - if v, ok := v.(ast.NamedValue); ok { - if _, ok := unresolved[v]; ok { - return true - } - } - } - return false -} diff --git a/llvm/asm/internal/irx/irx.go b/llvm/asm/internal/irx/irx.go deleted file mode 100755 index ae9bdee..0000000 --- a/llvm/asm/internal/irx/irx.go +++ /dev/null @@ -1,84 +0,0 @@ -// Package irx implements utility functions for translating ASTs of LLVM IR -// assembly to equivalent LLVM IR modules. -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/enc" - "github.com/geode-lang/geode/llvm/ir" - "github.com/geode-lang/geode/llvm/ir/metadata" - "github.com/geode-lang/geode/llvm/ir/types" - "github.com/geode-lang/geode/llvm/ir/value" -) - -// A Module represents an LLVM IR module generator. -type Module struct { - // Module being generated. - *ir.Module - - // Per module. - - // types maps from type identifiers to their corresponding LLVM IR types. - types map[string]types.Type - // globals maps global identifiers to their corresponding LLVM IR values. - globals map[string]value.Named - // metadata maps metadata IDs to their corresponding LLVM IR metadata. - metadata map[string]*metadata.Metadata - - // Per function. - - // locals maps local identifiers to their corresponding LLVM IR values; reset - // once per function definition. - locals map[string]value.Named - - // List of errors encountered during translation. - errs []error -} - -// NewModule returns a new module generator. -func NewModule() *Module { - m := ir.NewModule() - return &Module{ - Module: m, - types: make(map[string]types.Type), - globals: make(map[string]value.Named), - metadata: make(map[string]*metadata.Metadata), - } -} - -// getType returns the type of the given type name. -func (m *Module) getType(name string) types.Type { - typ, ok := m.types[name] - if !ok { - panic(fmt.Errorf("unable to locate type name %q", name)) - } - return typ -} - -// getGlobal returns the global value of the given global identifier. -func (m *Module) getGlobal(name string) value.Named { - global, ok := m.globals[name] - if !ok { - panic(fmt.Errorf("unable to locate global identifier %q", name)) - } - return global -} - -// getMetadata returns the metadata of the given metadata ID. -func (m *Module) getMetadata(id string) *metadata.Metadata { - metadata, ok := m.metadata[id] - if !ok { - panic(fmt.Errorf("unable to locate metadata ID %q", enc.Metadata(id))) - } - return metadata -} - -// getLocal returns the local value of the given local identifier. -func (m *Module) getLocal(name string) value.Named { - local, ok := m.locals[name] - if !ok { - panic(fmt.Errorf("unable to locate local identifier %q", name)) - } - return local -} diff --git a/llvm/asm/internal/irx/metadata.go b/llvm/asm/internal/irx/metadata.go deleted file mode 100755 index e5acd8c..0000000 --- a/llvm/asm/internal/irx/metadata.go +++ /dev/null @@ -1,41 +0,0 @@ -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/ir/metadata" -) - -// irMetadataNode returns the corresponding LLVM IR metadata node of the given -// metadata node. -func (m *Module) irMetadataNode(old ast.MetadataNode) metadata.Node { - switch old := old.(type) { - case *ast.Metadata: - var nodes []metadata.Node - for _, oldNode := range old.Nodes { - nodes = append(nodes, m.irMetadataNode(oldNode)) - } - return &metadata.Metadata{ - ID: old.ID, - Nodes: nodes, - } - case *ast.MetadataString: - return &metadata.String{ - Val: old.Val, - } - case *ast.MetadataValue: - return &metadata.Value{ - X: m.irValue(old.X), - } - case ast.Constant: - c := m.irConstant(old) - md, ok := c.(metadata.Node) - if !ok { - panic(fmt.Errorf("invalid constant type; expected metadata.Node, got %T", c)) - } - return md - default: - panic(fmt.Errorf("support for metadata node %T not yet implemented", old)) - } -} diff --git a/llvm/asm/internal/irx/translate.go b/llvm/asm/internal/irx/translate.go deleted file mode 100755 index 725868d..0000000 --- a/llvm/asm/internal/irx/translate.go +++ /dev/null @@ -1,961 +0,0 @@ -// Translates AST values as follows. -// -// Per module. -// -// 1. Index type definitions. -// 2. Index global variables. -// - Store preliminary content type. -// 3. Index function. -// - Store type. -// 4. Index metadata. -// 5. Fix type definitions. -// 6. Fix globals. -// 7. Fix named metadata definition. -// 8. Fix metadata definition. -// 9. Fix functions. -// -// Per function. -// -// 1. Index function parameters. -// 2. Index basic blocks. -// 3. Index local variables produced by instructions. -// 4. Resolve locals. -// 5. Fix basic blocks. - -package irx - -import ( - "fmt" - "sort" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/enc" - "github.com/geode-lang/geode/llvm/ir" - "github.com/geode-lang/geode/llvm/ir/constant" - "github.com/geode-lang/geode/llvm/ir/metadata" - "github.com/geode-lang/geode/llvm/ir/types" - "github.com/geode-lang/geode/llvm/ir/value" -) - -// === [ Modules ] ============================================================= - -// Translate translates the AST of the given module to an equivalent LLVM IR -// module. -func Translate(module *ast.Module) (*ir.Module, error) { - m := NewModule() - - // Set target specifiers. - m.DataLayout = module.DataLayout - m.TargetTriple = module.TargetTriple - - // Index type definitions. - for _, old := range module.Types { - name := old.Name - if _, ok := m.types[name]; ok { - panic(fmt.Errorf("type name %q already present; old `%v`, new `%v`", name, m.types[name], old)) - } - typ := newEmptyNamedType(old.Def) - typ.SetName(name) - m.Types = append(m.Types, typ) - m.types[name] = typ - } - - // Index global variables. - for _, old := range module.Globals { - name := old.Name - if _, ok := m.globals[name]; ok { - panic(fmt.Errorf("global identifier %q already present; old `%v`, new `%v`", name, m.globals[name], old)) - } - // Store preliminary content type (for circular dependencies). - content := m.irType(old.Content) - global := &ir.Global{ - Name: name, - Typ: types.NewPointer(content), - Content: content, - Metadata: make(map[string]*metadata.Metadata), - } - m.Globals = append(m.Globals, global) - m.globals[name] = global - } - - // Index functions. - for _, old := range module.Funcs { - name := old.Name - if _, ok := m.globals[name]; ok { - panic(fmt.Errorf("global identifier %q already present; old `%v`, new `%v`", name, m.globals[name], old)) - } - // Store type. - oldSig := m.irType(old.Sig) - sig, ok := oldSig.(*types.FuncType) - if !ok { - panic(fmt.Errorf("invalid function signature type, expected *types.FuncType, got %T", oldSig)) - } - typ := types.NewPointer(sig) - f := &ir.Function{ - Parent: m.Module, - Name: name, - Typ: typ, - Sig: sig, - Metadata: make(map[string]*metadata.Metadata), - } - m.Funcs = append(m.Funcs, f) - m.globals[name] = f - } - - // Index metadata. - for _, old := range module.Metadata { - id := old.ID - if _, ok := m.metadata[id]; ok { - panic(fmt.Errorf("metadata ID %q already present; old `%v`, new `%v`", id, m.metadata[id], old)) - } - md := &metadata.Metadata{ - ID: id, - } - m.Metadata = append(m.Metadata, md) - m.metadata[id] = md - } - - // Fix type definitions. - for _, typ := range module.Types { - m.typeDef(typ) - } - - // Fix globals. - for _, global := range module.Globals { - m.globalDecl(global) - } - - // Fix named metadata definitions. - for _, old := range module.NamedMetadata { - md := &metadata.Named{ - Name: old.Name, - } - for _, oldMetadata := range old.Metadata { - old, ok := oldMetadata.(*ast.Metadata) - if !ok { - panic(fmt.Errorf("invalid metadata type; expected *ast.Metadata, got %T", oldMetadata)) - } - metadata := m.getMetadata(old.ID) - md.Metadata = append(md.Metadata, metadata) - } - m.NamedMetadata = append(m.NamedMetadata, md) - } - - // Fix metadata definition. - for _, md := range module.Metadata { - m.metadataDef(md) - } - - // Fix functions. - for _, f := range module.Funcs { - m.funcDecl(f) - } - - if len(m.errs) > 0 { - // TODO: Return a list of all errors. - return nil, m.errs[0] - } - return m.Module, nil -} - -// === [ Type definitions ] ==================================================== - -// typeDef translates the given type definition to LLVM IR, emitting code to m. -func (m *Module) typeDef(old *ast.NamedType) { - typ := m.getType(old.Name) - def := m.irType(old.Def) - switch typ := typ.(type) { - case *types.VoidType: - _, ok := def.(*types.VoidType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.VoidType, got %T", def)) - } - // nothing to do. - case *types.FuncType: - d, ok := def.(*types.FuncType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.FuncType, got %T", def)) - } - typ.Ret = d.Ret - typ.Params = d.Params - typ.Variadic = d.Variadic - case *types.IntType: - d, ok := def.(*types.IntType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.IntType, got %T", def)) - } - typ.Size = d.Size - case *types.FloatType: - d, ok := def.(*types.FloatType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.FloatType, got %T", def)) - } - typ.Kind = d.Kind - case *types.PointerType: - d, ok := def.(*types.PointerType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.PointerType, got %T", def)) - } - typ.Elem = d.Elem - typ.AddrSpace = d.AddrSpace - case *types.VectorType: - d, ok := def.(*types.VectorType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.VectorType, got %T", def)) - } - typ.Elem = d.Elem - typ.Len = d.Len - case *types.LabelType: - _, ok := def.(*types.LabelType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.LabelType, got %T", def)) - } - // nothing to do. - case *types.MetadataType: - _, ok := def.(*types.MetadataType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.MetadataType, got %T", def)) - } - // nothing to do. - case *types.ArrayType: - d, ok := def.(*types.ArrayType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.ArrayType, got %T", def)) - } - typ.Elem = d.Elem - typ.Len = d.Len - case *types.StructType: - d, ok := def.(*types.StructType) - if !ok { - panic(fmt.Errorf("invalid type; expected *types.StructType, got %T", def)) - } - typ.Fields = d.Fields - typ.Opaque = d.Opaque - default: - panic(fmt.Errorf("support for type %T not yet implemented", typ)) - } -} - -// === [ Global variables ] ==================================================== - -// globalDecl translates the given global variable declaration to LLVM IR, -// emitting code to m. -func (m *Module) globalDecl(old *ast.Global) { - v := m.getGlobal(old.Name) - global, ok := v.(*ir.Global) - if !ok { - panic(fmt.Errorf("invalid global type; expected *ir.Global, got %T", v)) - } - - if old.Init != nil { - init := m.irConstant(old.Init) - global.Content = init.Type() - global.Init = init - } else { - global.Content = m.irType(old.Content) - } - typ := types.NewPointer(global.Content) - typ.AddrSpace = old.AddrSpace - global.Typ = typ - global.IsConst = old.Immutable - - // Fix attached metadata. - global.Metadata = m.irMetadata(old.Metadata) -} - -// === [ Functions ] =========================================================== - -// funcDecl translates the given function declaration to LLVM IR, emitting code -// to m. -func (m *Module) funcDecl(oldFunc *ast.Function) { - v := m.getGlobal(oldFunc.Name) - f, ok := v.(*ir.Function) - if !ok { - panic(fmt.Errorf("invalid function type for function %s; expected *ir.Function, got %T", enc.Global(oldFunc.Name), v)) - } - - // Fix calling convention. - f.CallConv = ir.CallConv(oldFunc.CallConv) - - // Fix attached metadata. - f.Metadata = m.irMetadata(oldFunc.Metadata) - - // Early exit if function declaration. - if len(oldFunc.Blocks) < 1 { - return - } - - // Reset locals. - m.locals = make(map[string]value.Named) - // track resolved and unresolved local values. - var ( - resolved = make(map[ast.NamedValue]value.Named) - unresolved = make(map[ast.NamedValue]value.Named) - ) - - // Index function parameters. - for i, param := range f.Params() { - name := param.Name - if _, ok := m.locals[name]; ok { - panic(fmt.Errorf("local identifier %q already present for function %s; old `%v`, new `%v`", name, f.Ident(), m.locals[name], param)) - } - m.locals[name] = param - resolved[oldFunc.Sig.Params[i]] = param - } - - // Index basic blocks. - for _, old := range oldFunc.Blocks { - name := old.Name - if _, ok := m.locals[name]; ok { - panic(fmt.Errorf("local identifier %q already present for function %s; old `%v`, new `%v`", name, f.Ident(), m.locals[name], old)) - } - block := &ir.BasicBlock{ - Name: name, - Parent: f, - } - f.Blocks = append(f.Blocks, block) - m.locals[name] = block - resolved[old] = block - } - - // Index local variables produced by instructions. - for i := 0; i < len(oldFunc.Blocks); i++ { - oldBlock := oldFunc.Blocks[i] - block := f.Blocks[i] - for _, oldInst := range oldBlock.Insts { - var inst ir.Instruction - switch oldInst := oldInst.(type) { - // Binary instructions - case *ast.InstAdd: - inst = &ir.InstAdd{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFAdd: - inst = &ir.InstFAdd{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstSub: - inst = &ir.InstSub{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFSub: - inst = &ir.InstFSub{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstMul: - inst = &ir.InstMul{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFMul: - inst = &ir.InstFMul{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstUDiv: - inst = &ir.InstUDiv{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstSDiv: - inst = &ir.InstSDiv{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFDiv: - inst = &ir.InstFDiv{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstURem: - inst = &ir.InstURem{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstSRem: - inst = &ir.InstSRem{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFRem: - inst = &ir.InstFRem{ - Parent: block, - Name: oldInst.Name, - } - - // Bitwise instructions - case *ast.InstShl: - inst = &ir.InstShl{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstLShr: - inst = &ir.InstLShr{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstAShr: - inst = &ir.InstAShr{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstAnd: - inst = &ir.InstAnd{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstOr: - inst = &ir.InstOr{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstXor: - inst = &ir.InstXor{ - Parent: block, - Name: oldInst.Name, - } - - // Vector instructions - case *ast.InstExtractElement: - inst = &ir.InstExtractElement{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstInsertElement: - inst = &ir.InstInsertElement{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstShuffleVector: - inst = &ir.InstShuffleVector{ - Parent: block, - Name: oldInst.Name, - } - - // Aggregate instructions - case *ast.InstExtractValue: - inst = &ir.InstExtractValue{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstInsertValue: - inst = &ir.InstInsertValue{ - Parent: block, - Name: oldInst.Name, - } - - // Memory instructions - case *ast.InstAlloca: - inst = &ir.InstAlloca{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstLoad: - inst = &ir.InstLoad{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstStore: - // Store instructions produce no value, and are thus not assigned - // names. - inst = &ir.InstStore{ - Parent: block, - } - case *ast.InstGetElementPtr: - inst = &ir.InstGetElementPtr{ - Parent: block, - Name: oldInst.Name, - } - - // Conversion instructions - case *ast.InstTrunc: - inst = &ir.InstTrunc{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstZExt: - inst = &ir.InstZExt{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstSExt: - inst = &ir.InstSExt{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFPTrunc: - inst = &ir.InstFPTrunc{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFPExt: - inst = &ir.InstFPExt{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFPToUI: - inst = &ir.InstFPToUI{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFPToSI: - inst = &ir.InstFPToSI{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstUIToFP: - inst = &ir.InstUIToFP{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstSIToFP: - inst = &ir.InstSIToFP{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstPtrToInt: - inst = &ir.InstPtrToInt{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstIntToPtr: - inst = &ir.InstIntToPtr{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstBitCast: - inst = &ir.InstBitCast{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstAddrSpaceCast: - inst = &ir.InstAddrSpaceCast{ - Parent: block, - Name: oldInst.Name, - } - - // Other instructions - case *ast.InstICmp: - inst = &ir.InstICmp{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstFCmp: - inst = &ir.InstFCmp{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstPhi: - inst = &ir.InstPhi{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstSelect: - inst = &ir.InstSelect{ - Parent: block, - Name: oldInst.Name, - } - case *ast.InstCall: - inst = &ir.InstCall{ - Parent: block, - Name: oldInst.Name, - } - - default: - panic(fmt.Errorf("support for instruction %T not yet implemented", oldInst)) - } - block.Insts = append(block.Insts, inst) - - // TODO: Validate if it is required to store a preliminary type of - // instructions prior to local variable resolution. - // - // What happens if a getelementptr instruction refers to the value - // produced by an instruction which cannot be calculated prior to its - // operands being resolved? - // - //// Store preliminary type. - - // Index local variable. - if inst, ok := inst.(value.Named); ok { - // Ignore local value if of type void. - if oldInst, ok := oldInst.(*ast.InstCall); ok { - switch t := oldInst.Type.(type) { - case *ast.VoidType: - continue - case *ast.FuncType: - if _, ok := t.Ret.(*ast.VoidType); ok { - continue - } - } - } - m.locals[inst.GetName()] = inst - oi, ok := oldInst.(ast.NamedValue) - if !ok { - panic(fmt.Errorf("invalid old instruction type; expected ast.NamedValue, got %T", oldInst)) - } - unresolved[oi] = inst - } - } - } - - // Resolve locals (as they can have circular dependencies). - for len(unresolved) > 0 { - prev := len(unresolved) - for old, local := range unresolved { - if m.resolveInst(old, resolved, unresolved) { - delete(unresolved, old) - resolved[old] = local - } - } - if len(unresolved) == prev { - var names []string - for old := range unresolved { - names = append(names, old.GetName()) - } - sort.Strings(names) - panic(fmt.Errorf("unable to resolve %d local values; %v", len(unresolved), names)) - } - } - - // Fix basic blocks. - for i := 0; i < len(oldFunc.Blocks); i++ { - oldBlock := oldFunc.Blocks[i] - block := f.Blocks[i] - m.basicBlock(oldBlock, block) - } -} - -// === [ Metadata definitions ] ================================================ - -// metadataDef translates the given metadata definition to LLVM IR, emitting -// code to m. -func (m *Module) metadataDef(oldMetadata *ast.Metadata) { - md := m.getMetadata(oldMetadata.ID) - for _, oldNode := range oldMetadata.Nodes { - node := m.metadataNode(oldNode) - md.Nodes = append(md.Nodes, node) - } -} - -// metadataNode returns the corresponding LLVM IR metadata node of the given -// metadata node. -func (m *Module) metadataNode(oldNode ast.MetadataNode) metadata.Node { - switch oldNode := oldNode.(type) { - case *ast.Metadata: - if len(oldNode.ID) > 0 { - return m.getMetadata(oldNode.ID) - } - // Unnamed metadata literal. - md := &metadata.Metadata{} - for _, node := range oldNode.Nodes { - n := m.metadataNode(node) - md.Nodes = append(md.Nodes, n) - } - return md - case *ast.MetadataString: - return &metadata.String{ - Val: oldNode.Val, - } - case *ast.MetadataValue: - return &metadata.Value{ - X: m.irValue(oldNode.X), - } - case ast.Constant: - c := m.irConstant(oldNode) - md, ok := c.(metadata.Node) - if !ok { - panic(fmt.Sprintf("invalid metadata node type; expected metadata.Node, got %T", c)) - } - return md - default: - panic(fmt.Errorf("support for metadata node type %T not yet implemented", oldNode)) - } -} - -// === [ Identifiers ] ========================================================= - -// === [ Types ] =============================================================== - -// === [ Values ] ============================================================== - -// === [ Constants ] =========================================================== - -// --- [ Binary expressions ] -------------------------------------------------- - -// --- [ Bitwise expressions ] ------------------------------------------------- - -// --- [ Aggregate expressions ] ----------------------------------------------- - -// --- [ Vector expressions ] -------------------------------------------------- - -// --- [ Memory expressions ] -------------------------------------------------- - -// --- [ Conversion expressions ] ---------------------------------------------- - -// --- [ Other expressions ] --------------------------------------------------- - -// === [ Basic blocks ] ======================================================== - -// basicBlock translates the given basic block to LLVM IR, emitting code to m. -func (m *Module) basicBlock(oldBlock *ast.BasicBlock, block *ir.BasicBlock) { - // Fix instructions not producing values. - for i := 0; i < len(oldBlock.Insts); i++ { - old := oldBlock.Insts[i] - v := block.Insts[i] - switch old := old.(type) { - // Memory instructions - case *ast.InstStore: - inst, ok := v.(*ir.InstStore) - if !ok { - panic(fmt.Errorf("invalid instruction type; expected *ir.InstStore, got %T", v)) - } - inst.Src = m.irValue(old.Src) - inst.Dst = m.irValue(old.Dst) - inst.Metadata = m.irMetadata(old.Metadata) - - // Other instructions - case *ast.InstCall: - inst, ok := v.(*ir.InstCall) - if !ok { - panic(fmt.Errorf("invalid instruction type; expected *ir.InstCall, got %T", v)) - } - // Handle calls to void functions. - switch t := old.Type.(type) { - case *ast.VoidType: - case *ast.FuncType: - if _, ok := t.Ret.(*ast.VoidType); !ok { - // handled by resolveInst. - continue - } - default: - // handled by resolveInst. - continue - } - // TODO: Call m.instCall to reuse code. - callee := m.irValue(old.Callee) - typ, ok := callee.Type().(*types.PointerType) - if !ok { - panic(fmt.Errorf("invalid callee type, expected *types.PointerType, got %T", callee.Type())) - } - sig, ok := typ.Elem.(*types.FuncType) - if !ok { - panic(fmt.Errorf("invalid callee signature type, expected *types.FuncType, got %T", typ.Elem)) - } - inst.Callee = callee - inst.Sig = sig - // TODO: Validate old.Type against inst.Sig. - for _, oldArg := range old.Args { - arg := m.irValue(oldArg) - inst.Args = append(inst.Args, arg) - } - inst.CallConv = ir.CallConv(old.CallConv) - inst.Metadata = m.irMetadata(old.Metadata) - } - } - - // Fix terminator. - switch oldTerm := oldBlock.Term.(type) { - case *ast.TermRet: - term := &ir.TermRet{ - Parent: block, - } - if oldTerm.X != nil { - term.X = m.irValue(oldTerm.X) - } - term.Metadata = m.irMetadata(oldTerm.Metadata) - block.Term = term - case *ast.TermBr: - term := &ir.TermBr{ - Parent: block, - } - v := m.irValue(oldTerm.Target) - target, ok := v.(*ir.BasicBlock) - if !ok { - panic(fmt.Errorf("invalid target branch type, expected *ir.BasicBlock, got %T", v)) - } - term.Target = target - term.Metadata = m.irMetadata(oldTerm.Metadata) - block.Term = term - case *ast.TermCondBr: - term := &ir.TermCondBr{ - Parent: block, - } - tTrue := m.irValue(oldTerm.TargetTrue) - targetTrue, ok := tTrue.(*ir.BasicBlock) - if !ok { - panic(fmt.Errorf("invalid true target branch type, expected *ir.BasicBlock, got %T", tTrue)) - } - tFalse := m.irValue(oldTerm.TargetFalse) - targetFalse, ok := tFalse.(*ir.BasicBlock) - if !ok { - panic(fmt.Errorf("invalid false target branch type, expected *ir.BasicBlock, got %T", tFalse)) - } - successors := []*ir.BasicBlock{targetTrue, targetFalse} - term.Cond = m.irValue(oldTerm.Cond) - term.TargetTrue = targetTrue - term.TargetFalse = targetFalse - term.Successors = successors - term.Metadata = m.irMetadata(oldTerm.Metadata) - block.Term = term - case *ast.TermSwitch: - term := &ir.TermSwitch{ - Parent: block, - } - term.X = m.irValue(oldTerm.X) - v := m.getLocal(oldTerm.TargetDefault.GetName()) - targetDefault, ok := v.(*ir.BasicBlock) - if !ok { - panic(fmt.Errorf("invalid default target branch type, expected *ir.BasicBlock, got %T", v)) - } - term.TargetDefault = targetDefault - successors := []*ir.BasicBlock{targetDefault} - for _, oldCase := range oldTerm.Cases { - xx := m.irConstant(oldCase.X) - x, ok := xx.(*constant.Int) - if !ok { - panic(fmt.Errorf("invalid x type, expected *constant.Int, got %T", xx)) - } - v := m.getLocal(oldCase.Target.GetName()) - target, ok := v.(*ir.BasicBlock) - if !ok { - panic(fmt.Errorf("invalid target branch type, expected *ir.BasicBlock, got %T", v)) - } - c := &ir.Case{ - X: x, - Target: target, - } - term.Cases = append(term.Cases, c) - successors = append(successors, target) - } - term.Successors = successors - term.Metadata = m.irMetadata(oldTerm.Metadata) - block.Term = term - case *ast.TermUnreachable: - term := &ir.TermUnreachable{ - Parent: block, - } - term.Metadata = m.irMetadata(oldTerm.Metadata) - block.Term = term - default: - panic(fmt.Errorf("support for terminator %T not yet implemented", oldTerm)) - } -} - -// === [ Instructions ] ======================================================== - -// resolveInst resolves the given local value, by recursively resolving its -// operands. -func (m *Module) resolveInst(old ast.NamedValue, resolved, unresolved map[ast.NamedValue]value.Named) bool { - switch old := old.(type) { - // Binary instructions - case *ast.InstAdd: - return m.instAdd(old, resolved, unresolved) - case *ast.InstFAdd: - return m.instFAdd(old, resolved, unresolved) - case *ast.InstSub: - return m.instSub(old, resolved, unresolved) - case *ast.InstFSub: - return m.instFSub(old, resolved, unresolved) - case *ast.InstMul: - return m.instMul(old, resolved, unresolved) - case *ast.InstFMul: - return m.instFMul(old, resolved, unresolved) - case *ast.InstUDiv: - return m.instUDiv(old, resolved, unresolved) - case *ast.InstSDiv: - return m.instSDiv(old, resolved, unresolved) - case *ast.InstFDiv: - return m.instFDiv(old, resolved, unresolved) - case *ast.InstURem: - return m.instURem(old, resolved, unresolved) - case *ast.InstSRem: - return m.instSRem(old, resolved, unresolved) - case *ast.InstFRem: - return m.instFRem(old, resolved, unresolved) - - // Bitwise instructions - case *ast.InstShl: - return m.instShl(old, resolved, unresolved) - case *ast.InstLShr: - return m.instLShr(old, resolved, unresolved) - case *ast.InstAShr: - return m.instAShr(old, resolved, unresolved) - case *ast.InstAnd: - return m.instAnd(old, resolved, unresolved) - case *ast.InstOr: - return m.instOr(old, resolved, unresolved) - case *ast.InstXor: - return m.instXor(old, resolved, unresolved) - - // Vector instructions - case *ast.InstExtractElement: - return m.instExtractElement(old, resolved, unresolved) - case *ast.InstInsertElement: - return m.instInsertElement(old, resolved, unresolved) - case *ast.InstShuffleVector: - return m.instShuffleVector(old, resolved, unresolved) - - // Aggregate instructions - case *ast.InstExtractValue: - return m.instExtractValue(old, resolved, unresolved) - case *ast.InstInsertValue: - return m.instInsertValue(old, resolved, unresolved) - - // Memory instructions - case *ast.InstAlloca: - return m.instAlloca(old, resolved, unresolved) - case *ast.InstLoad: - return m.instLoad(old, resolved, unresolved) - case *ast.InstGetElementPtr: - return m.instGetElementPtr(old, resolved, unresolved) - - // Conversion instructions - case *ast.InstTrunc: - return m.instTrunc(old, resolved, unresolved) - case *ast.InstZExt: - return m.instZExt(old, resolved, unresolved) - case *ast.InstSExt: - return m.instSExt(old, resolved, unresolved) - case *ast.InstFPTrunc: - return m.instFPTrunc(old, resolved, unresolved) - case *ast.InstFPExt: - return m.instFPExt(old, resolved, unresolved) - case *ast.InstFPToUI: - return m.instFPToUI(old, resolved, unresolved) - case *ast.InstFPToSI: - return m.instFPToSI(old, resolved, unresolved) - case *ast.InstUIToFP: - return m.instUIToFP(old, resolved, unresolved) - case *ast.InstSIToFP: - return m.instSIToFP(old, resolved, unresolved) - case *ast.InstPtrToInt: - return m.instPtrToInt(old, resolved, unresolved) - case *ast.InstIntToPtr: - return m.instIntToPtr(old, resolved, unresolved) - case *ast.InstBitCast: - return m.instBitCast(old, resolved, unresolved) - case *ast.InstAddrSpaceCast: - return m.instAddrSpaceCast(old, resolved, unresolved) - - // Other instructions - case *ast.InstICmp: - return m.instICmp(old, resolved, unresolved) - case *ast.InstFCmp: - return m.instFCmp(old, resolved, unresolved) - case *ast.InstPhi: - return m.instPhi(old, resolved, unresolved) - case *ast.InstSelect: - return m.instSelect(old, resolved, unresolved) - case *ast.InstCall: - return m.instCall(old, resolved, unresolved) - - default: - panic(fmt.Errorf("support for instruction %T not yet implemented", old)) - } -} - -// === [ Terminators ] ========================================================= diff --git a/llvm/asm/internal/irx/type.go b/llvm/asm/internal/irx/type.go deleted file mode 100755 index d399385..0000000 --- a/llvm/asm/internal/irx/type.go +++ /dev/null @@ -1,94 +0,0 @@ -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/ir/types" -) - -// irType returns the corresponding LLVM IR type of the given type. -func (m *Module) irType(old ast.Type) types.Type { - switch old := old.(type) { - case *ast.VoidType: - return types.Void - case *ast.FuncType: - params := make([]*types.Param, len(old.Params)) - for i, oldParam := range old.Params { - params[i] = types.NewParam(oldParam.Name, m.irType(oldParam.Type)) - } - typ := types.NewFunc(m.irType(old.Ret), params...) - typ.Variadic = old.Variadic - return typ - case *ast.IntType: - return types.NewInt(old.Size) - case *ast.FloatType: - switch old.Kind { - case ast.FloatKindIEEE_16: - return types.Half - case ast.FloatKindIEEE_32: - return types.Float - case ast.FloatKindIEEE_64: - return types.Double - case ast.FloatKindIEEE_128: - return types.FP128 - case ast.FloatKindDoubleExtended_80: - return types.X86_FP80 - case ast.FloatKindDoubleDouble_128: - return types.PPC_FP128 - default: - panic(fmt.Errorf("support for %v not yet implemented", old.Kind)) - } - case *ast.PointerType: - typ := types.NewPointer(m.irType(old.Elem)) - typ.AddrSpace = old.AddrSpace - return typ - case *ast.VectorType: - return types.NewVector(m.irType(old.Elem), old.Len) - case *ast.LabelType: - return types.Label - case *ast.MetadataType: - return types.Metadata - case *ast.ArrayType: - return types.NewArray(m.irType(old.Elem), old.Len) - case *ast.StructType: - fields := make([]types.Type, len(old.Fields)) - for i, oldField := range old.Fields { - fields[i] = m.irType(oldField) - } - typ := types.NewStruct(fields...) - typ.Opaque = old.Opaque - return typ - case *ast.NamedType: - return m.getType(old.Name) - case *ast.NamedTypeDummy: - return m.getType(old.Name) - case *ast.TypeDummy: - panic("invalid type *ast.TypeDummy; dummy types should have been translated during parsing by astx") - default: - panic(fmt.Errorf("support for %T not yet implemented", old)) - } -} - -// aggregateElemType returns the element type of the given aggregate type, based -// on the specified indices. -func aggregateElemType(t types.Type, indices []int64) types.Type { - if len(indices) == 0 { - return t - } - index := indices[0] - switch t := t.(type) { - case *types.ArrayType: - if index >= t.Len { - panic(fmt.Errorf("invalid index (%d); exceeds array length (%d)", index, t.Len)) - } - return aggregateElemType(t.Elem, indices[1:]) - case *types.StructType: - if index >= int64(len(t.Fields)) { - panic(fmt.Errorf("invalid index (%d); exceeds struct field count (%d)", index, len(t.Fields))) - } - return aggregateElemType(t.Fields[index], indices[1:]) - default: - panic(fmt.Errorf("invalid aggregate value type; expected *types.ArrayType or *types.StructType, got %T", t)) - } -} diff --git a/llvm/asm/internal/irx/util.go b/llvm/asm/internal/irx/util.go deleted file mode 100755 index d0724c1..0000000 --- a/llvm/asm/internal/irx/util.go +++ /dev/null @@ -1,129 +0,0 @@ -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/ir" - "github.com/geode-lang/geode/llvm/ir/metadata" - "github.com/geode-lang/geode/llvm/ir/types" -) - -// ### [ Helper functions ] #################################################### - -// irIntPred returns the corresponding LLVM IR integer predicate of the given -// integer predicate. -func irIntPred(cond ast.IntPred) ir.IntPred { - switch cond { - case ast.IntEQ: - return ir.IntEQ - case ast.IntNE: - return ir.IntNE - case ast.IntUGT: - return ir.IntUGT - case ast.IntUGE: - return ir.IntUGE - case ast.IntULT: - return ir.IntULT - case ast.IntULE: - return ir.IntULE - case ast.IntSGT: - return ir.IntSGT - case ast.IntSGE: - return ir.IntSGE - case ast.IntSLT: - return ir.IntSLT - case ast.IntSLE: - return ir.IntSLE - } - panic(fmt.Errorf("support for integer predicate %v not yet implemented", cond)) -} - -// irFloatPred returns the corresponding LLVM IR floating-point predicate of the -// given floating-point predicate. -func irFloatPred(cond ast.FloatPred) ir.FloatPred { - switch cond { - case ast.FloatFalse: - return ir.FloatFalse - case ast.FloatOEQ: - return ir.FloatOEQ - case ast.FloatOGT: - return ir.FloatOGT - case ast.FloatOGE: - return ir.FloatOGE - case ast.FloatOLT: - return ir.FloatOLT - case ast.FloatOLE: - return ir.FloatOLE - case ast.FloatONE: - return ir.FloatONE - case ast.FloatORD: - return ir.FloatORD - case ast.FloatUEQ: - return ir.FloatUEQ - case ast.FloatUGT: - return ir.FloatUGT - case ast.FloatUGE: - return ir.FloatUGE - case ast.FloatULT: - return ir.FloatULT - case ast.FloatULE: - return ir.FloatULE - case ast.FloatUNE: - return ir.FloatUNE - case ast.FloatUNO: - return ir.FloatUNO - case ast.FloatTrue: - return ir.FloatTrue - } - panic(fmt.Errorf("support for floating-point predicate %v not yet implemented", cond)) -} - -// irMetadata returns the corresponding LLVM IR metadata of the given list of -// attached metadata. -func (m *Module) irMetadata(oldMDs []*ast.AttachedMD) map[string]*metadata.Metadata { - mds := make(map[string]*metadata.Metadata) - for _, oldMD := range oldMDs { - key := oldMD.Name - node := m.metadataNode(oldMD.Metadata) - if prev, ok := mds[key]; ok { - panic(fmt.Errorf("attached metadata for metadata name %q already present; previous `%v`, new `%v`", key, prev, m.Metadata)) - } - md, ok := node.(*metadata.Metadata) - if !ok { - panic(fmt.Errorf("invalid metadata type; expected *metadata.Metadata, got %T", node)) - } - mds[key] = md - } - return mds -} - -// newEmptyNamedType returns an empty type definition for the given named type. -func newEmptyNamedType(old ast.Type) types.Type { - switch old := old.(type) { - case *ast.VoidType: - return &types.VoidType{} - case *ast.FuncType: - return &types.FuncType{} - case *ast.IntType: - return &types.IntType{} - case *ast.FloatType: - return &types.FloatType{} - case *ast.PointerType: - return &types.PointerType{} - case *ast.VectorType: - return &types.VectorType{} - case *ast.LabelType: - return &types.LabelType{} - case *ast.MetadataType: - return &types.MetadataType{} - case *ast.ArrayType: - return &types.ArrayType{} - case *ast.StructType: - return &types.StructType{} - case *ast.NamedType: - return newEmptyNamedType(old.Def) - default: - panic(fmt.Errorf("support for type %T not yet implemented", old)) - } -} diff --git a/llvm/asm/internal/irx/value.go b/llvm/asm/internal/irx/value.go deleted file mode 100755 index a020caf..0000000 --- a/llvm/asm/internal/irx/value.go +++ /dev/null @@ -1,42 +0,0 @@ -package irx - -import ( - "fmt" - - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/ir" - "github.com/geode-lang/geode/llvm/ir/value" -) - -// irValue returns the corresponding LLVM IR value of the given value. -func (m *Module) irValue(old ast.Value) value.Value { - switch old := old.(type) { - // Constant. - case ast.Constant: - return m.irConstant(old) - // Named values. - case ast.NamedValue: - switch old := old.(type) { - // Global identifiers. - case *ast.Global, *ast.GlobalDummy, *ast.Function: - return m.getGlobal(old.GetName()) - // Local identifiers. - case *ast.Param, *ast.BasicBlock, *ast.LocalDummy, ast.Instruction: - return m.getLocal(old.GetName()) - default: - panic(fmt.Errorf("support for named value %T not yet implemented", old)) - } - // Inline assmebly. - case *ast.InlineAsm: - return &ir.InlineAsm{ - Asm: old.Asm, - Constraints: old.Constraints, - Typ: m.irType(old.Type), - } - // Metadata node. - case ast.MetadataNode: - return m.irMetadataNode(old) - default: - panic(fmt.Errorf("support for value %T not yet implemented", old)) - } -} diff --git a/llvm/asm/internal/ll.bnf b/llvm/asm/internal/ll.bnf deleted file mode 100755 index ad9c8a4..0000000 --- a/llvm/asm/internal/ll.bnf +++ /dev/null @@ -1,2129 +0,0 @@ -// ### [ Lexical part ] ######################################################## - -_ascii_letter - : 'A' - 'Z' - | 'a' - 'z' -; - -_letter - : _ascii_letter - | '$' - | '-' - | '.' - | '_' -; - -_escape_letter - : _letter - | '\\' -; - -_decimal_digit - : '0' - '9' -; - -_hex_digit - : _decimal_digit - | 'A' - 'F' - | 'a' - 'f' -; - -!comment : ';' { . } '\n' ; - -!whitespace : '\x00' | ' ' | '\t' | '\r' | '\n' ; - -// === [ Identifiers ] ========================================================= - -_name - : _letter { _letter | _decimal_digit } -; - -_escape_name - : _escape_letter { _escape_letter | _decimal_digit } -; - -_quoted_name - : _quoted_string -; - -_id - : _decimals -; - -// --- [ Global identifiers ] -------------------------------------------------- - -global_ident - : _global_name - | _global_id -; - -_global_name - : '@' ( _name | _quoted_name ) -; - -_global_id - : '@' _id -; - -// --- [ Local identifiers ] --------------------------------------------------- - -local_ident - : _local_name - | _local_id -; - -_local_name - : '%' ( _name | _quoted_name ) -; - -_local_id - : '%' _id -; - -// --- [ Labels ] -------------------------------------------------------------- - -// Label [-a-zA-Z$._0-9]+: - -label_ident - : ( _letter | _decimal_digit ) { _letter | _decimal_digit } ':' - | _quoted_string ':' -; - -// --- [ Attribute group identifiers ] ----------------------------------------- - -attr_group_id - : '#' _id -; - -// --- [ Comdat identifiers ] -------------------------------------------------- - -comdat_name - : '$' ( _name | _quoted_name ) -; - -// --- [ Metadata identifiers ] ------------------------------------------------ - -metadata_name - : '!' _escape_name -; - -metadata_id - : '!' _id -; - -// === [ Integer literals ] ==================================================== - -// Integer [-]?[0-9]+ - -int_lit - : _decimal_lit -; - -_decimal_lit - : [ '-' ] _decimals -; - -_decimals - : _decimal_digit { _decimal_digit } -; - -// === [ Floating-point literals ] ============================================= - -// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)? - -float_lit - : _frac_lit - | _sci_lit - | _float_hex_lit -; - -_frac_lit - : [ _sign ] _decimals '.' { _decimal_digit } -; - -_sign - : '+' - | '-' -; - -_sci_lit - : _frac_lit ( 'e' | 'E' ) [ _sign ] _decimals -; - -// HexFPConstant 0x[0-9A-Fa-f]+ // 16 hex digits -// HexFP80Constant 0xK[0-9A-Fa-f]+ // 20 hex digits -// HexFP128Constant 0xL[0-9A-Fa-f]+ // 32 hex digits -// HexPPC128Constant 0xM[0-9A-Fa-f]+ // 32 hex digits -// HexHalfConstant 0xH[0-9A-Fa-f]+ // 4 hex digits - -_float_hex_lit - : '0' 'x' _hex_digit { _hex_digit } - | '0' 'x' 'K' _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit - | '0' 'x' 'L' _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit - | '0' 'x' 'M' _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit - | '0' 'x' 'H' _hex_digit _hex_digit _hex_digit _hex_digit -; - -// === [ String literals ] ===================================================== - -string_lit - : _quoted_string -; - -_quoted_string - : '"' { . } '"' -; - -// === [ Types ] =============================================================== - -int_type - : 'i' _decimals -; - -// ### [ Syntactic part ] ###################################################### - -<< import ( - "github.com/geode-lang/geode/llvm/asm/internal/ast" - "github.com/geode-lang/geode/llvm/asm/internal/astx" -) >> - -// === [ Modules ] ============================================================= - -Module - : TopLevelDecls << astx.NewModule($0) >> -; - -TopLevelDecls - : empty - | TopLevelDeclList -; - -TopLevelDeclList - : TopLevelDecl << astx.NewTopLevelDeclList($0) >> - | TopLevelDeclList TopLevelDecl << astx.AppendTopLevelDecl($0, $1) >> -; - -TopLevelDecl - : SourceFilename - | TargetSpec - | ModuleAsm - | TypeDef - | ComdatDef - | GlobalDecl - | GlobalDef - | FuncDecl - | FuncDef - | AttrGroupDef - | NamedMetadataDef - | MetadataDef -; - -// --- [ Source filename ] ----------------------------------------------------- - -SourceFilename - : "source_filename" "=" string_lit << nil, nil >> -; - -// --- [ Target specifiers ] --------------------------------------------------- - -TargetSpec - : "target" DataLayout << $1, nil >> - | "target" TargetTriple << $1, nil >> -; - -DataLayout - : "datalayout" "=" string_lit << astx.NewDataLayout($2) >> -; - -TargetTriple - : "triple" "=" string_lit << astx.NewTargetTriple($2) >> -; - -// --- [ Module-level inline assembly ] ---------------------------------------- - -// ref: http://llvm.org/docs/LangRef.html#module-level-inline-assembly -ModuleAsm - : "module" "asm" string_lit << nil, nil >> -; - -// --- [ Type definitions ] ---------------------------------------------------- - -TypeDef - : LocalIdent "=" "type" Type << astx.NewTypeDef($0, $3) >> - | LocalIdent "=" "type" "opaque" << astx.NewTypeDefOpaque($0) >> -; - -// --- [ Comdat definitions ] -------------------------------------------------- - -ComdatDef - : ComdatName "=" "comdat" SelectionKind << nil, nil >> -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#comdats -SelectionKind - : "any" - | "exactmatch" - | "largest" - | "noduplicates" - | "samesize" -; - -// --- [ Global variables ] ---------------------------------------------------- - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// GlobalDecl -// : GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType OptCommaSection OptCommaComdat OptCommaAlign OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $9) >> -// ; -GlobalDecl - : GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $6) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Align OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $8) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Comdat OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $8) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Comdat "," Align OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $10) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Section OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $8) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Section "," Align OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $10) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Section "," Comdat OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $10) >> - | GlobalIdent "=" ExternLinkage GlobalOptions Immutable ConcreteType "," Section "," Comdat "," Align OptCommaAttachedMDList << astx.NewGlobalDecl($0, $3, $4, $5, $12) >> -; - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// GlobalDef -// : GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant OptCommaSection OptCommaComdat OptCommaAlign OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $10) >> -// ; -GlobalDef - : GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $7) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Align OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $9) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Comdat OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $9) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Comdat "," Align OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $11) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Section OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $9) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Section "," Align OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $11) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Section "," Comdat OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $11) >> - | GlobalIdent "=" OptLinkage GlobalOptions Immutable ConcreteType Constant "," Section "," Comdat "," Align OptCommaAttachedMDList << astx.NewGlobalDef($0, $3, $4, $5, $6, $13) >> -; - -GlobalOptions - : OptVisibility OptDLLStorageClass OptThreadLocal OptUnnamedAddr OptAddrSpace OptExternallyInitialized << $4, nil >> -; - -OptExternallyInitialized - : empty - | ExternallyInitialized -; - -ExternallyInitialized - : "externally_initialized" -; - -Immutable - : "constant" << true, nil >> - | "global" << false, nil >> -; - -// --- [ Functions ] ----------------------------------------------------------- - -FuncDecl - : "declare" AttachedMDs OptExternLinkage FuncHeader << astx.NewFuncDecl($1, $3) >> -; - -FuncDef - : "define" OptLinkage FuncHeader AttachedMDs FuncBody << astx.NewFuncDef($2, $3, $4) >> -; - -FuncHeader - : OptVisibility OptDLLStorageClass OptCallConv ParamAttrs Type GlobalIdent - "(" Params ")" OptUnnamedAddr FuncAttrs OptSection OptComdat OptAlign - OptGC OptPrefix OptPrologue OptPersonality << astx.NewFuncHeader($2, $4, $5, $7) >> -; - -Params - : empty - | "..." << astx.NewParams(nil, true) >> - | ParamList << astx.NewParams($0, false) >> - | ParamList "," "..." << astx.NewParams($0, true) >> -; - -ParamList - : Param << astx.NewParamList($0) >> - | ParamList "," Param << astx.AppendParam($0, $2) >> -; - -Param - : FirstClassType ParamAttrs << astx.NewParam($0, nil) >> - | FirstClassType ParamAttrs LocalIdent << astx.NewParam($0, $2) >> -; - -FuncBody - : "{" BasicBlockList "}" << $1, nil >> -; - -// --- [ Attribute group definitions ] ----------------------------------------- - -AttrGroupDef - : "attributes" AttrGroupID "=" "{" FuncAttrList "}" << nil, nil >> -; - -// --- [ Metadata definitions ] ------------------------------------------------ - -NamedMetadataDef - : MetadataName "=" "!" "{" MetadataIDs "}" << astx.NewNamedMetadataDef($0, $4) >> -; - -MetadataIDs - : empty - | MetadataIDList -; - -MetadataIDList - : MetadataID << astx.NewMetadataIDList($0) >> - | MetadataIDList "," MetadataID << astx.AppendMetadataID($0, $2) >> -; - -MetadataDef - : MetadataID "=" OptDistinct Metadata << astx.NewMetadataDef($0, $3) >> -; - -OptDistinct - : empty - | "distinct" -; - -Metadata - : "!" "{" MetadataNodes "}" << astx.NewMetadata($2) >> -; - -MetadataNodes - : empty - | MetadataNodeList -; - -MetadataNodeList - : MetadataNode << astx.NewMetadataNodeList($0) >> - | MetadataNodeList "," MetadataNode << astx.AppendMetadataNode($0, $2) >> -; - -MetadataNode - : Metadata - | MetadataID - | "!" string_lit << astx.NewMetadataString($1) >> - | Type Constant << astx.NewConstant($0, $1) >> -; - -MetadataValue - : MetadataNode - | ConcreteType LocalIdent << astx.NewValue($0, $1) >> -; - -// === [ Identifiers ] ========================================================= - -GlobalIdent - : global_ident << astx.NewGlobalIdent($0) >> -; - -LocalIdent - : local_ident << astx.NewLocalIdent($0) >> -; - -LabelIdent - : label_ident << astx.NewLabelIdent($0) >> -; - -AttrGroupID - : attr_group_id -; - -ComdatName - : comdat_name -; - -MetadataName - : metadata_name << astx.NewMetadataName($0) >> -; - -MetadataID - : metadata_id << astx.NewMetadataID($0) >> -; - -// === [ Types ] =============================================================== - -Type - : VoidType - | FuncType - | FirstClassType -; - -FirstClassType - : ConcreteType - | MetadataType -; - -ConcreteType - : IntType - | FloatType - | PointerType - | VectorType - | LabelType - | ArrayType - | StructType - | NamedType -; - -// --- [ Void type ] ----------------------------------------------------------- - -VoidType - : "void" << &ast.VoidType{}, nil >> -; - -// --- [ Function type ] ------------------------------------------------------- - -FuncType - : Type "(" ParamTypes ")" << astx.NewFuncType($0, $2) >> -; - -ParamTypes - : empty - | "..." << astx.NewParams(nil, true) >> - | ParamTypeList << astx.NewParams($0, false) >> - | ParamTypeList "," "..." << astx.NewParams($0, true) >> -; - -ParamTypeList - : ParamType << astx.NewParamList($0) >> - | ParamTypeList "," ParamType << astx.AppendParam($0, $2) >> -; - -ParamType - : FirstClassType << astx.NewParam($0, nil) >> -; - -// --- [ Integer type ] -------------------------------------------------------- - -IntType - : int_type << astx.NewIntType($0) >> -; - -// --- [ Floating-point type ] ------------------------------------------------- - -FloatType - : "half" << &ast.FloatType{Kind: ast.FloatKindIEEE_16}, nil >> - | "float" << &ast.FloatType{Kind: ast.FloatKindIEEE_32}, nil >> - | "double" << &ast.FloatType{Kind: ast.FloatKindIEEE_64}, nil >> - | "fp128" << &ast.FloatType{Kind: ast.FloatKindIEEE_128}, nil >> - | "x86_fp80" << &ast.FloatType{Kind: ast.FloatKindDoubleExtended_80}, nil >> - | "ppc_fp128" << &ast.FloatType{Kind: ast.FloatKindDoubleDouble_128}, nil >> -; - -// --- [ Pointer type ] -------------------------------------------------------- - -PointerType - : Type OptAddrSpace "*" << astx.NewPointerType($0, $1) >> -; - -OptAddrSpace - : empty - | "addrspace" "(" IntLit ")" << $2, nil >> -; - -// --- [ Vector type ] --------------------------------------------------------- - -VectorType - : "<" IntLit "x" ConcreteType ">" << astx.NewVectorType($1, $3) >> -; - -// --- [ Label type ] ---------------------------------------------------------- - -LabelType - : "label" << &ast.LabelType{}, nil >> -; - -// --- [ Metadata type ] ------------------------------------------------------- - -MetadataType - : "metadata" << &ast.MetadataType{}, nil >> -; - -// --- [ Array type ] ---------------------------------------------------------- - -ArrayType - : "[" IntLit "x" ConcreteType "]" << astx.NewArrayType($1, $3) >> -; - -// --- [ struct type ] --------------------------------------------------------- - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// StructType -// : "{" Fields "}" -// | "<" "{" Fields "}" ">" -// ; -// -// Fields -// : empty -// | FieldList -// ; -StructType - : "{" "}" << astx.NewStructType(nil) >> - | "{" FieldList "}" << astx.NewStructType($1) >> - | "<" "{" "}" ">" << astx.NewStructType(nil) >> - | "<" "{" FieldList "}" ">" << astx.NewStructType($2) >> -; - -FieldList - : ConcreteType << astx.NewTypeList($0) >> - | FieldList "," ConcreteType << astx.AppendType($0, $2) >> -; - -// --- [ Named type ] ---------------------------------------------------------- - -NamedType - : LocalIdent << astx.NewTypeIdent($0) >> -; - -// === [ Values ] ============================================================== - -Value - : LocalIdent - | Constant -; - -// === [ Constants ] =========================================================== - -Constant - : IntConst - | FloatConst - | NullConst - | VectorConst - | ArrayConst - | CharArrayConst - | StructConst - | ZeroInitializerConst - | GlobalIdent - | UndefConst - | ConstExpr -; - -// --- [ Integer constant ] ---------------------------------------------------- - -IntConst - : IntLit - | BoolLit -; - -IntLit - : int_lit << astx.NewIntLit($0) >> -; - -BoolLit - : "true" << astx.NewBoolLit($0) >> - | "false" << astx.NewBoolLit($0) >> -; - -// --- [ Floating-point constant ] --------------------------------------------- - -FloatConst - : float_lit << astx.NewFloatLit($0) >> -; - -// --- [ Pointer constant ] ---------------------------------------------------- - -NullConst - : "null" << &astx.NullLit{}, nil >> -; - -// --- [ Vector constant ] ----------------------------------------------------- - -VectorConst - : "<" ElemList ">" << astx.NewVectorConst($1) >> -; - -// --- [ Array constant ] ------------------------------------------------------ - -ArrayConst - : "[" Elems "]" << astx.NewArrayConst($1) >> -; - -CharArrayConst - : "c" string_lit << astx.NewCharArrayConst($1) >> -; - -// --- [ Struct constant ] ----------------------------------------------------- - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// StructConst -// : "{" Elems "}" -// | "<" "{" Elems "}" ">" -// ; -StructConst - : "{" "}" << astx.NewStructConst(nil) >> - | "{" ElemList "}" << astx.NewStructConst($1) >> - | "<" "{" "}" ">" << astx.NewStructConst(nil) >> - | "<" "{" ElemList "}" ">" << astx.NewStructConst($2) >> -; - -// --- [ Zero initializer constant ] ------------------------------------------- - -ZeroInitializerConst - : "zeroinitializer" << &astx.ZeroInitializerLit{}, nil >> -; - -// --- [ Undefined value constant ] -------------------------------------------- - -UndefConst - : "undef" << &astx.UndefLit{}, nil >> -; - -// === [ Constant expressions ] ================================================ - -ConstExpr - // Binary expressions - : AddExpr - | FAddExpr - | SubExpr - | FSubExpr - | MulExpr - | FMulExpr - | UDivExpr - | SDivExpr - | FDivExpr - | URemExpr - | SRemExpr - | FRemExpr - // Bitwise expressions - | ShlExpr - | LShrExpr - | AShrExpr - | AndExpr - | OrExpr - | XorExpr - // Vector expressions - | ExtractElementExpr - | InsertElementExpr - | ShuffleVectorExpr - // Aggregate expressions - | ExtractValueExpr - | InsertValueExpr - // Memory expressions - | GetElementPtrExpr - // Conversion expressions - | TruncExpr - | ZExtExpr - | SExtExpr - | FPTruncExpr - | FPExtExpr - | FPToUIExpr - | FPToSIExpr - | UIToFPExpr - | SIToFPExpr - | PtrToIntExpr - | IntToPtrExpr - | BitCastExpr - | AddrSpaceCastExpr - // Other expressions - | ICmpExpr - | FCmpExpr - | SelectExpr -; - -// --- [ Binary expressions ] -------------------------------------------------- - -AddExpr - : "add" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewAddExpr($2, $3, $5, $6) >> -; - -FAddExpr - : "fadd" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewFAddExpr($2, $3, $5, $6) >> -; - -SubExpr - : "sub" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewSubExpr($2, $3, $5, $6) >> -; - -FSubExpr - : "fsub" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewFSubExpr($2, $3, $5, $6) >> -; - -MulExpr - : "mul" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewMulExpr($2, $3, $5, $6) >> -; - -FMulExpr - : "fmul" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewFMulExpr($2, $3, $5, $6) >> -; - -UDivExpr - : "udiv" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewUDivExpr($2, $3, $5, $6) >> -; - -SDivExpr - : "sdiv" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewSDivExpr($2, $3, $5, $6) >> -; - -FDivExpr - : "fdiv" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewFDivExpr($2, $3, $5, $6) >> -; - -URemExpr - : "urem" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewURemExpr($2, $3, $5, $6) >> -; - -SRemExpr - : "srem" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewSRemExpr($2, $3, $5, $6) >> -; - -FRemExpr - : "frem" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewFRemExpr($2, $3, $5, $6) >> -; - -// --- [ Bitwise expressions ] ------------------------------------------------- - -ShlExpr - : "shl" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewShlExpr($2, $3, $5, $6) >> -; - -LShrExpr - : "lshr" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewLShrExpr($2, $3, $5, $6) >> -; - -AShrExpr - : "ashr" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewAShrExpr($2, $3, $5, $6) >> -; - -AndExpr - : "and" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewAndExpr($2, $3, $5, $6) >> -; - -OrExpr - : "or" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewOrExpr($2, $3, $5, $6) >> -; - -XorExpr - : "xor" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewXorExpr($2, $3, $5, $6) >> -; - -// --- [ Vector expressions ] -------------------------------------------------- - -ExtractElementExpr - : "extractelement" "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewExtractElementExpr($2, $3, $5, $6) >> -; - -InsertElementExpr - : "insertelement" "(" ConcreteType Constant "," ConcreteType Constant "," ConcreteType Constant ")" << astx.NewInsertElementExpr($2, $3, $5, $6, $8, $9) >> -; - -ShuffleVectorExpr - : "shufflevector" "(" ConcreteType Constant "," ConcreteType Constant "," ConcreteType Constant ")" << astx.NewShuffleVectorExpr($2, $3, $5, $6, $8, $9) >> -; - -// --- [ Aggregate expressions ] ----------------------------------------------- - -ExtractValueExpr - : "extractvalue" "(" ConcreteType Constant "," IntLitList ")" << astx.NewExtractValueExpr($2, $3, $5) >> -; - -InsertValueExpr - : "insertvalue" "(" ConcreteType Constant "," ConcreteType Constant "," IntLitList ")" << astx.NewInsertValueExpr($2, $3, $5, $6, $8) >> -; - -// --- [ Memory expressions ] -------------------------------------------------- - -GetElementPtrExpr - : "getelementptr" OptInbounds "(" ConcreteType "," ConcreteType Constant ConstIndices ")" << astx.NewGetElementPtrExpr($3, $5, $6, $7) >> -; - -ConstIndices - : empty - | "," ConstIndexList << $1, nil >> -; - -ConstIndexList - : ConstIndex << astx.NewConstantList($0) >> - | ConstIndexList "," ConstIndex << astx.AppendConstant($0, $2) >> -; - -ConstIndex - : IntType Constant << astx.NewConstant($0, $1) >> -; - -// --- [ Conversion expressions ] ---------------------------------------------- - -TruncExpr - : "trunc" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewTruncExpr($2, $3, $5) >> -; - -ZExtExpr - : "zext" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewZExtExpr($2, $3, $5) >> -; - -SExtExpr - : "sext" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewSExtExpr($2, $3, $5) >> -; - -FPTruncExpr - : "fptrunc" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewFPTruncExpr($2, $3, $5) >> -; - -FPExtExpr - : "fpext" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewFPExtExpr($2, $3, $5) >> -; - -FPToUIExpr - : "fptoui" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewFPToUIExpr($2, $3, $5) >> -; - -FPToSIExpr - : "fptosi" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewFPToSIExpr($2, $3, $5) >> -; - -UIToFPExpr - : "uitofp" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewUIToFPExpr($2, $3, $5) >> -; - -SIToFPExpr - : "sitofp" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewSIToFPExpr($2, $3, $5) >> -; - -PtrToIntExpr - : "ptrtoint" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewPtrToIntExpr($2, $3, $5) >> -; - -IntToPtrExpr - : "inttoptr" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewIntToPtrExpr($2, $3, $5) >> -; - -BitCastExpr - : "bitcast" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewBitCastExpr($2, $3, $5) >> -; - -AddrSpaceCastExpr - : "addrspacecast" "(" ConcreteType Constant "to" ConcreteType ")" << astx.NewAddrSpaceCastExpr($2, $3, $5) >> -; - -// --- [ Other expressions ] --------------------------------------------------- - -ICmpExpr - : "icmp" IntPred "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewICmpExpr($1, $3, $4, $6, $7) >> -; - -FCmpExpr - : "fcmp" FloatPred "(" ConcreteType Constant "," ConcreteType Constant ")" << astx.NewFCmpExpr($1, $3, $4, $6, $7) >> -; - -SelectExpr - : "select" "(" ConcreteType Constant "," ConcreteType Constant "," ConcreteType Constant ")" << astx.NewSelectExpr($2, $3, $5, $6, $8, $9) >> -; - -// === [ Basic blocks ] ======================================================== - -BasicBlockList - : BasicBlock << astx.NewBasicBlockList($0) >> - | BasicBlockList BasicBlock << astx.AppendBasicBlock($0, $1) >> -; - -BasicBlock - : OptLabelIdent Instructions Terminator << astx.NewBasicBlock($0, $1, $2) >> -; - -OptLabelIdent - : empty - | LabelIdent -; - -// === [ Instructions ] ======================================================== - -Instructions - : empty - | InstructionList -; - -InstructionList - : Instruction << astx.NewInstructionList($0) >> - | InstructionList Instruction << astx.AppendInstruction($0, $1) >> -; - -Instruction - : StoreInst - | FenceInst - | CmpXchgInst - | AtomicRMWInst - | LocalIdent "=" ValueInstruction << astx.NewNamedInstruction($0, $2) >> - | ValueInstruction -; - -ValueInstruction - // Binary instructions - : AddInst - | FAddInst - | SubInst - | FSubInst - | MulInst - | FMulInst - | UDivInst - | SDivInst - | FDivInst - | URemInst - | SRemInst - | FRemInst - // Bitwise instructions - | ShlInst - | LShrInst - | AShrInst - | AndInst - | OrInst - | XorInst - // Vector instructions - | ExtractElementInst - | InsertElementInst - | ShuffleVectorInst - // Aggregate instructions - | ExtractValueInst - | InsertValueInst - // Memory instructions - | AllocaInst - | LoadInst - | GetElementPtrInst - // Conversion instructions - | TruncInst - | ZExtInst - | SExtInst - | FPTruncInst - | FPExtInst - | FPToUIInst - | FPToSIInst - | UIToFPInst - | SIToFPInst - | PtrToIntInst - | IntToPtrInst - | BitCastInst - | AddrSpaceCastInst - // Other instructions - | ICmpInst - | FCmpInst - | PhiInst - | SelectInst - | CallInst - | VAArgInst - | LandingPadInst - | CatchPadInst - | CleanupPadInst -; - -// --- [ Binary instructions ] ------------------------------------------------- - -// ~~~ [ add ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -AddInst - : "add" OverflowFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewAddInst($2, $3, $5, $6) >> -; - -// ~~~ [ fadd ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FAddInst - : "fadd" FastMathFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewFAddInst($2, $3, $5, $6) >> -; - -// ~~~ [ sub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SubInst - : "sub" OverflowFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewSubInst($2, $3, $5, $6) >> -; - -// ~~~ [ fsub ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FSubInst - : "fsub" FastMathFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewFSubInst($2, $3, $5, $6) >> -; - -// ~~~ [ mul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -MulInst - : "mul" OverflowFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewMulInst($2, $3, $5, $6) >> -; - -// ~~~ [ fmul ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FMulInst - : "fmul" FastMathFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewFMulInst($2, $3, $5, $6) >> -; - -// ~~~ [ udiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -UDivInst - : "udiv" OptExact ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewUDivInst($2, $3, $5, $6) >> -; - -// ~~~ [ sdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SDivInst - : "sdiv" OptExact ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewSDivInst($2, $3, $5, $6) >> -; - -// ~~~ [ fdiv ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FDivInst - : "fdiv" FastMathFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewFDivInst($2, $3, $5, $6) >> -; - -// ~~~ [ urem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -URemInst - : "urem" ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewURemInst($1, $2, $4, $5) >> -; - -// ~~~ [ srem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SRemInst - : "srem" ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewSRemInst($1, $2, $4, $5) >> -; - -// ~~~ [ frem ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FRemInst - : "frem" FastMathFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewFRemInst($2, $3, $5, $6) >> -; - -OverflowFlags - : empty - | OverflowFlagList -; - -OverflowFlagList - : OverflowFlag - | OverflowFlagList OverflowFlag -; - -OverflowFlag - : "nuw" - | "nsw" -; - -FastMathFlags - : empty - | FastMathFlagList -; - -FastMathFlagList - : FastMathFlag - | FastMathFlagList FastMathFlag -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#fast-math-flags -FastMathFlag - : "arcp" - | "fast" - | "ninf" - | "nnan" - | "nsz" -; - -OptExact - : empty - | "exact" -; - -// --- [ Bitwise instructions ] ------------------------------------------------ - -// ~~~ [ shl ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ShlInst - : "shl" OverflowFlags ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewShlInst($2, $3, $5, $6) >> -; - -// ~~~ [ lshr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -LShrInst - : "lshr" OptExact ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewLShrInst($2, $3, $5, $6) >> -; - -// ~~~ [ ashr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -AShrInst - : "ashr" OptExact ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewAShrInst($2, $3, $5, $6) >> -; - -// ~~~ [ and ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -AndInst - : "and" ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewAndInst($1, $2, $4, $5) >> -; - -// ~~~ [ or ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -OrInst - : "or" ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewOrInst($1, $2, $4, $5) >> -; - -// ~~~ [ xor ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -XorInst - : "xor" ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewXorInst($1, $2, $4, $5) >> -; - -// --- [ Vector instructions ] ------------------------------------------------- - -// ~~~ [ extractelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ExtractElementInst - : "extractelement" ConcreteType Value "," ConcreteType Value OptCommaAttachedMDList << astx.NewExtractElementInst($1, $2, $4, $5, $6) >> -; - -// ~~~ [ insertelement ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -InsertElementInst - : "insertelement" ConcreteType Value "," ConcreteType Value "," ConcreteType Value OptCommaAttachedMDList << astx.NewInsertElementInst($1, $2, $4, $5, $7, $8, $9) >> -; - -// ~~~ [ shufflevector ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ShuffleVectorInst - : "shufflevector" ConcreteType Value "," ConcreteType Value "," ConcreteType Value OptCommaAttachedMDList << astx.NewShuffleVectorInst($1, $2, $4, $5, $7, $8, $9) >> -; - -// --- [ Aggregate instructions ] --------------------------------------------- - -// ~~~ [ extractvalue ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ExtractValueInst - : "extractvalue" ConcreteType Value "," IntLitList OptCommaAttachedMDList << astx.NewExtractValueInst($1, $2, $4, $5) >> -; - -IntLitList - : IntLit << astx.NewIntLitList($0) >> - | IntLitList "," IntLit << astx.AppendIntLit($0, $2) >> -; - -// ~~~ [ insertvalue ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -InsertValueInst - : "insertvalue" ConcreteType Value "," ConcreteType Value "," IntLitList OptCommaAttachedMDList << astx.NewInsertValueInst($1, $2, $4, $5, $7, $8) >> -; - -// --- [ Memory instructions ] ------------------------------------------------- - -// ~~~ [ alloca ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// AllocaInst -// : "alloca" ConcreteType OptCommaNElems OptCommaAlign OptCommaAttachedMDList << astx.NewAllocaInst($1, $2, $4) >> -// ; -// -// OptCommaNElems -// : empty -// | "," NElems << $1 >> -// ; -AllocaInst - : "alloca" ConcreteType OptCommaAttachedMDList << astx.NewAllocaInst($1, nil, $2) >> - | "alloca" ConcreteType "," Align OptCommaAttachedMDList << astx.NewAllocaInst($1, nil, $4) >> - | "alloca" ConcreteType "," NElems OptCommaAttachedMDList << astx.NewAllocaInst($1, $3, $4) >> - | "alloca" ConcreteType "," NElems "," Align OptCommaAttachedMDList << astx.NewAllocaInst($1, $3, $6) >> -; - -NElems - : ConcreteType Value << astx.NewValue($0, $1) >> -; - -// ~~~ [ load ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// LoadInst -// : "load" OptVolatile ConcreteType "," PointerType Value OptCommaAlign OptCommaAttachedMDList << astx.NewLoadInst($2, $4, $5, $7) >> -// ; -LoadInst - : "load" OptVolatile ConcreteType "," PointerType Value OptCommaAttachedMDList << astx.NewLoadInst($2, $4, $5, $6) >> - | "load" OptVolatile ConcreteType "," PointerType Value "," Align OptCommaAttachedMDList << astx.NewLoadInst($2, $4, $5, $8) >> -; - -OptVolatile - : empty - | "volatile" -; - -// ~~~ [ store ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// -// StoreInst -// : "store" OptVolatile ConcreteType Value "," PointerType Value OptCommaAlign OptCommaAttachedMDList << astx.NewStoreInst($2, $3, $5, $6, $8) >> -// ; -StoreInst - : "store" OptVolatile ConcreteType Value "," PointerType Value OptCommaAttachedMDList << astx.NewStoreInst($2, $3, $5, $6, $7) >> - | "store" OptVolatile ConcreteType Value "," PointerType Value "," Align OptCommaAttachedMDList << astx.NewStoreInst($2, $3, $5, $6, $9) >> -; - -// ~~~ [ fence ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FenceInst - : "fence" OptSinglethread Ordering OptCommaAttachedMDList << nil, nil >> -; - -OptSinglethread - : empty - | "singlethread" -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#ordering -Ordering - : "acq_rel" - | "acquire" - | "monotonic" - | "release" - | "seq_cst" - | "unordered" -; - -// ~~~ [ cmpxchg ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CmpXchgInst - : "cmpxchg" OptWeak OptVolatile ConcreteType Value "," ConcreteType Value "," ConcreteType Value OptSinglethread Ordering Ordering OptCommaAttachedMDList << nil, nil >> -; - -OptWeak - : empty - | "weak" -; - -// ~~~ [ atomicrmw ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -AtomicRMWInst - : "atomicrmw" OptVolatile AtomicOperation ConcreteType Value "," ConcreteType Value OptSinglethread Ordering OptCommaAttachedMDList << nil, nil >> -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#atomicrmw-instruction -AtomicOperation - : "add" - | "and" - | "max" - | "min" - | "nand" - | "or" - | "sub" - | "umax" - | "umin" - | "xchg" - | "xor" -; - -// ~~~ [ getelementptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// TODO: Clean up when the parser generator no longer introduces ambiguities -// through the limitation of 1 token lookahead. -// -// Structured in this way to allow for naiive 1 token lookahead parser -// generators. -// -// Original production rule. -// GetElementPtrInst -// : "getelementptr" OptInbounds ConcreteType "," ConcreteType Value Indices OptCommaAttachedMDList << astx.NewGetElementPtrInst($2, $4, $5, $6, $7) >> -// ; -// -// Indices -// : empty -// | "," IndexList << $1, nil >> -// ; -GetElementPtrInst - : "getelementptr" OptInbounds ConcreteType "," ConcreteType Value OptCommaAttachedMDList << astx.NewGetElementPtrInst($2, $4, $5, nil, $6) >> - | "getelementptr" OptInbounds ConcreteType "," ConcreteType Value "," IndexList OptCommaAttachedMDList << astx.NewGetElementPtrInst($2, $4, $5, $7, $8) >> -; - -IndexList - : Index << astx.NewValueList($0) >> - | IndexList "," Index << astx.AppendValue($0, $2) >> -; - -Index - : IntType Value << astx.NewValue($0, $1) >> -; - -// --- [ Conversion instructions ] --------------------------------------------- - -// ~~~ [ trunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -TruncInst - : "trunc" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewTruncInst($1, $2, $4, $5) >> -; - -// ~~~ [ zext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ZExtInst - : "zext" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewZExtInst($1, $2, $4, $5) >> -; - -// ~~~ [ sext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SExtInst - : "sext" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewSExtInst($1, $2, $4, $5) >> -; - -// ~~~ [ fptrunc ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FPTruncInst - : "fptrunc" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewFPTruncInst($1, $2, $4, $5) >> -; - -// ~~~ [ fpext ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FPExtInst - : "fpext" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewFPExtInst($1, $2, $4, $5) >> -; - -// ~~~ [ fptoui ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FPToUIInst - : "fptoui" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewFPToUIInst($1, $2, $4, $5) >> -; - -// ~~~ [ fptosi ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FPToSIInst - : "fptosi" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewFPToSIInst($1, $2, $4, $5) >> -; - -// ~~~ [ uitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -UIToFPInst - : "uitofp" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewUIToFPInst($1, $2, $4, $5) >> -; - -// ~~~ [ sitofp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SIToFPInst - : "sitofp" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewSIToFPInst($1, $2, $4, $5) >> -; - -// ~~~ [ ptrtoint ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -PtrToIntInst - : "ptrtoint" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewPtrToIntInst($1, $2, $4, $5) >> -; - -// ~~~ [ inttoptr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -IntToPtrInst - : "inttoptr" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewIntToPtrInst($1, $2, $4, $5) >> -; - -// ~~~ [ bitcast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -BitCastInst - : "bitcast" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewBitCastInst($1, $2, $4, $5) >> -; - -// ~~~ [ addrspacecast ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -AddrSpaceCastInst - : "addrspacecast" ConcreteType Value "to" ConcreteType OptCommaAttachedMDList << astx.NewAddrSpaceCastInst($1, $2, $4, $5) >> -; - -// --- [ Other instructions ] -------------------------------------------------- - -// ~~~ [ icmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ICmpInst - : "icmp" IntPred ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewICmpInst($1, $2, $3, $5, $6) >> -; - -IntPred - : "eq" << ast.IntEQ, nil >> - | "ne" << ast.IntNE, nil >> - | "ugt" << ast.IntUGT, nil >> - | "uge" << ast.IntUGE, nil >> - | "ult" << ast.IntULT, nil >> - | "ule" << ast.IntULE, nil >> - | "sgt" << ast.IntSGT, nil >> - | "sge" << ast.IntSGE, nil >> - | "slt" << ast.IntSLT, nil >> - | "sle" << ast.IntSLE, nil >> -; - -// ~~~ [ fcmp ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -FCmpInst - : "fcmp" FastMathFlags FloatPred ConcreteType Value "," Value OptCommaAttachedMDList << astx.NewFCmpInst($2, $3, $4, $6, $7) >> -; - -FloatPred - : "false" << ast.FloatFalse, nil >> - | "oeq" << ast.FloatOEQ, nil >> - | "ogt" << ast.FloatOGT, nil >> - | "oge" << ast.FloatOGE, nil >> - | "olt" << ast.FloatOLT, nil >> - | "ole" << ast.FloatOLE, nil >> - | "one" << ast.FloatONE, nil >> - | "ord" << ast.FloatORD, nil >> - | "ueq" << ast.FloatUEQ, nil >> - | "ugt" << ast.FloatUGT, nil >> - | "uge" << ast.FloatUGE, nil >> - | "ult" << ast.FloatULT, nil >> - | "ule" << ast.FloatULE, nil >> - | "une" << ast.FloatUNE, nil >> - | "uno" << ast.FloatUNO, nil >> - | "true" << ast.FloatTrue, nil >> -; - -// ~~~ [ phi ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -PhiInst - : "phi" ConcreteType IncomingList OptCommaAttachedMDList << astx.NewPhiInst($1, $2, $3) >> -; - -IncomingList - : Incoming << astx.NewIncomingList($0) >> - | IncomingList "," Incoming << astx.AppendIncoming($0, $2) >> -; - -Incoming - : "[" Value "," LocalIdent "]" << astx.NewIncoming($1, $3) >> -; - -// ~~~ [ select ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SelectInst - : "select" ConcreteType Value "," ConcreteType Value "," ConcreteType Value OptCommaAttachedMDList << astx.NewSelectInst($1, $2, $4, $5, $7, $8, $9) >> -; - -// ~~~ [ call ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CallInst - : OptTail "call" FastMathFlags OptCallConv ParamAttrs Type Callee "(" Args ")" FuncAttrs OptCommaAttachedMDList << astx.NewCallInst($3, $5, $6, $8, $11) >> -; - -OptTail - : empty - | Tail -; - -Tail - : "tail" - | "musttail" - | "notail" -; - -Callee - : Value - | InlineAsm -; - -Args - : empty - | ArgList -; - -ArgList - : Arg << astx.NewValueList($0) >> - | ArgList "," Arg << astx.AppendValue($0, $2) >> -; - -Arg - : ConcreteType ParamAttrs Value << astx.NewValue($0, $2) >> - | MetadataType MetadataValue << astx.NewMetadataValue($1) >> -; - -// ~~~ [ va_arg ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -VAArgInst - : "va_arg" ConcreteType Value "," ConcreteType OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ landingpad ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -LandingPadInst - : "landingpad" ConcreteType ClauseList OptCommaAttachedMDList << nil, nil >> - | "landingpad" ConcreteType "cleanup" Clauses OptCommaAttachedMDList << nil, nil >> -; - -Clauses - : empty - | ClauseList -; - -ClauseList - : Clause - | ClauseList Clause -; - -Clause - : "catch" ConcreteType Value - | "filter" ConcreteType ArrayConst -; - -// ~~~ [ catchpad ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CatchPadInst - : "catchpad" "within" LocalIdent ArrayConst OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ cleanuppad ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CleanupPadInst - : "cleanuppad" "within" ExceptionParent ArrayConst OptCommaAttachedMDList << nil, nil >> -; - -ExceptionParent - : "none" - | LocalIdent -; - -// === [ Terminators ] ========================================================= - -Terminator - : RetTerm - | BrTerm - | CondBrTerm - | SwitchTerm - | IndirectBrTerm - | InvokeTerm - | ResumeTerm - | CatchSwitchTerm - | CatchRetTerm - | CleanupRetTerm - | UnreachableTerm -; - -// ~~~ [ ret ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -RetTerm - : "ret" VoidType OptCommaAttachedMDList << astx.NewRetTerm(nil, nil, $2) >> - | "ret" ConcreteType Value OptCommaAttachedMDList << astx.NewRetTerm($1, $2, $3) >> -; - -// ~~~ [ br ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// Unconditional branch terminator. -BrTerm - : "br" LabelType LocalIdent OptCommaAttachedMDList << astx.NewBrTerm($1, $2, $3) >> -; - -// Conditional branch terminator. -CondBrTerm - : "br" IntType Value "," LabelType LocalIdent "," LabelType LocalIdent OptCommaAttachedMDList << astx.NewCondBrTerm($1, $2, $4, $5, $7, $8, $9) >> -; - -// ~~~ [ switch ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -SwitchTerm - : "switch" IntType Value "," LabelType LocalIdent "[" Cases "]" OptCommaAttachedMDList << astx.NewSwitchTerm($1, $2, $4, $5, $7, $9) >> -; - -Cases - : empty - | CastList -; - -CastList - : Case << astx.NewCaseList($0) >> - | CastList Case << astx.AppendCase($0, $1) >> -; - -Case - : IntType Value "," LabelType LocalIdent << astx.NewCase($0, $1, $3, $4) >> -; - -// ~~~ [ indirectbr ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -IndirectBrTerm - : "indirectbr" ConcreteType Value "," "[" Labels "]" OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ invoke ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -InvokeTerm - : "invoke" OptCallConv ParamAttrs Type Callee "(" Args ")" FuncAttrs OptOperandBundle "to" LabelType LocalIdent "unwind" LabelType LocalIdent OptCommaAttachedMDList << nil, nil >> -; - -OptOperandBundle - : empty - | OperandBundle -; - -OperandBundle - : "[" TagValues "]" -; - -TagValues - : empty - | TagValueList -; - -TagValueList - : TagValue - | TagValueList "," TagValue -; - -TagValue - : string_lit "(" Values ")" -; - -Values - : empty - | ValueList -; - -ValueList - : ConcreteType Value - | ValueList "," ConcreteType Value -; - -// ~~~ [ resume ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -ResumeTerm - : "resume" ConcreteType Value OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ catchswitch ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CatchSwitchTerm - : "catchswitch" "within" ExceptionParent "[" Labels "]" "unwind" "to" "caller" OptCommaAttachedMDList << nil, nil >> - | "catchswitch" "within" ExceptionParent "[" Labels "]" "unwind" LabelType LocalIdent OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ catchret ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CatchRetTerm - : "catchret" "from" Value "to" LabelType LocalIdent OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ cleanupret ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -CleanupRetTerm - : "cleanupret" "from" Value "unwind" "to" "caller" OptCommaAttachedMDList << nil, nil >> - | "cleanupret" "from" Value "unwind" LabelType LocalIdent OptCommaAttachedMDList << nil, nil >> -; - -// ~~~ [ unreachable ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -UnreachableTerm - : "unreachable" OptCommaAttachedMDList << astx.NewUnreachableTerm($1) >> -; - -// ### [ Helper productions ] ################################################## - -OptLinkage - : empty - | Linkage -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#linkage -Linkage - : "appending" - | "available_externally" - | "common" - | "internal" - | "linkonce" - | "linkonce_odr" - | "private" - | "weak" - | "weak_odr" -; - -OptExternLinkage - : empty - | ExternLinkage -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#linkage -ExternLinkage - : "extern_weak" - | "external" -; - -OptVisibility - : empty - | Visibility -; - -// From spec of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#visibility-styles -Visibility - : "default" - | "hidden" - | "protected" -; - -OptDLLStorageClass - : empty - | DLLStorageClass -; - -// From spec of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#dllstorageclass -DLLStorageClass - : "dllimport" - | "dllexport" -; - -OptThreadLocal - : empty - | ThreadLocal -; - -// From spec of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#thread-local-storage-models -ThreadLocal - : "thread_local" - | "thread_local" "(" TLSModel ")" -; - -TLSModel - : "localdynamic" - | "initialexec" - | "localexec" -; - -OptUnnamedAddr - : empty - | UnnamedAddr -; - -UnnamedAddr - : "local_unnamed_addr" - | "unnamed_addr" -; - -OptSection - : empty - | Section -; - -Section - : "section" string_lit -; - -OptComdat - : empty - | Comdat -; - -Comdat - : "comdat" - | "comdat" "(" ComdatName ")" -; - -OptAlign - : empty - | Align -; - -Align - : "align" IntLit -; - -OptGC - : empty - | GC -; - -GC - : "gc" string_lit -; - -OptPrefix - : empty - | Prefix -; - -// ref: http://llvm.org/docs/LangRef.html#prefix-data -Prefix - : "prefix" ConcreteType Constant -; - -OptPrologue - : empty - | Prologue -; - -// ref: http://llvm.org/docs/LangRef.html#prologue-data -Prologue - : "prologue" ConcreteType Constant -; - -OptPersonality - : empty - | Personality -; - -// ref: http://llvm.org/docs/LangRef.html#personality-function -Personality - : "personality" ConcreteType Constant -; - -ParamAttrs - : empty - | ParamAttrList -; - -ParamAttrList - : ParamAttr - | ParamAttrList ParamAttr -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#parameter-attributes -ParamAttr - : string_lit - | string_lit "=" string_lit - | Align - | "byval" - | "dereferenceable" "(" IntLit ")" - | "dereferenceable_or_null" "(" IntLit ")" - | "inalloca" - | "inreg" - | "nest" - | "noalias" - | "nocapture" - | "nonnull" - | "readnone" // NOTE: accepted by lli but not part of spec in v4.0 - | "readonly" // NOTE: accepted by lli but not part of spec in v4.0 - | "returned" - | "signext" - | "sret" - | "swifterror" - | "swiftself" - | "writeonly" // NOTE: accepted by lli but not part of spec in v4.0 - | "zeroext" -; - -FuncAttrs - : empty - | FuncAttrList -; - -FuncAttrList - : FuncAttr - | FuncAttrList FuncAttr -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#function-attributes -FuncAttr - : string_lit - | string_lit "=" string_lit - | AttrGroupID - | "alignstack" "=" IntLit // NOTE: only valid in attribute group definitions. - | "alignstack" "(" IntLit ")" - | "allocsize" "(" IntLit ")" - | "allocsize" "(" IntLit "," IntLit ")" - | "alwaysinline" - | "argmemonly" - | "builtin" - | "cold" - | "convergent" - | "inaccessiblemem_or_argmemonly" - | "inaccessiblememonly" - | "inlinehint" - | "jumptable" - | "minsize" - | "naked" - | "nobuiltin" - | "noduplicate" - | "noimplicitfloat" - | "noinline" - | "nonlazybind" - | "norecurse" - | "noredzone" - | "noreturn" - | "nounwind" - | "optnone" - | "optsize" - | "readnone" - | "readonly" - | "returns_twice" - | "safestack" - | "sanitize_address" - | "sanitize_memory" - | "sanitize_thread" - | "ssp" - | "sspreq" - | "sspstrong" - | "uwtable" - | "writeonly" -; - -Elems - : empty - | ElemList -; - -ElemList - : Elem << astx.NewConstantList($0) >> - | ElemList "," Elem << astx.AppendConstant($0, $2) >> -; - -Elem - : ConcreteType Value << astx.NewConstant($0, $1) >> -; - -OptCallConv - : empty << ast.CallConvNone, nil >> - | CallConv -; - -// From spec and src of v4.0. -// -// ref: http://llvm.org/docs/LangRef.html#callingconv -CallConv - : "amdgpu_cs" << ast.CallConvAMDGPU_CS, nil >> - | "amdgpu_gs" << ast.CallConvAMDGPU_GS, nil >> - | "amdgpu_kernel" << ast.CallConvAMDGPU_Kernel, nil >> - | "amdgpu_ps" << ast.CallConvAMDGPU_PS, nil >> - | "amdgpu_vs" << ast.CallConvAMDGPU_VS, nil >> - | "anyregcc" << ast.CallConvAnyReg, nil >> - | "arm_aapcs_vfpcc" << ast.CallConvARM_AAPCS_VFP, nil >> - | "arm_aapcscc" << ast.CallConvARM_AAPCS, nil >> - | "arm_apcscc" << ast.CallConvARM_APCS, nil >> - | "avr_intrcc" << ast.CallConvAVR_Intr, nil >> - | "avr_signalcc" << ast.CallConvAVR_Signal, nil >> - | "cc" IntLit << astx.NewCallConv($1) >> - | "ccc" << ast.CallConvC, nil >> - | "coldcc" << ast.CallConvCold, nil >> - | "cxx_fast_tlscc" << ast.CallConvCXX_Fast_TLS, nil >> - | "fastcc" << ast.CallConvFast, nil >> - | "ghccc" << ast.CallConvGHC, nil >> - | "hhvm_ccc" << ast.CallConvHHVM_C, nil >> - | "hhvmcc" << ast.CallConvHHVM, nil >> - | "intel_ocl_bicc" << ast.CallConvIntel_OCL_BI, nil >> - | "msp430_intrcc" << ast.CallConvMSP430_Intr, nil >> - | "preserve_allcc" << ast.CallConvPreserveAll, nil >> - | "preserve_mostcc" << ast.CallConvPreserveMost, nil >> - | "ptx_device" << ast.CallConvPTX_Device, nil >> - | "ptx_kernel" << ast.CallConvPTX_Kernel, nil >> - | "spir_func" << ast.CallConvSPIR_Func, nil >> - | "spir_kernel" << ast.CallConvSPIR_Kernel, nil >> - | "swiftcc" << ast.CallConvSwift, nil >> - | "webkit_jscc" << ast.CallConvWebKit_JS, nil >> - | "x86_64_sysvcc" << ast.CallConvX86_64_SysV, nil >> - | "x86_64_win64cc" << ast.CallConvX86_64_Win64, nil >> - | "x86_fastcallcc" << ast.CallConvX86_FastCall, nil >> - | "x86_intrcc" << ast.CallConvX86_Intr, nil >> - | "x86_regcallcc" << ast.CallConvX86_RegCall, nil >> - | "x86_stdcallcc" << ast.CallConvX86_StdCall, nil >> - | "x86_thiscallcc" << ast.CallConvX86_ThisCall, nil >> - | "x86_vectorcallcc" << ast.CallConvX86_VectorCall, nil >> -; - -InlineAsm - : "asm" OptSideEffect OptAlignStack OptIntelDialect string_lit "," string_lit << astx.NewInlineAsm($4, $6) >> -; - -OptSideEffect - : empty - | "sideeffect" -; - -OptAlignStack - : empty - | "alignstack" -; - -OptIntelDialect - : empty - | "inteldialect" -; - -Labels - : empty - | LabelList -; - -LabelList - : Label - | LabelList "," Label -; - -Label - : LabelType LocalIdent -; - -OptInbounds - : empty - | "inbounds" -; - -AttachedMDs - : empty - | AttachedMDList -; - -AttachedMDList - : AttachedMD << astx.NewAttachedMDList($0) >> - | AttachedMDList AttachedMD << astx.AppendAttachedMD($0, $1) >> -; - -AttachedMD - : MetadataName MD << astx.NewAttachedMD($0, $1) >> -; - -MD - : Metadata - | MetadataID -; - -OptCommaAttachedMDList - : empty - | CommaAttachedMDList -; - -CommaAttachedMDList - : "," AttachedMD << astx.NewAttachedMDList($1) >> - | CommaAttachedMDList "," AttachedMD << astx.AppendAttachedMD($0, $2) >> -; diff --git a/llvm/asm/internal/parser/asm_test.go b/llvm/asm/internal/parser/asm_test.go deleted file mode 100755 index 3446309..0000000 --- a/llvm/asm/internal/parser/asm_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package parser_test - -import ( - "fmt" - "io/ioutil" - "testing" - - "github.com/geode-lang/geode/llvm/asm" - "github.com/sergi/go-diff/diffmatchpatch" -) - -func TestRoundTrip(t *testing.T) { - // Round-trip test of the parser. - golden := []struct { - path string - }{ - // Empty module. - {path: "../../testdata/empty.ll"}, - // Top-level declarations. - {path: "../../testdata/module.ll"}, - {path: "../../testdata/global.ll"}, - {path: "../../testdata/global_circular.ll"}, - {path: "../../testdata/func.ll"}, - {path: "../../testdata/metadata.ll"}, - // Types. - {path: "../../testdata/type.ll"}, - // Constants. - {path: "../../testdata/const.ll"}, - // Constant expressions. - {path: "../../testdata/expr_binary.ll"}, - {path: "../../testdata/expr_bitwise.ll"}, - {path: "../../testdata/expr_vector.ll"}, - {path: "../../testdata/expr_aggregate.ll"}, - {path: "../../testdata/expr_memory.ll"}, - {path: "../../testdata/expr_conversion.ll"}, - {path: "../../testdata/expr_other.ll"}, - // Instructions. - {path: "../../testdata/inst_binary.ll"}, - {path: "../../testdata/inst_bitwise.ll"}, - {path: "../../testdata/inst_vector.ll"}, - {path: "../../testdata/inst_aggregate.ll"}, - {path: "../../testdata/inst_memory.ll"}, - {path: "../../testdata/inst_conversion.ll"}, - {path: "../../testdata/inst_other.ll"}, - // Terminators. - {path: "../../testdata/term.ll"}, - // Pseudo-random number generator. - {path: "../../testdata/rand.ll"}, - // Inline assembly. - {path: "../../testdata/inline_asm.ll"}, - // Fixed bugs. - {path: "../../testdata/fixedbugs/issue_27.ll"}, - } - dmp := diffmatchpatch.New() - for _, g := range golden { - buf, err := ioutil.ReadFile(g.path) - if err != nil { - t.Errorf("%q: unable to read file; %v", g.path, err) - continue - } - input := string(buf) - m, err := asm.ParseString(input) - if err != nil { - t.Errorf("%q: unable to parse file; %v", g.path, err) - continue - } - want := input - // Read foo.ll.golden if present. - if buf, err := ioutil.ReadFile(g.path + ".golden"); err == nil { - want = string(buf) - } - got := m.String() - if want != got { - diffs := dmp.DiffMain(want, got, false) - fmt.Println(dmp.DiffPrettyText(diffs)) - t.Errorf("%q: module mismatch; expected `%v`, got `%v`", g.path, want, got) - continue - } - } -} - -func BenchmarkParseFile(b *testing.B) { - const path = "../testdata/sqlite/sqlite.ll" - buf, err := ioutil.ReadFile(path) - if err != nil { - b.Errorf("%q: unable to read file; %v", path, err) - return - } - input := string(buf) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := asm.ParseString(input) - if err != nil { - b.Errorf("%q: unable to parse file; %v", path, err) - return - } - } -} diff --git a/llvm/enc/enc.go b/llvm/enc/enc.go deleted file mode 100755 index d2543bf..0000000 --- a/llvm/enc/enc.go +++ /dev/null @@ -1,239 +0,0 @@ -package enc - -import ( - "fmt" - "strings" -) - -// Global encodes a global name to its LLVM IR assembly representation. -// -// Examples: -// "foo" -> "@foo" -// "a b" -> `@"a\20b"` -// "世" -> `@"\E4\B8\96"` -// -// References: -// http://www.llvm.org/docs/LangRef.html#identifiers -func Global(name string) string { - return "@" + EscapeIdent(name) -} - -// Local encodes a local name to its LLVM IR assembly representation. -// -// Examples: -// "foo" -> "%foo" -// "a b" -> `%"a\20b"` -// "世" -> `%"\E4\B8\96"` -// -// References: -// http://www.llvm.org/docs/LangRef.html#identifiers -func Local(name string) string { - return "%" + EscapeIdent(name) -} - -// Metadata encodes a metadata name to its LLVM IR assembly representation. -// -// Examples: -// "foo" -> "!foo" -// "a b" -> `!a\20b` -// "世" -> `!\E4\B8\96` -// -// References: -// http://www.llvm.org/docs/LangRef.html#identifiers -func Metadata(name string) string { - valid := func(b byte) bool { - const metadataChar = tail + `\` - return strings.IndexByte(metadataChar, b) != -1 - } - return "!" + Escape(name, valid) -} - -const ( - // decimal specifies the decimal digit characters. - decimal = "0123456789" - // upper specifies the uppercase letters. - upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - // lower specifies the lowercase letters. - lower = "abcdefghijklmnopqrstuvwxyz" - // alpha specifies the alphabetic characters. - alpha = upper + lower - // head is the set of valid characters for the first character of an - // identifier. - head = alpha + "$-._" - // tail is the set of valid characters for the remaining characters of an - // identifier (i.e. all characters in the identifier except the first). All - // characters of a label may be from the tail set, even the first character. - tail = head + decimal -) - -// // EscapeIdent takes a string, and if it contains invalid llvm chars, surrounds -// // it in quotes -// func EscapeIdent(s string) string { -// // Check if a replacement is required. -// extra := 0 -// for i := 0; i < len(s); i++ { -// if strings.IndexByte(tail, s[i]) == -1 { -// // Two extra bytes are required for each invalid byte; e.g. -// // "#" -> `\23` -// // "世" -> `\E4\B8\96` -// extra += 2 -// } -// } -// if extra == 0 { -// return s -// } -// // Add surrounding quotes. -// return `"` + s + `"` -// } -// EscapeIdent replaces any characters which are not valid in identifiers with -// corresponding hexadecimal escape sequence (\XX). -func EscapeIdent(s string) string { - // Check if a replacement is required. - extra := 0 - for i := 0; i < len(s); i++ { - if strings.IndexByte(tail, s[i]) == -1 { - // Two extra bytes are required for each invalid byte; e.g. - // "#" -> `\23` - // "世" -> `\E4\B8\96` - extra += 2 - } - } - if extra == 0 { - return s - } - - // Replace invalid characters. - const hextable = "0123456789ABCDEF" - buf := make([]byte, len(s)+extra) - j := 0 - for i := 0; i < len(s); i++ { - b := s[i] - if strings.IndexByte(tail, b) != -1 { - buf[j] = b - j++ - continue - } - buf[j] = '\\' - buf[j+1] = hextable[b>>4] - buf[j+2] = hextable[b&0x0F] - j += 3 - } - // Add surrounding quotes. - return `"` + string(buf) + `"` -} - -// EscapeString replaces any characters categorized as invalid in string -// literals with corresponding hexadecimal escape sequence (\XX). -func EscapeString(s string) string { - valid := func(b byte) bool { - return ' ' <= b && b <= '~' && b != '"' && b != '\\' - } - return Escape(s, valid) -} - -// Escape replaces any characters categorized as invalid by the valid function -// with corresponding hexadecimal escape sequence (\XX). -func Escape(s string, valid func(b byte) bool) string { - // Check if a replacement is required. - extra := 0 - for i := 0; i < len(s); i++ { - b := s[i] - switch { - case !valid(b): - // Two extra bytes are required for each invalid byte; e.g. - // "#" -> `\23` - // "世" -> `\E4\B8\96` - extra += 2 - default: - // no extra bytes required. - } - } - if extra == 0 { - return s - } - - // Replace invalid characters. - const hextable = "0123456789ABCDEF" - buf := make([]byte, len(s)+extra) - j := 0 - for i := 0; i < len(s); i++ { - b := s[i] - switch { - case !valid(b): - buf[j] = '\\' - buf[j+1] = hextable[b>>4] - buf[j+2] = hextable[b&0x0F] - j += 3 - default: - buf[j] = b - j++ - } - } - return string(buf) -} - -// Unquote interprets s as a double-quoted string literal, returning the string -// value that s quotes. -func Unquote(s string) string { - if len(s) < 2 { - panic(fmt.Errorf("invalid length of quoted string; expected >= 2, got %d", len(s))) - } - if !strings.HasPrefix(s, `"`) { - panic(fmt.Errorf("invalid quoted string `%s`; missing quote character prefix", s)) - } - if !strings.HasSuffix(s, `"`) { - panic(fmt.Errorf("invalid quoted string `%s`; missing quote character suffix", s)) - } - // Skip double-quotes. - s = s[1 : len(s)-1] - return Unescape(s) -} - -// Unescape replaces hexadecimal escape sequences (\xx) in s with their -// corresponding characters. -func Unescape(s string) string { - if !strings.ContainsRune(s, '\\') { - return s - } - j := 0 - buf := []byte(s) - for i := 0; i < len(s); i++ { - b := s[i] - if b == '\\' && i+2 < len(s) { - if s[i+1] == '\\' { - b = '\\' - i++ - } else { - x1, ok := unhex(s[i+1]) - if ok { - x2, ok := unhex(s[i+2]) - if ok { - b = x1<<4 | x2 - i += 2 - } - } - } - } - if i != j { - buf[j] = b - } - j++ - } - return string(buf[:j]) -} - -// unhex returns the numeric value represented by the hexadecimal digit b. It -// returns false if b is not a hexadecimal digit. -func unhex(b byte) (v byte, ok bool) { - // This is an adapted copy of the unhex function from the strconv package, - // which is governed by a BSD-style license. - switch { - case '0' <= b && b <= '9': - return b - '0', true - case 'a' <= b && b <= 'f': - return b - 'a' + 10, true - case 'A' <= b && b <= 'F': - return b - 'A' + 10, true - } - return 0, false -} diff --git a/llvm/enc/enc_test.go b/llvm/enc/enc_test.go deleted file mode 100755 index e7a95cd..0000000 --- a/llvm/enc/enc_test.go +++ /dev/null @@ -1,216 +0,0 @@ -package enc_test - -import ( - "testing" - - "github.com/geode-lang/geode/llvm/enc" -) - -func TestGlobal(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "@foo"}, - // i=1 - {s: "a b", want: `@"a\20b"`}, - // i=2 - {s: "$a", want: "@$a"}, - // i=3 - {s: "-a", want: "@-a"}, - // i=4 - {s: ".a", want: "@.a"}, - // i=5 - {s: "_a", want: "@_a"}, - // i=6 - {s: "#a", want: `@"\23a"`}, - // i=7 - {s: "a b#c", want: `@"a\20b\23c"`}, - // i=8 - {s: "2", want: "@2"}, - // i=9 - {s: "foo世bar", want: `@"foo\E4\B8\96bar"`}, - } - - for i, g := range golden { - got := enc.Global(g.s) - if got != g.want { - t.Errorf("i=%d: name mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestLocal(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "%foo"}, - // i=1 - {s: "a b", want: `%"a\20b"`}, - // i=2 - {s: "$a", want: "%$a"}, - // i=3 - {s: "-a", want: "%-a"}, - // i=4 - {s: ".a", want: "%.a"}, - // i=5 - {s: "_a", want: "%_a"}, - // i=6 - {s: "#a", want: `%"\23a"`}, - // i=7 - {s: "a b#c", want: `%"a\20b\23c"`}, - // i=8 - {s: "2", want: "%2"}, - // i=9 - {s: "foo世bar", want: `%"foo\E4\B8\96bar"`}, - } - - for i, g := range golden { - got := enc.Local(g.s) - if got != g.want { - t.Errorf("i=%d: name mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestMetadata(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "!foo"}, - // i=1 - {s: "a b", want: `!a\20b`}, - // i=2 - {s: "$a", want: "!$a"}, - // i=3 - {s: "-a", want: "!-a"}, - // i=4 - {s: ".a", want: "!.a"}, - // i=5 - {s: "_a", want: "!_a"}, - // i=6 - {s: "#a", want: `!\23a`}, - // i=7 - {s: "a b#c", want: `!a\20b\23c`}, - // i=8 - {s: "2", want: "!2"}, - // i=9 - {s: "foo世bar", want: `!foo\E4\B8\96bar`}, - } - - for i, g := range golden { - got := enc.Metadata(g.s) - if got != g.want { - t.Errorf("i=%d: name mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestUnescape(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "foo"}, - // i=1 - {s: `a\20b`, want: "a b"}, - // i=2 - {s: "$a", want: "$a"}, - // i=3 - {s: "-a", want: "-a"}, - // i=4 - {s: ".a", want: ".a"}, - // i=5 - {s: "_a", want: "_a"}, - // i=6 - {s: `\23a`, want: "#a"}, - // i=7 - {s: `a\20b\23c`, want: "a b#c"}, - // i=8 - {s: "2", want: "2"}, - // i=9 - {s: `foo\E4\B8\96bar`, want: "foo世bar"}, - // i=10 - {s: `foo \5C bar`, want: `foo \ bar`}, - // i=11 - {s: `foo \\ bar`, want: `foo \ bar`}, - } - - for i, g := range golden { - got := enc.Unescape(g.s) - if got != g.want { - t.Errorf("i=%d: string mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestEscape(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "foo"}, - // i=1 - {s: "a b", want: `a b`}, - // i=2 - {s: "$a", want: "$a"}, - // i=3 - {s: "-a", want: "-a"}, - // i=4 - {s: ".a", want: ".a"}, - // i=5 - {s: "_a", want: "_a"}, - // i=6 - {s: "#a", want: `#a`}, - // i=7 - {s: "a b#c", want: `a b#c`}, - // i=8 - {s: "2", want: "2"}, - // i=9 - {s: "foo世bar", want: `foo\E4\B8\96bar`}, - // i=10 - {s: `foo \ bar`, want: `foo \5C bar`}, - } - - // isPrint reports whether the given byte is printable. - isPrint := func(b byte) bool { - return ' ' <= b && b <= '~' && b != '"' && b != '\\' - } - for i, g := range golden { - got := enc.Escape(g.s, isPrint) - if got != g.want { - t.Errorf("i=%d: string mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func BenchmarkGlobalNoReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Global("$foo_bar_baz") - } -} - -func BenchmarkGlobalReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Global("$foo bar#baz") - } -} - -func BenchmarkLocalNoReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Local("$foo_bar_baz") - } -} - -func BenchmarkLocalReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Local("$foo bar#baz") - } -} diff --git a/llvm/internal/enc/enc_test.go b/llvm/internal/enc/enc_test.go deleted file mode 100755 index e7a95cd..0000000 --- a/llvm/internal/enc/enc_test.go +++ /dev/null @@ -1,216 +0,0 @@ -package enc_test - -import ( - "testing" - - "github.com/geode-lang/geode/llvm/enc" -) - -func TestGlobal(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "@foo"}, - // i=1 - {s: "a b", want: `@"a\20b"`}, - // i=2 - {s: "$a", want: "@$a"}, - // i=3 - {s: "-a", want: "@-a"}, - // i=4 - {s: ".a", want: "@.a"}, - // i=5 - {s: "_a", want: "@_a"}, - // i=6 - {s: "#a", want: `@"\23a"`}, - // i=7 - {s: "a b#c", want: `@"a\20b\23c"`}, - // i=8 - {s: "2", want: "@2"}, - // i=9 - {s: "foo世bar", want: `@"foo\E4\B8\96bar"`}, - } - - for i, g := range golden { - got := enc.Global(g.s) - if got != g.want { - t.Errorf("i=%d: name mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestLocal(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "%foo"}, - // i=1 - {s: "a b", want: `%"a\20b"`}, - // i=2 - {s: "$a", want: "%$a"}, - // i=3 - {s: "-a", want: "%-a"}, - // i=4 - {s: ".a", want: "%.a"}, - // i=5 - {s: "_a", want: "%_a"}, - // i=6 - {s: "#a", want: `%"\23a"`}, - // i=7 - {s: "a b#c", want: `%"a\20b\23c"`}, - // i=8 - {s: "2", want: "%2"}, - // i=9 - {s: "foo世bar", want: `%"foo\E4\B8\96bar"`}, - } - - for i, g := range golden { - got := enc.Local(g.s) - if got != g.want { - t.Errorf("i=%d: name mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestMetadata(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "!foo"}, - // i=1 - {s: "a b", want: `!a\20b`}, - // i=2 - {s: "$a", want: "!$a"}, - // i=3 - {s: "-a", want: "!-a"}, - // i=4 - {s: ".a", want: "!.a"}, - // i=5 - {s: "_a", want: "!_a"}, - // i=6 - {s: "#a", want: `!\23a`}, - // i=7 - {s: "a b#c", want: `!a\20b\23c`}, - // i=8 - {s: "2", want: "!2"}, - // i=9 - {s: "foo世bar", want: `!foo\E4\B8\96bar`}, - } - - for i, g := range golden { - got := enc.Metadata(g.s) - if got != g.want { - t.Errorf("i=%d: name mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestUnescape(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "foo"}, - // i=1 - {s: `a\20b`, want: "a b"}, - // i=2 - {s: "$a", want: "$a"}, - // i=3 - {s: "-a", want: "-a"}, - // i=4 - {s: ".a", want: ".a"}, - // i=5 - {s: "_a", want: "_a"}, - // i=6 - {s: `\23a`, want: "#a"}, - // i=7 - {s: `a\20b\23c`, want: "a b#c"}, - // i=8 - {s: "2", want: "2"}, - // i=9 - {s: `foo\E4\B8\96bar`, want: "foo世bar"}, - // i=10 - {s: `foo \5C bar`, want: `foo \ bar`}, - // i=11 - {s: `foo \\ bar`, want: `foo \ bar`}, - } - - for i, g := range golden { - got := enc.Unescape(g.s) - if got != g.want { - t.Errorf("i=%d: string mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func TestEscape(t *testing.T) { - golden := []struct { - s string - want string - }{ - // i=0 - {s: "foo", want: "foo"}, - // i=1 - {s: "a b", want: `a b`}, - // i=2 - {s: "$a", want: "$a"}, - // i=3 - {s: "-a", want: "-a"}, - // i=4 - {s: ".a", want: ".a"}, - // i=5 - {s: "_a", want: "_a"}, - // i=6 - {s: "#a", want: `#a`}, - // i=7 - {s: "a b#c", want: `a b#c`}, - // i=8 - {s: "2", want: "2"}, - // i=9 - {s: "foo世bar", want: `foo\E4\B8\96bar`}, - // i=10 - {s: `foo \ bar`, want: `foo \5C bar`}, - } - - // isPrint reports whether the given byte is printable. - isPrint := func(b byte) bool { - return ' ' <= b && b <= '~' && b != '"' && b != '\\' - } - for i, g := range golden { - got := enc.Escape(g.s, isPrint) - if got != g.want { - t.Errorf("i=%d: string mismatch; expected %q, got %q", i, g.want, got) - } - } -} - -func BenchmarkGlobalNoReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Global("$foo_bar_baz") - } -} - -func BenchmarkGlobalReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Global("$foo bar#baz") - } -} - -func BenchmarkLocalNoReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Local("$foo_bar_baz") - } -} - -func BenchmarkLocalReplace(b *testing.B) { - for i := 0; i < b.N; i++ { - enc.Local("$foo bar#baz") - } -} diff --git a/llvm/internal/floats/float128.go b/llvm/internal/floats/float128.go deleted file mode 100755 index cff5985..0000000 --- a/llvm/internal/floats/float128.go +++ /dev/null @@ -1,20 +0,0 @@ -package floats - -// Float128 represents a 128-bit IEEE 754 quadruple-precision floating-point -// value, in binary128 format. -// -// References: -// https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#IEEE_754_quadruple-precision_binary_floating-point_format:_binary128 -type Float128 struct { - // Sign, exponent and fraction. - // - // 1 bit: sign - // 15 bits: exponent - // 112 bits: fraction - a, b uint64 -} - -// Bytes returns the IEEE 754 binary representation of f as a byte slice. -func (f Float128) Bytes() []byte { - panic("not yet implemented") -} diff --git a/llvm/internal/floats/float16.go b/llvm/internal/floats/float16.go deleted file mode 100755 index 8447d10..0000000 --- a/llvm/internal/floats/float16.go +++ /dev/null @@ -1,304 +0,0 @@ -// The implementation of Float16 is heavily inspired by -// https://github.com/h2so5/half which is released into the public domain. - -// Package floats implements encoding and decoding of IEEE 754 floating-point -// values. -package floats - -import ( - "fmt" - "math" -) - -// Float16 represents a 16-bit IEEE 754 half-precision floating-point value, in -// binary16 format. -// -// References: -// https://en.wikipedia.org/wiki/Half-precision_floating-point_format#IEEE_754_half-precision_binary_floating-point_format:_binary16 -type Float16 struct { - // Sign, exponent and fraction. - // - // 1 bit: sign - // 5 bits: exponent - // 10 bits: fraction - a uint16 -} - -// Bits returns the IEEE 754 binary representation of f. -func (f Float16) Bits() uint16 { - return f.a -} - -// Bytes returns the IEEE 754 binary representation of f as a byte slice, -// containing 4 bytes in hexadecimal format. -func (f Float16) Bytes() []byte { - return []byte(f.String()) -} - -// String returns the IEEE 754 binary representation of f as a string, -// containing 4 bytes in hexadecimal format. -func (f Float16) String() string { - return fmt.Sprintf("%04X", f.Bits()) -} - -// Float32 returns the float32 representation of f. -func (f Float16) Float32() float32 { - a := uint32(f.a) - // 1 bit: sign - sign := a >> 15 - // 5 bits: exponent - exp := a >> 10 & 0x1F - // Adjust for exponent bias. - // - // === [ binary16 ] ========================================================= - // - // Exponent bias 15. - // - // +======================+=======================+ - // | Exponent (in binary) | Notes | - // +======================+=======================+ - // | 00000 | zero/subnormal number | - // +----------------------+-----------------------+ - // | 00001 - 11110 | normalized value | - // +----------------------+-----------------------+ - // | 11111 | infinity/NaN | - // +----------------------+-----------------------+ - // - // References: - // https://en.wikipedia.org/wiki/Half-precision_floating-point_format#Exponent_encoding - // - // === [ binary32 ] ========================================================= - // - // Exponent bias 127. - // - // +===================+=======================+ - // | Exponent (in hex) | Notes | - // +===================+=======================+ - // | 00 | zero/subnormal number | - // +-------------------+-----------------------+ - // | 01 - FE | normalized value | - // +-------------------+-----------------------+ - // | FF | infinity/NaN | - // +-------------------+-----------------------+ - // - // References: - // https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Exponent_encoding - exp32 := exp - 15 + 127 - switch { - case exp == 0: - exp32 = 0 - case exp == 0x1F: - exp32 = 0xFF - } - // 10 bits: fraction - frac := a & 0x3FF - // Sign, exponent and fraction of binary32. - // - // 1 bit: sign - // 8 bits: exponent - // 23 bits: fraction - // - // References: - // https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32 - bits := sign<<31 | exp32<<23 | frac<<13 - return math.Float32frombits(bits) -} - -// Float64 returns the float64 representation of f. -func (f Float16) Float64() float64 { - a := uint64(f.a) - // 1 bit: sign - sign := a >> 15 - // 5 bits: exponent - exp := a >> 10 & 0x1F - // Adjust for exponent bias. - // - // === [ binary64 ] ========================================================= - // - // Exponent bias 1023. - // - // +===========================+=======================+ - // | Exponent (in binary) | Notes | - // +===========================+=======================+ - // | 00000000000 | zero/subnormal number | - // +---------------------------+-----------------------+ - // | 00000000001 - 11111111110 | normalized value | - // +---------------------------+-----------------------+ - // | 11111111111 | infinity/NaN | - // +---------------------------+-----------------------+ - // - // References: - // https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Exponent_encoding - exp64 := exp - 15 + 1023 - switch { - case exp == 0: - exp64 = 0 - case exp == 0x1F: - exp64 = 0x7FF - } - // 10 bits: fraction - frac := a & 0x3FF - // Sign, exponent and fraction of binary64. - // - // 1 bit: sign - // 11 bits: exponent - // 52 bits: fraction - // - // References: - // https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64 - bits := sign<<63 | exp64<<52 | frac<<42 - return math.Float64frombits(bits) -} - -// NewFloat16FromFloat32 returns the nearest 16-bit floating-point value for x -// and a bool indicating whether f represents x exactly. -func NewFloat16FromFloat32(x float32) (f Float16, exact bool) { - exact = true - // Sign, exponent and fraction of binary32. - // - // 1 bit: sign - // 8 bits: exponent - // 23 bits: fraction - bits := math.Float32bits(x) - // 1 bit: sign - sign := uint16(bits >> 31) - // 8 bits: exponent - exp := bits >> 23 & 0xFF - // 23 bits: fraction - frac := bits & 0x7FFFFF - - // Sign, exponent and fraction of binary16. - // - // 1 bit: sign - // 5 bits: exponent - // 10 bits: fraction - - // 5 bits: exponent. - // - // Exponent bias 127 (binary32) - // Exponent bias 15 (binary16) - exp16 := int16(exp) - 127 + 15 - // 10 bits: fraction. - // - // Truncate 13 bits of the binary32 fraction. - if frac&0x1FFF != 0 { - exact = false - } - frac16 := uint16(frac >> 13) - switch { - case exp == 0: - exp16 = 0 - case exp == 0xFF: - exp16 = 0x1F - default: - if exp16 < 0x1 { - // set float16 to zero if exp is too low. - exp16 = 0 - frac16 = 0 - exact = false - } else if exp16 > 0x1E { - // set float16 to infinity if exp is too high. - exp16 = 0x1F - frac16 = 0 - exact = false - } - } - a := sign<<15 | uint16(exp16<<10) | frac16 - return NewFloat16FromBits(a), exact -} - -// NewFloat16FromFloat64 returns the nearest 16-bit floating-point value for x -// and a bool indicating whether f represents x exactly. -func NewFloat16FromFloat64(x float64) (f Float16, exact bool) { - exact = true - // Sign, exponent and fraction of binary64. - // - // 1 bit: sign - // 11 bits: exponent - // 52 bits: fraction - bits := math.Float64bits(x) - // 1 bit: sign - sign := uint16(bits >> 63) - // 11 bits: exponent - exp := bits >> 52 & 0x7FF - // 52 bits: fraction - frac := bits & 0xFFFFFFFFFFFFF - - // Sign, exponent and fraction of binary16. - // - // 1 bit: sign - // 5 bits: exponent - // 10 bits: fraction - - // 5 bits: exponent. - // - // Exponent bias 1023 (binary64) - // Exponent bias 15 (binary16) - exp16 := int16(exp) - 1023 + 15 - // 10 bits: fraction. - // - // Truncate 42 bits of the binary64 fraction. - if frac&0x3FFFFFFFFFF != 0 { - exact = false - } - frac16 := uint16(frac >> 42) - switch { - case exp == 0: - exp16 = 0 - case exp == 0x7FF: - exp16 = 0x1F - default: - if exp16 < 0x1 { - // set float16 to zero if exp is too low. - exp16 = 0 - frac16 = 0 - exact = false - } else if exp16 > 0x1E { - // set float16 to infinity if exp is too high. - exp16 = 0x1F - frac16 = 0 - exact = false - } - } - a := sign<<15 | uint16(exp16<<10) | frac16 - return NewFloat16FromBits(a), exact -} - -// NewFloat16FromString returns a new 16-bit floating-point value based on s, -// which contains 4 bytes in hexadecimal format. -func NewFloat16FromString(s string) Float16 { - return NewFloat16FromBytes([]byte(s)) -} - -// NewFloat16FromBytes returns a new 16-bit floating-point value based on b, -// which contains 4 bytes in hexadecimal format. -func NewFloat16FromBytes(b []byte) Float16 { - if len(b) != 4 { - panic(fmt.Errorf("invalid length of float16 hexadecimal representation, expected 4, got %d", len(b))) - } - bits := uint16(unhex(b[0])<<12 | unhex(b[1])<<8 | unhex(b[2])<<4 | unhex(b[3])<<0) - return NewFloat16FromBits(bits) -} - -// NewFloat16FromBits returns a new 16-bit floating-point value based on bits. -func NewFloat16FromBits(bits uint16) Float16 { - return Float16{a: bits} -} - -// ### [ helper functions ] #################################################### - -// unhex returns the numeric value represented by the hexadecimal digit b. It -// panics if b is not a hexadecimal digit. -func unhex(b byte) uint64 { - // This is an adapted copy of the unhex function from the strconv package, - // which is governed by a BSD-style license. - switch { - case '0' <= b && b <= '9': - return uint64(b - '0') - case 'a' <= b && b <= 'f': - return uint64(b - 'a' + 10) - case 'A' <= b && b <= 'F': - return uint64(b - 'A' + 10) - } - panic(fmt.Errorf("invalid byte; expected hexadecimal, got %q", b)) -} diff --git a/llvm/internal/floats/float80.go b/llvm/internal/floats/float80.go deleted file mode 100755 index f98c95d..0000000 --- a/llvm/internal/floats/float80.go +++ /dev/null @@ -1,166 +0,0 @@ -package floats - -import ( - "fmt" - "math" -) - -// Float80 represents an 80-bit IEEE 754 extended precision floating-point -// value, in x86 extended precision format. -// -// References: -// https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format -type Float80 struct { - // Sign and exponent. - // - // 1 bit: sign - // 15 bits: exponent - se uint16 - // Integer part and fraction. - // - // 1 bit: integer part - // 63 bits: fraction - m uint64 -} - -// Bits returns the IEEE 754 binary representation of f, with the sign and -// exponent in se and the mantissa in m. -func (f Float80) Bits() (se uint16, m uint64) { - return f.se, f.m -} - -// Bytes returns the x86 extended precision binary representation of f as a byte -// slice. -func (f Float80) Bytes() []byte { - return []byte(f.String()) -} - -// String returns the IEEE 754 binary representation of f as a string, -// containing 10 bytes in hexadecimal format. -func (f Float80) String() string { - return fmt.Sprintf("%04X%016X", f.se, f.m) -} - -// Float64 returns the float64 representation of f. -func (f Float80) Float64() float64 { - se := uint64(f.se) - m := f.m - // 1 bit: sign - sign := se >> 15 - // 15 bits: exponent - exp := se & 0x7FFF - // Adjust for exponent bias. - // - // === [ binary64 ] ========================================================= - // - // Exponent bias 1023. - // - // +===========================+=======================+ - // | Exponent (in binary) | Notes | - // +===========================+=======================+ - // | 00000000000 | zero/subnormal number | - // +---------------------------+-----------------------+ - // | 00000000001 - 11111111110 | normalized value | - // +---------------------------+-----------------------+ - // | 11111111111 | infinity/NaN | - // +---------------------------+-----------------------+ - // - // References: - // https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Exponent_encoding - exp64 := int64(exp) - 16383 + 1023 - switch { - case exp == 0: - // exponent is all zeroes. - exp64 = 0 - case exp == 0x7FFF: - // exponent is all ones. - exp64 = 0x7FF - default: - } - // 63 bits: fraction - frac := m & 0x7FFFFFFFFFFFFFFF - // Sign, exponent and fraction of binary64. - // - // 1 bit: sign - // 11 bits: exponent - // 52 bits: fraction - // - // References: - // https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64 - bits := sign<<63 | uint64(exp64)<<52 | frac>>11 - return math.Float64frombits(bits) -} - -// NewFloat80FromFloat64 returns the nearest 80-bit floating-point value for x. -func NewFloat80FromFloat64(x float64) Float80 { - // Sign, exponent and fraction of binary64. - // - // 1 bit: sign - // 11 bits: exponent - // 52 bits: fraction - bits := math.Float64bits(x) - // 1 bit: sign - sign := uint16(bits >> 63) - // 11 bits: exponent - exp := bits >> 52 & 0x7FF - // 52 bits: fraction - frac := bits & 0xFFFFFFFFFFFFF - - if exp == 0 && frac == 0 { - // zero value. - return Float80{} - } - - // Sign, exponent and fraction of binary80. - // - // 1 bit: sign - // 15 bits: exponent - // 1 bit: integer part - // 63 bits: fraction - - // 15 bits: exponent. - // - // Exponent bias 1023 (binary64) - // Exponent bias 16383 (binary80) - exp80 := int64(exp) - 1023 + 16383 - // 63 bits: fraction. - // - frac80 := frac << 11 - switch { - case exp == 0: - exp80 = 0 - case exp == 0x7FF: - exp80 = 0x7FFF - } - se := sign<<15 | uint16(exp80) - // Integer part set to specify normalized value. - m := 0x8000000000000000 | frac80 - return NewFloat80FromBits(se, m) -} - -// NewFloat80FromString returns a new 80-bit floating-point value based on s, -// which contains 20 bytes in hexadecimal format. -func NewFloat80FromString(s string) Float80 { - return NewFloat80FromBytes([]byte(s)) -} - -// NewFloat80FromBytes returns a new 80-bit floating-point value based on b, -// which contains 20 bytes in hexadecimal format. -func NewFloat80FromBytes(b []byte) Float80 { - var f Float80 - if len(b) != 20 { - panic(fmt.Errorf("invalid length of float80 hexadecimal representation, expected 20, got %d", len(b))) - } - f.se = uint16(unhex(b[0])<<12 | unhex(b[1])<<8 | unhex(b[2])<<4 | unhex(b[3])<<0) - f.m = uint64(unhex(b[4])<<60 | unhex(b[5])<<56 | unhex(b[6])<<52 | unhex(b[7])<<48 | unhex(b[8])<<44 | unhex(b[9])<<40 | unhex(b[10])<<36 | unhex(b[11])<<32 | unhex(b[12])<<28 | unhex(b[13])<<24 | unhex(b[14])<<20 | unhex(b[15])<<16 | unhex(b[16])<<12 | unhex(b[17])<<8 | unhex(b[18])<<4 | unhex(b[19])<<0) - return f -} - -// NewFloat80FromBits returns a new 80-bit floating-point value based on the -// sign, exponent and mantissa bits. -func NewFloat80FromBits(se uint16, m uint64) Float80 { - return Float80{ - se: se, - m: m, - } -} diff --git a/llvm/internal/floats/floats_test.go b/llvm/internal/floats/floats_test.go deleted file mode 100755 index 7fece7c..0000000 --- a/llvm/internal/floats/floats_test.go +++ /dev/null @@ -1,201 +0,0 @@ -package floats - -import ( - "math" - "testing" -) - -// === [ float16 ] ============================================================= - -func TestFloat16Float32(t *testing.T) { - golden := []struct { - in string - want float32 - }{ - {in: "3C00", want: 1}, - {in: "4000", want: 2}, - {in: "C000", want: -2}, - {in: "7BFE", want: 65472}, - {in: "7BFF", want: 65504}, - {in: "FBFF", want: -65504}, - {in: "0000", want: 0}, - {in: "8000", want: float32(math.Copysign(0, -1))}, - {in: "7C00", want: float32(math.Inf(1))}, - {in: "FC00", want: float32(math.Inf(-1))}, - {in: "5B8F", want: 241.875}, - {in: "48C8", want: 9.5625}, - } - for _, g := range golden { - f := NewFloat16FromString(g.in) - got := f.Float32() - if got != g.want { - t.Errorf("float32 mismatch for binary16 0x%s; expected %v, got %v", g.in, g.want, got) - continue - } - } -} - -func TestFloat16Float64(t *testing.T) { - golden := []struct { - in uint16 - want float64 - }{ - {in: 0x3C00, want: 1}, - {in: 0x4000, want: 2}, - {in: 0xC000, want: -2}, - {in: 0x7BFE, want: 65472}, - {in: 0x7BFF, want: 65504}, - {in: 0xFBFF, want: -65504}, - {in: 0x0000, want: 0}, - {in: 0x8000, want: math.Copysign(0, -1)}, - {in: 0x7C00, want: math.Inf(1)}, - {in: 0xFC00, want: math.Inf(-1)}, - {in: 0x5B8F, want: 241.875}, - {in: 0x48C8, want: 9.5625}, - } - for _, g := range golden { - f := NewFloat16FromBits(g.in) - got := f.Float64() - if got != g.want { - t.Errorf("float64 mismatch for binary16 0x%04X; expected %v, got %v", g.in, g.want, got) - continue - } - } -} - -func TestNewFloat16FromFloat32(t *testing.T) { - golden := []struct { - want uint16 - in float32 - }{ - {want: 0x3C00, in: 1}, - {want: 0x4000, in: 2}, - {want: 0xC000, in: -2}, - {want: 0x7BFE, in: 65472}, - {want: 0x7BFF, in: 65504}, - {want: 0xFBFF, in: -65504}, - {want: 0x0000, in: 0}, - {want: 0x8000, in: float32(math.Copysign(0, -1))}, - {want: 0x7C00, in: float32(math.Inf(1))}, - {want: 0xFC00, in: float32(math.Inf(-1))}, - {want: 0x5B8F, in: 241.875}, - {want: 0x48C8, in: 9.5625}, - } - for _, g := range golden { - f, exact := NewFloat16FromFloat32(g.in) - if !exact { - t.Errorf("unable to represent %v exactly using binary16 format", g.in) - continue - } - got := f.Bits() - if got != g.want { - t.Errorf("binary16 mismatch for float32 %v; expected 0x%04X, got 0x%04X", g.in, g.want, got) - continue - } - } -} - -func TestNewFloat16FromFloat64(t *testing.T) { - golden := []struct { - want uint16 - in float64 - }{ - {want: 0x3C00, in: 1}, - {want: 0x4000, in: 2}, - {want: 0xC000, in: -2}, - {want: 0x7BFE, in: 65472}, - {want: 0x7BFF, in: 65504}, - {want: 0xFBFF, in: -65504}, - {want: 0x0000, in: 0}, - {want: 0x8000, in: math.Copysign(0, -1)}, - {want: 0x7C00, in: math.Inf(1)}, - {want: 0xFC00, in: math.Inf(-1)}, - {want: 0x5B8F, in: 241.875}, - {want: 0x48C8, in: 9.5625}, - } - for _, g := range golden { - f, exact := NewFloat16FromFloat64(g.in) - if !exact { - t.Errorf("unable to represent %v exactly using binary16 format", g.in) - continue - } - got := f.Bits() - if got != g.want { - t.Errorf("binary16 mismatch for float64 %v; expected 0x%04X, got 0x%04X", g.in, g.want, got) - continue - } - } -} - -// === [ float80 ] ============================================================= - -func TestFloat80Float64(t *testing.T) { - golden := []struct { - in string - want float64 - }{ - {in: "00000000000000000000", want: 0.0}, // +0 - {in: "80000000000000000000", want: -0.0}, // -0 - {in: "3FFF8000000000000000", want: 1.0}, // 1 - {in: "40008000000000000000", want: 2.0}, // 2 - {in: "4000C000000000000000", want: 3.0}, // 3 - {in: "3FFC8000000000000000", want: 0.125}, // 0.125 - //{in: "7FFEFFFFFFFFFFFFFFFF", want: 1.18973149535723176505e+4932}, // max normal - //{in: "00018000000000000000", want: 3.36210314311209350626e-4932}, // min positive normal - //{in: "00007FFFFFFFFFFFFFFF", want: 3.36210314311209350608e-4932}, // max subnormal - //{in: "00000000000000000001", want: 3.64519953188247460253e-4951}, // min positive subnormal - {in: "7FFF8000000000000000", want: math.Inf(1)}, // +inf - {in: "FFFF8000000000000000", want: math.Inf(-1)}, // -inf - //{in: "7FFFFFFFFFFFFFFFFFFF", want: math.NaN()}, // QNaN - quiet NaN with greatest fraction - //{in: "7FFFC000000000000000", want: math.NaN()}, // QNaN - quiet NaN with least fraction - //{in: "7FFFBFFFFFFFFFFFFFFF", want: math.NaN()}, // SNaN - signaling NaN with greatest fraction - //{in: "7FFF8000000000000001", want: math.NaN()}, // SNaN - signaling NaN with least fraction - } - for _, g := range golden { - f := NewFloat80FromString(g.in) - got := f.Float64() - if got != g.want { - t.Errorf("float64 mismatch for binary80 0x%s; expected %v, got %v", g.in, g.want, got) - continue - } - } -} - -func TestNewFloat80FromFloat64(t *testing.T) { - golden := []struct { - // want - se uint16 - m uint64 - // in - in float64 - }{ - {se: 0x0000, m: 0x0000000000000000, in: 0.0}, // +0 - //{se: 0x8000, m: 0x0000000000000000, in: -0.0}, // -0 - {se: 0x3FFF, m: 0x8000000000000000, in: 1.0}, // 1 - {se: 0x4000, m: 0x8000000000000000, in: 2.0}, // 2 - {se: 0x4000, m: 0xC000000000000000, in: 3.0}, // 3 - {se: 0x3FFC, m: 0x8000000000000000, in: 0.125}, // 0.125 - //{se: 0x7FFE, m: 0xFFFFFFFFFFFFFFFF, in: 1.18973149535723176505e+4932}, // max normal - //{se: 0x0001, m: 0x8000000000000000, in: 3.36210314311209350626e-4932}, // min positive normal - //{se: 0x0000, m: 0x7FFFFFFFFFFFFFFF, in: 3.36210314311209350608e-4932}, // max subnormal - //{se: 0x0000, m: 0x0000000000000001, in: 3.64519953188247460253e-4951}, // min positive subnormal - {se: 0x7FFF, m: 0x8000000000000000, in: math.Inf(1)}, // +inf - {se: 0xFFFF, m: 0x8000000000000000, in: math.Inf(-1)}, // -inf - //{se: 0x7FFF, m: 0xFFFFFFFFFFFFFFFF, in: math.NaN()}, // QNaN - quiet NaN with greatest fraction - //{se: 0x7FFF, m: 0xC000000000000000, in: math.NaN()}, // QNaN - quiet NaN with least fraction - //{se: 0x7FFF, m: 0xBFFFFFFFFFFFFFFF, in: math.NaN()}, // SNaN - signaling NaN with greatest fraction - //{se: 0x7FFF, m: 0x8000000000000001, in: math.NaN()}, // SNaN - signaling NaN with least fraction - } - for _, g := range golden { - f := NewFloat80FromFloat64(g.in) - se, m := f.Bits() - if se != g.se { - t.Errorf("binary80 se mismatch for float64 %v; expected 0x%04X, got 0x%04X", g.in, g.se, se) - continue - } - if m != g.m { - t.Errorf("binary80 m mismatch for float64 %v; expected 0x%016X, got 0x%016X", g.in, g.m, m) - continue - } - } -} diff --git a/llvm/ir/asm_test.go b/llvm/ir/asm_test.go deleted file mode 100755 index 1e20a43..0000000 --- a/llvm/ir/asm_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package ir_test - -import ( - "fmt" - "io/ioutil" - "testing" - - "github.com/geode-lang/geode/llvm/asm" - "github.com/sergi/go-diff/diffmatchpatch" -) - -func TestRoundTrip(t *testing.T) { - // Round-trip test of the parser. - golden := []struct { - path string - }{ - // Empty module. - {path: "../asm/testdata/empty.ll"}, - // Top-level declarations. - {path: "../asm/testdata/module.ll"}, - {path: "../asm/testdata/global.ll"}, - {path: "../asm/testdata/func.ll"}, - {path: "../asm/testdata/metadata.ll"}, - // Types. - {path: "../asm/testdata/type.ll"}, - // Constants. - {path: "../asm/testdata/const.ll"}, - // Constant expressions. - {path: "../asm/testdata/expr_binary.ll"}, - {path: "../asm/testdata/expr_bitwise.ll"}, - {path: "../asm/testdata/expr_vector.ll"}, - {path: "../asm/testdata/expr_aggregate.ll"}, - {path: "../asm/testdata/expr_memory.ll"}, - {path: "../asm/testdata/expr_conversion.ll"}, - {path: "../asm/testdata/expr_other.ll"}, - // Instructions. - {path: "../asm/testdata/inst_binary.ll"}, - {path: "../asm/testdata/inst_bitwise.ll"}, - {path: "../asm/testdata/inst_vector.ll"}, - {path: "../asm/testdata/inst_aggregate.ll"}, - {path: "../asm/testdata/inst_memory.ll"}, - {path: "../asm/testdata/inst_conversion.ll"}, - {path: "../asm/testdata/inst_other.ll"}, - // Terminators. - {path: "../asm/testdata/term.ll"}, - // Pseudo-random number generator. - {path: "../asm/testdata/rand.ll"}, - } - dmp := diffmatchpatch.New() - for _, g := range golden { - buf, err := ioutil.ReadFile(g.path) - if err != nil { - t.Errorf("%q: unable to read file; %v", g.path, err) - continue - } - input := string(buf) - m, err := asm.ParseString(input) - if err != nil { - t.Errorf("%q: unable to parse file; %v", g.path, err) - continue - } - want := input - // Read foo.ll.golden if present. - if buf, err := ioutil.ReadFile(g.path + ".golden"); err == nil { - want = string(buf) - } - got := m.String() - if want != got { - diffs := dmp.DiffMain(want, got, false) - fmt.Println(dmp.DiffPrettyText(diffs)) - t.Errorf("%q: module mismatch; expected `%v`, got `%v`", g.path, want, got) - continue - } - } -} diff --git a/llvm/ir/block.go b/llvm/ir/block.go deleted file mode 100755 index 033ecb9..0000000 --- a/llvm/ir/block.go +++ /dev/null @@ -1,523 +0,0 @@ -// === [ Basic blocks ] ======================================================== - -package ir - -import ( - "bytes" - "fmt" - - "github.com/geode-lang/geode/llvm/enc" - "github.com/geode-lang/geode/llvm/ir/types" - "github.com/geode-lang/geode/llvm/ir/value" -) - -// A BasicBlock represents an LLVM IR basic block, which consists of a sequence -// of non-branching instructions, terminated by a control flow instruction (e.g. -// br or ret). -// -// Basic blocks may be referenced from terminators (e.g. br), and are thus -// considered LLVM IR values of label type. -type BasicBlock struct { - // Parent function of the basic block. - Parent *Function - // Label name of the basic block; or empty if unnamed basic block. - Name string - // Non-branching instructions of the basic block. - Insts []Instruction - // Terminator of the basic block. - Term Terminator -} - -// NewBlock returns a new basic block based on the given label name. An empty -// label name indicates an unnamed basic block. -func NewBlock(name string) *BasicBlock { - return &BasicBlock{ - Name: name, - } -} - -// Type returns the type of the basic block. -func (block *BasicBlock) Type() types.Type { - return types.Label -} - -// Ident returns the identifier associated with the basic block. -func (block *BasicBlock) Ident() string { - return enc.Local(block.Name) -} - -// GetName returns the label name of the basic block. -func (block *BasicBlock) GetName() string { - return block.Name -} - -// SetName sets the label name of the basic block. -func (block *BasicBlock) SetName(name string) { - block.Name = name -} - -// String returns the LLVM syntax representation of the basic block. -func (block *BasicBlock) String() string { - buf := &bytes.Buffer{} - if isLocalID(block.Name) { - fmt.Fprintf(buf, ";