diff options
| author | Yao Zhang <lunaria21@gmail.com> | 2015-09-10 11:32:32 -0400 |
|---|---|---|
| committer | Minux Ma <minux@golang.org> | 2015-11-12 04:43:42 +0000 |
| commit | 43ea3054358a3d2dde5787e088dffaba27c4d91e (patch) | |
| tree | 3432868bc03a298473b4acb1be781cc7d051c70e /src/cmd/asm/internal/arch | |
| parent | fa6a1ecd6327ffbedc7dd117e0fba819f6f4faf1 (diff) | |
| download | go-43ea3054358a3d2dde5787e088dffaba27c4d91e.tar.xz | |
cmd/asm: added support for GOARCH=mips64{,le}
Change-Id: I951387f88993715e86b6ab9f18d38ed5c691ee0f
Reviewed-on: https://go-review.googlesource.com/14443
Reviewed-by: Minux Ma <minux@golang.org>
Diffstat (limited to 'src/cmd/asm/internal/arch')
| -rw-r--r-- | src/cmd/asm/internal/arch/arch.go | 63 | ||||
| -rw-r--r-- | src/cmd/asm/internal/arch/mips64.go | 64 |
2 files changed, 127 insertions, 0 deletions
diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go index 04622e63ec..cc1aab6ad5 100644 --- a/src/cmd/asm/internal/arch/arch.go +++ b/src/cmd/asm/internal/arch/arch.go @@ -8,6 +8,7 @@ import ( "cmd/internal/obj" "cmd/internal/obj/arm" "cmd/internal/obj/arm64" + "cmd/internal/obj/mips" "cmd/internal/obj/ppc64" "cmd/internal/obj/x86" "fmt" @@ -65,6 +66,14 @@ func Set(GOARCH string) *Arch { return archArm() case "arm64": return archArm64() + case "mips64": + a := archMips64() + a.LinkArch = &mips.Linkmips64 + return a + case "mips64le": + a := archMips64() + a.LinkArch = &mips.Linkmips64le + return a case "ppc64": a := archPPC64() a.LinkArch = &ppc64.Linkppc64 @@ -363,3 +372,57 @@ func archPPC64() *Arch { IsJump: jumpPPC64, } } + +func archMips64() *Arch { + register := make(map[string]int16) + // Create maps for easy lookup of instruction names etc. + // Note that there is no list of names as there is for x86. + for i := mips.REG_R0; i <= mips.REG_R31; i++ { + register[obj.Rconv(i)] = int16(i) + } + for i := mips.REG_F0; i <= mips.REG_F31; i++ { + register[obj.Rconv(i)] = int16(i) + } + for i := mips.REG_M0; i <= mips.REG_M31; i++ { + register[obj.Rconv(i)] = int16(i) + } + for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ { + register[obj.Rconv(i)] = int16(i) + } + register["HI"] = mips.REG_HI + register["LO"] = mips.REG_LO + // Pseudo-registers. + register["SB"] = RSB + register["FP"] = RFP + register["PC"] = RPC + // Avoid unintentionally clobbering g using R30. + delete(register, "R30") + register["g"] = mips.REG_R30 + registerPrefix := map[string]bool{ + "F": true, + "FCR": true, + "M": true, + "R": true, + } + + instructions := make(map[string]int) + for i, s := range obj.Anames { + instructions[s] = i + } + for i, s := range mips.Anames { + if i >= obj.A_ARCHSPECIFIC { + instructions[s] = i + obj.ABaseMIPS64 + } + } + // Annoying alias. + instructions["JAL"] = mips.AJAL + + return &Arch{ + LinkArch: &mips.Linkmips64, + Instructions: instructions, + Register: register, + RegisterPrefix: registerPrefix, + RegisterNumber: mipsRegisterNumber, + IsJump: jumpMIPS64, + } +} diff --git a/src/cmd/asm/internal/arch/mips64.go b/src/cmd/asm/internal/arch/mips64.go new file mode 100644 index 0000000000..b5867d93df --- /dev/null +++ b/src/cmd/asm/internal/arch/mips64.go @@ -0,0 +1,64 @@ +// Copyright 2015 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. + +// This file encapsulates some of the odd characteristics of the +// 64-bit MIPS (MIPS64) instruction set, to minimize its interaction +// with the core of the assembler. + +package arch + +import "cmd/internal/obj/mips" + +func jumpMIPS64(word string) bool { + switch word { + case "BEQ", "BFPF", "BFPT", "BGEZ", "BGEZAL", "BGTZ", "BLEZ", "BLTZ", "BLTZAL", "BNE", "JMP", "JAL", "CALL": + return true + } + return false +} + +// IsMIPS64CMP reports whether the op (as defined by an mips.A* constant) is +// one of the CMP instructions that require special handling. +func IsMIPS64CMP(op int) bool { + switch op { + case mips.ACMPEQF, mips.ACMPEQD, mips.ACMPGEF, mips.ACMPGED, + mips.ACMPGTF, mips.ACMPGTD: + return true + } + return false +} + +// IsMIPS64MUL reports whether the op (as defined by an mips.A* constant) is +// one of the MUL/DIV/REM instructions that require special handling. +func IsMIPS64MUL(op int) bool { + switch op { + case mips.AMUL, mips.AMULU, mips.AMULV, mips.AMULVU, + mips.ADIV, mips.ADIVU, mips.ADIVV, mips.ADIVVU, + mips.AREM, mips.AREMU, mips.AREMV, mips.AREMVU: + return true + } + return false +} + +func mipsRegisterNumber(name string, n int16) (int16, bool) { + switch name { + case "F": + if 0 <= n && n <= 31 { + return mips.REG_F0 + n, true + } + case "FCR": + if 0 <= n && n <= 31 { + return mips.REG_FCR0 + n, true + } + case "M": + if 0 <= n && n <= 31 { + return mips.REG_M0 + n, true + } + case "R": + if 0 <= n && n <= 31 { + return mips.REG_R0 + n, true + } + } + return 0, false +} |
