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

View as plain text