1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package ssa
6
7import (
8	"cmd/compile/internal/types"
9	"fmt"
10)
11
12// A place that an ssa variable can reside.
13type Location interface {
14	String() string // name to use in assembly templates: AX, 16(SP), ...
15}
16
17// A Register is a machine register, like AX.
18// They are numbered densely from 0 (for each architecture).
19type Register struct {
20	num    int32 // dense numbering
21	objNum int16 // register number from cmd/internal/obj/$ARCH
22	gcNum  int16 // GC register map number (dense numbering of registers that can contain pointers)
23	name   string
24}
25
26func (r *Register) String() string {
27	return r.name
28}
29
30// ObjNum returns the register number from cmd/internal/obj/$ARCH that
31// corresponds to this register.
32func (r *Register) ObjNum() int16 {
33	return r.objNum
34}
35
36// GCNum returns the runtime GC register index of r, or -1 if this
37// register can't contain pointers.
38func (r *Register) GCNum() int16 {
39	return r.gcNum
40}
41
42// A LocalSlot is a location in the stack frame, which identifies and stores
43// part or all of a PPARAM, PPARAMOUT, or PAUTO ONAME node.
44// It can represent a whole variable, part of a larger stack slot, or part of a
45// variable that has been decomposed into multiple stack slots.
46// As an example, a string could have the following configurations:
47//
48//           stack layout              LocalSlots
49//
50// Optimizations are disabled. s is on the stack and represented in its entirety.
51// [ ------- s string ---- ] { N: s, Type: string, Off: 0 }
52//
53// s was not decomposed, but the SSA operates on its parts individually, so
54// there is a LocalSlot for each of its fields that points into the single stack slot.
55// [ ------- s string ---- ] { N: s, Type: *uint8, Off: 0 }, {N: s, Type: int, Off: 8}
56//
57// s was decomposed. Each of its fields is in its own stack slot and has its own LocalSLot.
58// [ ptr *uint8 ] [ len int] { N: ptr, Type: *uint8, Off: 0, SplitOf: parent, SplitOffset: 0},
59//                           { N: len, Type: int, Off: 0, SplitOf: parent, SplitOffset: 8}
60//                           parent = &{N: s, Type: string}
61type LocalSlot struct {
62	N    GCNode      // an ONAME *gc.Node representing a stack location.
63	Type *types.Type // type of slot
64	Off  int64       // offset of slot in N
65
66	SplitOf     *LocalSlot // slot is a decomposition of SplitOf
67	SplitOffset int64      // .. at this offset.
68}
69
70func (s LocalSlot) String() string {
71	if s.Off == 0 {
72		return fmt.Sprintf("%v[%v]", s.N, s.Type)
73	}
74	return fmt.Sprintf("%v+%d[%v]", s.N, s.Off, s.Type)
75}
76
77type LocPair [2]Location
78
79func (t LocPair) String() string {
80	n0, n1 := "nil", "nil"
81	if t[0] != nil {
82		n0 = t[0].String()
83	}
84	if t[1] != nil {
85		n1 = t[1].String()
86	}
87	return fmt.Sprintf("<%s,%s>", n0, n1)
88}
89