aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/asm/internal/arch
diff options
context:
space:
mode:
authorYao Zhang <lunaria21@gmail.com>2015-09-10 11:32:32 -0400
committerMinux Ma <minux@golang.org>2015-11-12 04:43:42 +0000
commit43ea3054358a3d2dde5787e088dffaba27c4d91e (patch)
tree3432868bc03a298473b4acb1be781cc7d051c70e /src/cmd/asm/internal/arch
parentfa6a1ecd6327ffbedc7dd117e0fba819f6f4faf1 (diff)
downloadgo-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.go63
-rw-r--r--src/cmd/asm/internal/arch/mips64.go64
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
+}