mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
For integer types less than a machine register, we have to decide what the invariants are for the high bits of the register. We used to set the high bits to the correct extension (sign or zero, as determined by the type) of the low bits. This CL makes the compiler ignore the high bits of the register altogether (they are junk). On this plus side, this means ops that generate subword results don't have to worry about correctly extending them. On the minus side, ops that consume subword arguments have to deal with the input registers not being correctly extended. For x86, this tradeoff is probably worth it. Almost all opcodes have versions that use only the correct subword piece of their inputs. (The one big exception is array indexing.) Not many opcodes can correctly sign extend on output. For other architectures, the tradeoff is probably not so clear, as they don't have many subword-safe opcodes (e.g. 16-bit compare, ignoring the high 16/48 bits). Fortunately we can decide whether we do this per-architecture. For the machine-independent opcodes, we pretend that the "register" size is equal to the type width, so sign extension is immaterial. Opcodes that care about the signedness of the input (e.g. compare, right shift) have two different variants. Change-Id: I465484c5734545ee697afe83bc8bf4b53bd9df8d Reviewed-on: https://go-review.googlesource.com/12600 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
// 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
|
|
|
|
type Config struct {
|
|
arch string // "amd64", etc.
|
|
IntSize int64 // 4 or 8
|
|
PtrSize int64 // 4 or 8
|
|
Uintptr Type // pointer arithmetic type
|
|
Int Type
|
|
lowerBlock func(*Block) bool // lowering function
|
|
lowerValue func(*Value, *Config) bool // lowering function
|
|
fe Frontend // callbacks into compiler frontend
|
|
|
|
// TODO: more stuff. Compiler flags of interest, ...
|
|
}
|
|
|
|
type Frontend interface {
|
|
// StringData returns a symbol pointing to the given string's contents.
|
|
StringData(string) interface{} // returns *gc.Sym
|
|
|
|
// Log logs a message from the compiler.
|
|
Logf(string, ...interface{})
|
|
|
|
// Fatal reports a compiler error and exits.
|
|
Fatalf(string, ...interface{})
|
|
|
|
// Unimplemented reports that the function cannot be compiled.
|
|
// It will be removed once SSA work is complete.
|
|
Unimplementedf(msg string, args ...interface{})
|
|
}
|
|
|
|
// NewConfig returns a new configuration object for the given architecture.
|
|
func NewConfig(arch string, fe Frontend) *Config {
|
|
c := &Config{arch: arch, fe: fe}
|
|
switch arch {
|
|
case "amd64":
|
|
c.IntSize = 8
|
|
c.PtrSize = 8
|
|
c.lowerBlock = rewriteBlockAMD64
|
|
c.lowerValue = rewriteValueAMD64
|
|
case "386":
|
|
c.IntSize = 4
|
|
c.PtrSize = 4
|
|
c.lowerBlock = rewriteBlockAMD64
|
|
c.lowerValue = rewriteValueAMD64 // TODO(khr): full 32-bit support
|
|
default:
|
|
fe.Unimplementedf("arch %s not implemented", arch)
|
|
}
|
|
|
|
// cache the frequently-used types in the config
|
|
c.Uintptr = TypeUInt32
|
|
c.Int = TypeInt32
|
|
if c.PtrSize == 8 {
|
|
c.Uintptr = TypeUInt64
|
|
}
|
|
if c.IntSize == 8 {
|
|
c.Int = TypeInt64
|
|
}
|
|
|
|
return c
|
|
}
|
|
|
|
func (c *Config) Frontend() Frontend { return c.fe }
|
|
|
|
// 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}
|
|
}
|
|
|
|
func (c *Config) Logf(msg string, args ...interface{}) { c.fe.Logf(msg, args...) }
|
|
func (c *Config) Fatalf(msg string, args ...interface{}) { c.fe.Fatalf(msg, args...) }
|
|
func (c *Config) Unimplementedf(msg string, args ...interface{}) { c.fe.Unimplementedf(msg, args...) }
|
|
|
|
// TODO(khr): do we really need a separate Config, or can we just
|
|
// store all its fields inside a Func?
|