Source file src/cmd/internal/sys/arch.go

     1  // Copyright 2016 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  
     5  package sys
     6  
     7  import "encoding/binary"
     8  
     9  // ArchFamily represents a family of one or more related architectures.
    10  // For example, ppc64 and ppc64le are both members of the PPC64 family.
    11  type ArchFamily byte
    12  
    13  const (
    14  	NoArch ArchFamily = iota
    15  	AMD64
    16  	ARM
    17  	ARM64
    18  	I386
    19  	Loong64
    20  	MIPS
    21  	MIPS64
    22  	PPC64
    23  	RISCV64
    24  	S390X
    25  	Wasm
    26  )
    27  
    28  // Arch represents an individual architecture.
    29  type Arch struct {
    30  	Name   string
    31  	Family ArchFamily
    32  
    33  	ByteOrder binary.ByteOrder
    34  
    35  	// PtrSize is the size in bytes of pointers and the
    36  	// predeclared "int", "uint", and "uintptr" types.
    37  	PtrSize int
    38  
    39  	// RegSize is the size in bytes of general purpose registers.
    40  	RegSize int
    41  
    42  	// MinLC is the minimum length of an instruction code.
    43  	MinLC int
    44  
    45  	// Alignment is maximum alignment required by the architecture
    46  	// for any (compiler-generated) load or store instruction.
    47  	// Loads or stores smaller than Alignment must be naturally aligned.
    48  	// Loads or stores larger than Alignment need only be Alignment-aligned.
    49  	Alignment int8
    50  
    51  	// CanMergeLoads reports whether the backend optimization passes
    52  	// can combine adjacent loads into a single larger, possibly unaligned, load.
    53  	// Note that currently the optimizations must be able to handle little endian byte order.
    54  	CanMergeLoads bool
    55  
    56  	// CanJumpTable reports whether the backend can handle
    57  	// compiling a jump table.
    58  	CanJumpTable bool
    59  
    60  	// HasLR indicates that this architecture uses a link register
    61  	// for calls.
    62  	HasLR bool
    63  
    64  	// FixedFrameSize is the smallest possible offset from the
    65  	// hardware stack pointer to a local variable on the stack.
    66  	// Architectures that use a link register save its value on
    67  	// the stack in the function prologue and so always have a
    68  	// pointer between the hardware stack pointer and the local
    69  	// variable area.
    70  	FixedFrameSize int64
    71  }
    72  
    73  // InFamily reports whether a is a member of any of the specified
    74  // architecture families.
    75  func (a *Arch) InFamily(xs ...ArchFamily) bool {
    76  	for _, x := range xs {
    77  		if a.Family == x {
    78  			return true
    79  		}
    80  	}
    81  	return false
    82  }
    83  
    84  var Arch386 = &Arch{
    85  	Name:           "386",
    86  	Family:         I386,
    87  	ByteOrder:      binary.LittleEndian,
    88  	PtrSize:        4,
    89  	RegSize:        4,
    90  	MinLC:          1,
    91  	Alignment:      1,
    92  	CanMergeLoads:  true,
    93  	HasLR:          false,
    94  	FixedFrameSize: 0,
    95  }
    96  
    97  var ArchAMD64 = &Arch{
    98  	Name:           "amd64",
    99  	Family:         AMD64,
   100  	ByteOrder:      binary.LittleEndian,
   101  	PtrSize:        8,
   102  	RegSize:        8,
   103  	MinLC:          1,
   104  	Alignment:      1,
   105  	CanMergeLoads:  true,
   106  	CanJumpTable:   true,
   107  	HasLR:          false,
   108  	FixedFrameSize: 0,
   109  }
   110  
   111  var ArchARM = &Arch{
   112  	Name:           "arm",
   113  	Family:         ARM,
   114  	ByteOrder:      binary.LittleEndian,
   115  	PtrSize:        4,
   116  	RegSize:        4,
   117  	MinLC:          4,
   118  	Alignment:      4, // TODO: just for arm5?
   119  	CanMergeLoads:  false,
   120  	HasLR:          true,
   121  	FixedFrameSize: 4, // LR
   122  }
   123  
   124  var ArchARM64 = &Arch{
   125  	Name:           "arm64",
   126  	Family:         ARM64,
   127  	ByteOrder:      binary.LittleEndian,
   128  	PtrSize:        8,
   129  	RegSize:        8,
   130  	MinLC:          4,
   131  	Alignment:      1,
   132  	CanMergeLoads:  true,
   133  	CanJumpTable:   true,
   134  	HasLR:          true,
   135  	FixedFrameSize: 8, // LR
   136  }
   137  
   138  var ArchLoong64 = &Arch{
   139  	Name:           "loong64",
   140  	Family:         Loong64,
   141  	ByteOrder:      binary.LittleEndian,
   142  	PtrSize:        8,
   143  	RegSize:        8,
   144  	MinLC:          4,
   145  	Alignment:      8, // Unaligned accesses are not guaranteed to be fast
   146  	CanMergeLoads:  false,
   147  	HasLR:          true,
   148  	FixedFrameSize: 8, // LR
   149  }
   150  
   151  var ArchMIPS = &Arch{
   152  	Name:           "mips",
   153  	Family:         MIPS,
   154  	ByteOrder:      binary.BigEndian,
   155  	PtrSize:        4,
   156  	RegSize:        4,
   157  	MinLC:          4,
   158  	Alignment:      4,
   159  	CanMergeLoads:  false,
   160  	HasLR:          true,
   161  	FixedFrameSize: 4, // LR
   162  }
   163  
   164  var ArchMIPSLE = &Arch{
   165  	Name:           "mipsle",
   166  	Family:         MIPS,
   167  	ByteOrder:      binary.LittleEndian,
   168  	PtrSize:        4,
   169  	RegSize:        4,
   170  	MinLC:          4,
   171  	Alignment:      4,
   172  	CanMergeLoads:  false,
   173  	HasLR:          true,
   174  	FixedFrameSize: 4, // LR
   175  }
   176  
   177  var ArchMIPS64 = &Arch{
   178  	Name:           "mips64",
   179  	Family:         MIPS64,
   180  	ByteOrder:      binary.BigEndian,
   181  	PtrSize:        8,
   182  	RegSize:        8,
   183  	MinLC:          4,
   184  	Alignment:      8,
   185  	CanMergeLoads:  false,
   186  	HasLR:          true,
   187  	FixedFrameSize: 8, // LR
   188  }
   189  
   190  var ArchMIPS64LE = &Arch{
   191  	Name:           "mips64le",
   192  	Family:         MIPS64,
   193  	ByteOrder:      binary.LittleEndian,
   194  	PtrSize:        8,
   195  	RegSize:        8,
   196  	MinLC:          4,
   197  	Alignment:      8,
   198  	CanMergeLoads:  false,
   199  	HasLR:          true,
   200  	FixedFrameSize: 8, // LR
   201  }
   202  
   203  var ArchPPC64 = &Arch{
   204  	Name:          "ppc64",
   205  	Family:        PPC64,
   206  	ByteOrder:     binary.BigEndian,
   207  	PtrSize:       8,
   208  	RegSize:       8,
   209  	MinLC:         4,
   210  	Alignment:     1,
   211  	CanMergeLoads: false,
   212  	HasLR:         true,
   213  	// PIC code on ppc64le requires 32 bytes of stack, and it's
   214  	// easier to just use that much stack always.
   215  	FixedFrameSize: 4 * 8,
   216  }
   217  
   218  var ArchPPC64LE = &Arch{
   219  	Name:           "ppc64le",
   220  	Family:         PPC64,
   221  	ByteOrder:      binary.LittleEndian,
   222  	PtrSize:        8,
   223  	RegSize:        8,
   224  	MinLC:          4,
   225  	Alignment:      1,
   226  	CanMergeLoads:  true,
   227  	HasLR:          true,
   228  	FixedFrameSize: 4 * 8,
   229  }
   230  
   231  var ArchRISCV64 = &Arch{
   232  	Name:           "riscv64",
   233  	Family:         RISCV64,
   234  	ByteOrder:      binary.LittleEndian,
   235  	PtrSize:        8,
   236  	RegSize:        8,
   237  	MinLC:          4,
   238  	Alignment:      8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
   239  	CanMergeLoads:  false,
   240  	HasLR:          true,
   241  	FixedFrameSize: 8, // LR
   242  }
   243  
   244  var ArchS390X = &Arch{
   245  	Name:           "s390x",
   246  	Family:         S390X,
   247  	ByteOrder:      binary.BigEndian,
   248  	PtrSize:        8,
   249  	RegSize:        8,
   250  	MinLC:          2,
   251  	Alignment:      1,
   252  	CanMergeLoads:  true,
   253  	HasLR:          true,
   254  	FixedFrameSize: 8, // LR
   255  }
   256  
   257  var ArchWasm = &Arch{
   258  	Name:           "wasm",
   259  	Family:         Wasm,
   260  	ByteOrder:      binary.LittleEndian,
   261  	PtrSize:        8,
   262  	RegSize:        8,
   263  	MinLC:          1,
   264  	Alignment:      1,
   265  	CanMergeLoads:  false,
   266  	HasLR:          false,
   267  	FixedFrameSize: 0,
   268  }
   269  
   270  var Archs = [...]*Arch{
   271  	Arch386,
   272  	ArchAMD64,
   273  	ArchARM,
   274  	ArchARM64,
   275  	ArchLoong64,
   276  	ArchMIPS,
   277  	ArchMIPSLE,
   278  	ArchMIPS64,
   279  	ArchMIPS64LE,
   280  	ArchPPC64,
   281  	ArchPPC64LE,
   282  	ArchRISCV64,
   283  	ArchS390X,
   284  	ArchWasm,
   285  }
   286  

View as plain text