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  	HasLR:          true,
   149  	FixedFrameSize: 8, // LR
   150  }
   151  
   152  var ArchMIPS = &Arch{
   153  	Name:           "mips",
   154  	Family:         MIPS,
   155  	ByteOrder:      binary.BigEndian,
   156  	PtrSize:        4,
   157  	RegSize:        4,
   158  	MinLC:          4,
   159  	Alignment:      4,
   160  	CanMergeLoads:  false,
   161  	HasLR:          true,
   162  	FixedFrameSize: 4, // LR
   163  }
   164  
   165  var ArchMIPSLE = &Arch{
   166  	Name:           "mipsle",
   167  	Family:         MIPS,
   168  	ByteOrder:      binary.LittleEndian,
   169  	PtrSize:        4,
   170  	RegSize:        4,
   171  	MinLC:          4,
   172  	Alignment:      4,
   173  	CanMergeLoads:  false,
   174  	HasLR:          true,
   175  	FixedFrameSize: 4, // LR
   176  }
   177  
   178  var ArchMIPS64 = &Arch{
   179  	Name:           "mips64",
   180  	Family:         MIPS64,
   181  	ByteOrder:      binary.BigEndian,
   182  	PtrSize:        8,
   183  	RegSize:        8,
   184  	MinLC:          4,
   185  	Alignment:      8,
   186  	CanMergeLoads:  false,
   187  	HasLR:          true,
   188  	FixedFrameSize: 8, // LR
   189  }
   190  
   191  var ArchMIPS64LE = &Arch{
   192  	Name:           "mips64le",
   193  	Family:         MIPS64,
   194  	ByteOrder:      binary.LittleEndian,
   195  	PtrSize:        8,
   196  	RegSize:        8,
   197  	MinLC:          4,
   198  	Alignment:      8,
   199  	CanMergeLoads:  false,
   200  	HasLR:          true,
   201  	FixedFrameSize: 8, // LR
   202  }
   203  
   204  var ArchPPC64 = &Arch{
   205  	Name:          "ppc64",
   206  	Family:        PPC64,
   207  	ByteOrder:     binary.BigEndian,
   208  	PtrSize:       8,
   209  	RegSize:       8,
   210  	MinLC:         4,
   211  	Alignment:     1,
   212  	CanMergeLoads: true,
   213  	HasLR:         true,
   214  	// PIC code on ppc64le requires 32 bytes of stack, and it's
   215  	// easier to just use that much stack always.
   216  	FixedFrameSize: 4 * 8,
   217  }
   218  
   219  var ArchPPC64LE = &Arch{
   220  	Name:           "ppc64le",
   221  	Family:         PPC64,
   222  	ByteOrder:      binary.LittleEndian,
   223  	PtrSize:        8,
   224  	RegSize:        8,
   225  	MinLC:          4,
   226  	Alignment:      1,
   227  	CanMergeLoads:  true,
   228  	HasLR:          true,
   229  	FixedFrameSize: 4 * 8,
   230  }
   231  
   232  var ArchRISCV64 = &Arch{
   233  	Name:           "riscv64",
   234  	Family:         RISCV64,
   235  	ByteOrder:      binary.LittleEndian,
   236  	PtrSize:        8,
   237  	RegSize:        8,
   238  	MinLC:          4,
   239  	Alignment:      8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
   240  	CanMergeLoads:  false,
   241  	HasLR:          true,
   242  	FixedFrameSize: 8, // LR
   243  }
   244  
   245  var ArchS390X = &Arch{
   246  	Name:           "s390x",
   247  	Family:         S390X,
   248  	ByteOrder:      binary.BigEndian,
   249  	PtrSize:        8,
   250  	RegSize:        8,
   251  	MinLC:          2,
   252  	Alignment:      1,
   253  	CanMergeLoads:  true,
   254  	HasLR:          true,
   255  	FixedFrameSize: 8, // LR
   256  }
   257  
   258  var ArchWasm = &Arch{
   259  	Name:           "wasm",
   260  	Family:         Wasm,
   261  	ByteOrder:      binary.LittleEndian,
   262  	PtrSize:        8,
   263  	RegSize:        8,
   264  	MinLC:          1,
   265  	Alignment:      1,
   266  	CanMergeLoads:  false,
   267  	HasLR:          false,
   268  	FixedFrameSize: 0,
   269  }
   270  
   271  var Archs = [...]*Arch{
   272  	Arch386,
   273  	ArchAMD64,
   274  	ArchARM,
   275  	ArchARM64,
   276  	ArchLoong64,
   277  	ArchMIPS,
   278  	ArchMIPSLE,
   279  	ArchMIPS64,
   280  	ArchMIPS64LE,
   281  	ArchPPC64,
   282  	ArchPPC64LE,
   283  	ArchRISCV64,
   284  	ArchS390X,
   285  	ArchWasm,
   286  }
   287  

View as plain text