| // 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 |
| RISCV |
| 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 |
| } |
| |
| // 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, |
| } |
| |
| var ArchAMD64 = &Arch{ |
| Name: "amd64", |
| Family: AMD64, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 1, |
| Alignment: 1, |
| CanMergeLoads: true, |
| } |
| |
| var ArchARM = &Arch{ |
| Name: "arm", |
| Family: ARM, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 4, |
| RegSize: 4, |
| MinLC: 4, |
| Alignment: 4, // TODO: just for arm5? |
| CanMergeLoads: false, |
| } |
| |
| var ArchARM64 = &Arch{ |
| Name: "arm64", |
| Family: ARM64, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 4, |
| Alignment: 1, |
| CanMergeLoads: true, |
| } |
| |
| 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, |
| } |
| |
| var ArchMIPS = &Arch{ |
| Name: "mips", |
| Family: MIPS, |
| ByteOrder: binary.BigEndian, |
| PtrSize: 4, |
| RegSize: 4, |
| MinLC: 4, |
| Alignment: 4, |
| CanMergeLoads: false, |
| } |
| |
| var ArchMIPSLE = &Arch{ |
| Name: "mipsle", |
| Family: MIPS, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 4, |
| RegSize: 4, |
| MinLC: 4, |
| Alignment: 4, |
| CanMergeLoads: false, |
| } |
| |
| var ArchMIPS64 = &Arch{ |
| Name: "mips64", |
| Family: MIPS64, |
| ByteOrder: binary.BigEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 4, |
| Alignment: 8, |
| CanMergeLoads: false, |
| } |
| |
| var ArchMIPS64LE = &Arch{ |
| Name: "mips64le", |
| Family: MIPS64, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 4, |
| Alignment: 8, |
| CanMergeLoads: false, |
| } |
| |
| var ArchPPC64 = &Arch{ |
| Name: "ppc64", |
| Family: PPC64, |
| ByteOrder: binary.BigEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 4, |
| Alignment: 1, |
| CanMergeLoads: false, |
| } |
| |
| var ArchPPC64LE = &Arch{ |
| Name: "ppc64le", |
| Family: PPC64, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 4, |
| Alignment: 1, |
| CanMergeLoads: true, |
| } |
| |
| var ArchRISCV = &Arch{ |
| Name: "riscv", |
| Family: RISCV, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 4, |
| RegSize: 4, |
| MinLC: 4, |
| } |
| |
| 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, |
| } |
| |
| var ArchS390X = &Arch{ |
| Name: "s390x", |
| Family: S390X, |
| ByteOrder: binary.BigEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 2, |
| Alignment: 1, |
| CanMergeLoads: true, |
| } |
| |
| var ArchWasm = &Arch{ |
| Name: "wasm", |
| Family: Wasm, |
| ByteOrder: binary.LittleEndian, |
| PtrSize: 8, |
| RegSize: 8, |
| MinLC: 1, |
| Alignment: 1, |
| CanMergeLoads: false, |
| } |
| |
| var Archs = [...]*Arch{ |
| Arch386, |
| ArchAMD64, |
| ArchARM, |
| ArchARM64, |
| ArchLoong64, |
| ArchMIPS, |
| ArchMIPSLE, |
| ArchMIPS64, |
| ArchMIPS64LE, |
| ArchPPC64, |
| ArchPPC64LE, |
| ArchRISCV, |
| ArchRISCV64, |
| ArchS390X, |
| ArchWasm, |
| } |