aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/op.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/ssa/op.go')
-rw-r--r--src/cmd/compile/internal/ssa/op.go118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
new file mode 100644
index 0000000000..7b2a8f8f04
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -0,0 +1,118 @@
+// 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 "fmt"
+
+// An Op encodes the specific operation that a Value performs.
+// Opcodes' semantics can be modified by the type and aux fields of the Value.
+// For instance, OpAdd can be 32 or 64 bit, signed or unsigned, float or complex, depending on Value.Type.
+// Semantics of each op are described in the opcode files in gen/*Ops.go.
+// There is one file for generic (architecture-independent) ops and one file
+// for each architecture.
+type Op int32
+
+type opInfo struct {
+ name string
+ asm int
+ reg regInfo
+ auxType auxType
+ argLen int32 // the number of arugments, -1 if variable length
+ generic bool // this is a generic (arch-independent) opcode
+ rematerializeable bool // this op is rematerializeable
+ commutative bool // this operation is commutative (e.g. addition)
+}
+
+type inputInfo struct {
+ idx int // index in Args array
+ regs regMask // allowed input registers
+}
+
+type regInfo struct {
+ inputs []inputInfo // ordered in register allocation order
+ clobbers regMask
+ outputs []regMask // NOTE: values can only have 1 output for now.
+}
+
+type auxType int8
+
+const (
+ auxNone auxType = iota
+ auxBool // auxInt is 0/1 for false/true
+ auxInt8 // auxInt is an 8-bit integer
+ auxInt16 // auxInt is a 16-bit integer
+ auxInt32 // auxInt is a 32-bit integer
+ auxInt64 // auxInt is a 64-bit integer
+ auxFloat // auxInt is a float64 (encoded with math.Float64bits)
+ auxString // auxInt is a string
+ auxSym // aux is a symbol
+ auxSymOff // aux is a symbol, auxInt is an offset
+ auxSymValAndOff // aux is a symbol, auxInt is a ValAndOff
+)
+
+// A ValAndOff is used by the several opcodes. It holds
+// both a value and a pointer offset.
+// A ValAndOff is intended to be encoded into an AuxInt field.
+// The zero ValAndOff encodes a value of 0 and an offset of 0.
+// The high 32 bits hold a value.
+// The low 32 bits hold a pointer offset.
+type ValAndOff int64
+
+func (x ValAndOff) Val() int64 {
+ return int64(x) >> 32
+}
+func (x ValAndOff) Off() int64 {
+ return int64(int32(x))
+}
+func (x ValAndOff) Int64() int64 {
+ return int64(x)
+}
+func (x ValAndOff) String() string {
+ return fmt.Sprintf("val=%d,off=%d", x.Val(), x.Off())
+}
+
+// validVal reports whether the value can be used
+// as an argument to makeValAndOff.
+func validVal(val int64) bool {
+ return val == int64(int32(val))
+}
+
+// validOff reports whether the offset can be used
+// as an argument to makeValAndOff.
+func validOff(off int64) bool {
+ return off == int64(int32(off))
+}
+
+// validValAndOff reports whether we can fit the value and offset into
+// a ValAndOff value.
+func validValAndOff(val, off int64) bool {
+ if !validVal(val) {
+ return false
+ }
+ if !validOff(off) {
+ return false
+ }
+ return true
+}
+
+// makeValAndOff encodes a ValAndOff into an int64 suitable for storing in an AuxInt field.
+func makeValAndOff(val, off int64) int64 {
+ if !validValAndOff(val, off) {
+ panic("invalid makeValAndOff")
+ }
+ return ValAndOff(val<<32 + int64(uint32(off))).Int64()
+}
+
+func (x ValAndOff) canAdd(off int64) bool {
+ newoff := x.Off() + off
+ return newoff == int64(int32(newoff))
+}
+
+func (x ValAndOff) add(off int64) int64 {
+ if !x.canAdd(off) {
+ panic("invalid ValAndOff.add")
+ }
+ return makeValAndOff(x.Val(), x.Off()+off)
+}