summaryrefslogtreecommitdiffstats
path: root/src/cmd/internal/sys/arch.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/internal/sys/arch.go')
-rw-r--r--src/cmd/internal/sys/arch.go285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/cmd/internal/sys/arch.go b/src/cmd/internal/sys/arch.go
new file mode 100644
index 0000000..2e35284
--- /dev/null
+++ b/src/cmd/internal/sys/arch.go
@@ -0,0 +1,285 @@
+// Copyright 2016 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 sys
+
+import "encoding/binary"
+
+// ArchFamily represents a family of one or more related architectures.
+// For example, ppc64 and ppc64le are both members of the PPC64 family.
+type ArchFamily byte
+
+const (
+ NoArch ArchFamily = iota
+ AMD64
+ ARM
+ ARM64
+ I386
+ Loong64
+ MIPS
+ MIPS64
+ PPC64
+ RISCV64
+ S390X
+ Wasm
+)
+
+// Arch represents an individual architecture.
+type Arch struct {
+ Name string
+ Family ArchFamily
+
+ ByteOrder binary.ByteOrder
+
+ // PtrSize is the size in bytes of pointers and the
+ // predeclared "int", "uint", and "uintptr" types.
+ PtrSize int
+
+ // RegSize is the size in bytes of general purpose registers.
+ RegSize int
+
+ // MinLC is the minimum length of an instruction code.
+ MinLC int
+
+ // Alignment is maximum alignment required by the architecture
+ // for any (compiler-generated) load or store instruction.
+ // Loads or stores smaller than Alignment must be naturally aligned.
+ // Loads or stores larger than Alignment need only be Alignment-aligned.
+ Alignment int8
+
+ // CanMergeLoads reports whether the backend optimization passes
+ // can combine adjacent loads into a single larger, possibly unaligned, load.
+ // Note that currently the optimizations must be able to handle little endian byte order.
+ CanMergeLoads bool
+
+ // CanJumpTable reports whether the backend can handle
+ // compiling a jump table.
+ CanJumpTable bool
+
+ // HasLR indicates that this architecture uses a link register
+ // for calls.
+ HasLR bool
+
+ // FixedFrameSize is the smallest possible offset from the
+ // hardware stack pointer to a local variable on the stack.
+ // Architectures that use a link register save its value on
+ // the stack in the function prologue and so always have a
+ // pointer between the hardware stack pointer and the local
+ // variable area.
+ FixedFrameSize int64
+}
+
+// InFamily reports whether a is a member of any of the specified
+// architecture families.
+func (a *Arch) InFamily(xs ...ArchFamily) bool {
+ for _, x := range xs {
+ if a.Family == x {
+ return true
+ }
+ }
+ return false
+}
+
+var Arch386 = &Arch{
+ Name: "386",
+ Family: I386,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 4,
+ RegSize: 4,
+ MinLC: 1,
+ Alignment: 1,
+ CanMergeLoads: true,
+ HasLR: false,
+ FixedFrameSize: 0,
+}
+
+var ArchAMD64 = &Arch{
+ Name: "amd64",
+ Family: AMD64,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 1,
+ Alignment: 1,
+ CanMergeLoads: true,
+ CanJumpTable: true,
+ HasLR: false,
+ FixedFrameSize: 0,
+}
+
+var ArchARM = &Arch{
+ Name: "arm",
+ Family: ARM,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 4,
+ RegSize: 4,
+ MinLC: 4,
+ Alignment: 4, // TODO: just for arm5?
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 4, // LR
+}
+
+var ArchARM64 = &Arch{
+ Name: "arm64",
+ Family: ARM64,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 1,
+ CanMergeLoads: true,
+ CanJumpTable: true,
+ HasLR: true,
+ FixedFrameSize: 8, // LR
+}
+
+var ArchLoong64 = &Arch{
+ Name: "loong64",
+ Family: Loong64,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 8, // Unaligned accesses are not guaranteed to be fast
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 8, // LR
+}
+
+var ArchMIPS = &Arch{
+ Name: "mips",
+ Family: MIPS,
+ ByteOrder: binary.BigEndian,
+ PtrSize: 4,
+ RegSize: 4,
+ MinLC: 4,
+ Alignment: 4,
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 4, // LR
+}
+
+var ArchMIPSLE = &Arch{
+ Name: "mipsle",
+ Family: MIPS,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 4,
+ RegSize: 4,
+ MinLC: 4,
+ Alignment: 4,
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 4, // LR
+}
+
+var ArchMIPS64 = &Arch{
+ Name: "mips64",
+ Family: MIPS64,
+ ByteOrder: binary.BigEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 8,
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 8, // LR
+}
+
+var ArchMIPS64LE = &Arch{
+ Name: "mips64le",
+ Family: MIPS64,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 8,
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 8, // LR
+}
+
+var ArchPPC64 = &Arch{
+ Name: "ppc64",
+ Family: PPC64,
+ ByteOrder: binary.BigEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 1,
+ CanMergeLoads: false,
+ HasLR: true,
+ // PIC code on ppc64le requires 32 bytes of stack, and it's
+ // easier to just use that much stack always.
+ FixedFrameSize: 4 * 8,
+}
+
+var ArchPPC64LE = &Arch{
+ Name: "ppc64le",
+ Family: PPC64,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 1,
+ CanMergeLoads: true,
+ HasLR: true,
+ FixedFrameSize: 4 * 8,
+}
+
+var ArchRISCV64 = &Arch{
+ Name: "riscv64",
+ Family: RISCV64,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 4,
+ Alignment: 8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
+ CanMergeLoads: false,
+ HasLR: true,
+ FixedFrameSize: 8, // LR
+}
+
+var ArchS390X = &Arch{
+ Name: "s390x",
+ Family: S390X,
+ ByteOrder: binary.BigEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 2,
+ Alignment: 1,
+ CanMergeLoads: true,
+ HasLR: true,
+ FixedFrameSize: 8, // LR
+}
+
+var ArchWasm = &Arch{
+ Name: "wasm",
+ Family: Wasm,
+ ByteOrder: binary.LittleEndian,
+ PtrSize: 8,
+ RegSize: 8,
+ MinLC: 1,
+ Alignment: 1,
+ CanMergeLoads: false,
+ HasLR: false,
+ FixedFrameSize: 0,
+}
+
+var Archs = [...]*Arch{
+ Arch386,
+ ArchAMD64,
+ ArchARM,
+ ArchARM64,
+ ArchLoong64,
+ ArchMIPS,
+ ArchMIPSLE,
+ ArchMIPS64,
+ ArchMIPS64LE,
+ ArchPPC64,
+ ArchPPC64LE,
+ ArchRISCV64,
+ ArchS390X,
+ ArchWasm,
+}