2015-04-15 15:51:25 -07:00
|
|
|
// Copyright 2015 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package ssa
|
|
|
|
|
|
|
|
|
|
import "log"
|
|
|
|
|
|
|
|
|
|
type Config struct {
|
2015-05-27 14:52:22 -07:00
|
|
|
arch string // "amd64", etc.
|
|
|
|
|
ptrSize int64 // 4 or 8
|
|
|
|
|
Uintptr Type // pointer arithmetic type
|
|
|
|
|
lowerBlock func(*Block) bool // lowering function
|
|
|
|
|
lowerValue func(*Value, *Config) bool // lowering function
|
|
|
|
|
fe Frontend // callbacks into compiler frontend
|
2015-04-15 15:51:25 -07:00
|
|
|
|
|
|
|
|
// TODO: more stuff. Compiler flags of interest, ...
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-27 14:52:22 -07:00
|
|
|
type Frontend interface {
|
|
|
|
|
// StringSym returns a symbol pointing to the given string.
|
|
|
|
|
// Strings are laid out in read-only memory with one word of pointer,
|
|
|
|
|
// one word of length, then the contents of the string.
|
|
|
|
|
StringSym(string) interface{} // returns *gc.Sym
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-15 15:51:25 -07:00
|
|
|
// NewConfig returns a new configuration object for the given architecture.
|
2015-05-27 14:52:22 -07:00
|
|
|
func NewConfig(arch string, fe Frontend) *Config {
|
|
|
|
|
c := &Config{arch: arch, fe: fe}
|
2015-04-15 15:51:25 -07:00
|
|
|
switch arch {
|
|
|
|
|
case "amd64":
|
|
|
|
|
c.ptrSize = 8
|
2015-06-06 16:03:33 -07:00
|
|
|
c.lowerBlock = rewriteBlockAMD64
|
|
|
|
|
c.lowerValue = rewriteValueAMD64
|
2015-04-15 15:51:25 -07:00
|
|
|
case "386":
|
|
|
|
|
c.ptrSize = 4
|
2015-06-06 16:03:33 -07:00
|
|
|
c.lowerBlock = rewriteBlockAMD64
|
|
|
|
|
c.lowerValue = rewriteValueAMD64 // TODO(khr): full 32-bit support
|
2015-04-15 15:51:25 -07:00
|
|
|
default:
|
|
|
|
|
log.Fatalf("arch %s not implemented", arch)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cache the intptr type in the config
|
2015-05-18 16:44:20 -07:00
|
|
|
c.Uintptr = TypeUInt32
|
2015-04-15 15:51:25 -07:00
|
|
|
if c.ptrSize == 8 {
|
2015-05-18 16:44:20 -07:00
|
|
|
c.Uintptr = TypeUInt64
|
2015-04-15 15:51:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewFunc returns a new, empty function object
|
|
|
|
|
func (c *Config) NewFunc() *Func {
|
|
|
|
|
// TODO(khr): should this function take name, type, etc. as arguments?
|
|
|
|
|
return &Func{Config: c}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(khr): do we really need a separate Config, or can we just
|
|
|
|
|
// store all its fields inside a Func?
|