Commit f9dafc74 authored by Cherry Zhang's avatar Cherry Zhang

cmd/compile, runtime, etc: get rid of constant FP registers

On ARM64, MIPS64, and PPC64, some floating point registers were
reserved for constants 0, 1, 2, 0.5, etc. This CL removes them.

On ARM64, they are never used. On MIPS64 and PPC64, the only use
case is a multiplication-by-2 in the old backend of the compiler,
which is replaced with an addition.

Change-Id: I737cbf43283756e3408964fc88c567a938c57036
Reviewed-on: https://go-review.googlesource.com/28095
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: default avatarDavid Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent b2e0e968
......@@ -43,10 +43,6 @@ var resvd = []int{
arm64.REGRT1,
arm64.REGRT2,
arm64.REG_R31, // REGZERO and REGSP
arm64.FREGZERO,
arm64.FREGHALF,
arm64.FREGONE,
arm64.FREGTWO,
}
/*
......
......@@ -47,10 +47,6 @@ var resvd = []int{
mips.REGTMP,
mips.REG_R26, // kernel
mips.REG_R27, // kernel
mips.FREGZERO,
mips.FREGHALF,
mips.FREGONE,
mips.FREGTWO,
}
/*
......@@ -516,8 +512,7 @@ func gmove(f *gc.Node, t *gc.Node) {
if ft == gc.TUINT64 {
p1 := ginsbranch(mips.ABEQ, nil, &rtmp, nil, 0)
gc.Nodreg(&r1, gc.Types[gc.TFLOAT64], mips.FREGTWO)
gins(mips.AMULD, &r1, &r2)
gins(mips.AADDD, &r2, &r2)
gc.Patch(p1, gc.Pc)
}
......
......@@ -112,10 +112,6 @@ func regnames(n *int) []string {
func excludedregs() uint64 {
// Exclude registers with fixed functions
regbits := 1<<0 | RtoB(mips.REGSP) | RtoB(mips.REGG) | RtoB(mips.REGSB) | RtoB(mips.REGTMP) | RtoB(mips.REGLINK) | RtoB(mips.REG_R26) | RtoB(mips.REG_R27)
// Also exclude floating point registers with fixed constants
regbits |= RtoB(mips.FREGZERO) | RtoB(mips.FREGHALF) | RtoB(mips.FREGONE) | RtoB(mips.FREGTWO)
return regbits
}
......
......@@ -51,11 +51,6 @@ var resvd = []int{
// TODO(austin): Consolidate REGTLS and REGG?
ppc64.REGG,
ppc64.REGTMP, // REGTMP
ppc64.FREGCVI,
ppc64.FREGZERO,
ppc64.FREGHALF,
ppc64.FREGONE,
ppc64.FREGTWO,
}
/*
......@@ -500,8 +495,7 @@ func gmove(f *gc.Node, t *gc.Node) {
gc.Regfree(&r1)
if ft == gc.TUINT64 {
p1 := gc.Gbranch(optoas(gc.OLT, gc.Types[gc.TUINT64]), nil, +1) // use CR0 here again
gc.Nodreg(&r1, gc.Types[gc.TFLOAT64], ppc64.FREGTWO)
gins(ppc64.AFMUL, &r1, &r2)
gins(ppc64.AFADD, &r2, &r2)
gc.Patch(p1, gc.Pc)
}
gmove(&r2, t)
......
......@@ -119,9 +119,6 @@ func excludedregs() uint64 {
regbits |= RtoB(ppc64.REG_R2)
regbits |= RtoB(ppc64.REG_R12)
}
// Also exclude floating point registers with fixed constants
regbits |= RtoB(ppc64.REG_F27) | RtoB(ppc64.REG_F28) | RtoB(ppc64.REG_F29) | RtoB(ppc64.REG_F30) | RtoB(ppc64.REG_F31)
return regbits
}
......
......@@ -91,10 +91,10 @@ var regNamesARM64 = []string{
"F25",
"F26",
"F27",
"F28", // 0.0
"F29", // 0.5
"F30", // 1.0
"F31", // 2.0
"F28",
"F29",
"F30",
"F31",
// pseudo-registers
"SB",
......@@ -128,7 +128,7 @@ func init() {
gpsp = gp | buildReg("SP")
gpspg = gpg | buildReg("SP")
gpspsbg = gpspg | buildReg("SB")
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27")
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
)
// Common regInfo
......
......@@ -88,13 +88,13 @@ var regNamesMIPS64 = []string{
"F21",
"F22",
"F23",
"F24", // 0.0
"F24",
"F25",
"F26", // 0.5
"F26",
"F27",
"F28", // 1.0
"F28",
"F29",
"F30", // 2.0
"F30",
"F31",
"HI", // high bits of multiplication
......@@ -132,7 +132,7 @@ func init() {
gpsp = gp | buildReg("SP")
gpspg = gpg | buildReg("SP")
gpspsbg = gpspg | buildReg("SB")
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F25 F27 F29 F31")
fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
lo = buildReg("LO")
hi = buildReg("HI")
callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
......
......@@ -77,11 +77,11 @@ var regNamesPPC64 = []string{
"F24",
"F25",
"F26",
// "F27", // reserved for "floating conversion constant"
// "F28", // 0.0
// "F29", // 0.5
// "F30", // 1.0
// "F31", // 2.0
"F27",
"F28",
"F29",
"F30",
"F31",
// "CR0",
// "CR1",
......
This diff is collapsed.
......@@ -229,14 +229,10 @@ const (
REGZERO = REG_R31
REGSP = REG_RSP
FREGRET = REG_F0
FREGMIN = REG_F7 // first register variable
FREGMAX = REG_F26 // last register variable for 7g only
FREGEXT = REG_F26 // first external register
FREGZERO = REG_F28 // both float and double
FREGHALF = REG_F29 // double
FREGONE = REG_F30 // double
FREGTWO = REG_F31 // double
FREGRET = REG_F0
FREGMIN = REG_F7 // first register variable
FREGMAX = REG_F26 // last register variable for 7g only
FREGEXT = REG_F26 // first external register
)
const (
......
......@@ -185,22 +185,18 @@ const (
REG_SPECIAL = REG_M0
REGZERO = REG_R0 /* set to zero */
REGSP = REG_R29
REGSB = REG_R28
REGLINK = REG_R31
REGRET = REG_R1
REGARG = -1 /* -1 disables passing the first argument in register */
REGRT1 = REG_R1 /* reserved for runtime, duffzero and duffcopy */
REGRT2 = REG_R2 /* reserved for runtime, duffcopy */
REGCTXT = REG_R22 /* context for closures */
REGG = REG_R30 /* G */
REGTMP = REG_R23 /* used by the linker */
FREGRET = REG_F0
FREGZERO = REG_F24 /* both float and double */
FREGHALF = REG_F26 /* double */
FREGONE = REG_F28 /* double */
FREGTWO = REG_F30 /* double */
REGZERO = REG_R0 /* set to zero */
REGSP = REG_R29
REGSB = REG_R28
REGLINK = REG_R31
REGRET = REG_R1
REGARG = -1 /* -1 disables passing the first argument in register */
REGRT1 = REG_R1 /* reserved for runtime, duffzero and duffcopy */
REGRT2 = REG_R2 /* reserved for runtime, duffcopy */
REGCTXT = REG_R22 /* context for closures */
REGG = REG_R30 /* G */
REGTMP = REG_R23 /* used by the linker */
FREGRET = REG_F0
)
const (
......
......@@ -132,29 +132,24 @@ const (
REG_LR = REG_SPR0 + 8
REG_CTR = REG_SPR0 + 9
REGZERO = REG_R0 /* set to zero */
REGSP = REG_R1
REGSB = REG_R2
REGRET = REG_R3
REGARG = -1 /* -1 disables passing the first argument in register */
REGRT1 = REG_R3 /* reserved for runtime, duffzero and duffcopy */
REGRT2 = REG_R4 /* reserved for runtime, duffcopy */
REGMIN = REG_R7 /* register variables allocated from here to REGMAX */
REGCTXT = REG_R11 /* context for closures */
REGTLS = REG_R13 /* C ABI TLS base pointer */
REGMAX = REG_R27
REGEXT = REG_R30 /* external registers allocated from here down */
REGG = REG_R30 /* G */
REGTMP = REG_R31 /* used by the linker */
FREGRET = REG_F0
FREGMIN = REG_F17 /* first register variable */
FREGMAX = REG_F26 /* last register variable for 9g only */
FREGEXT = REG_F26 /* first external register */
FREGCVI = REG_F27 /* floating conversion constant */
FREGZERO = REG_F28 /* both float and double */
FREGHALF = REG_F29 /* double */
FREGONE = REG_F30 /* double */
FREGTWO = REG_F31 /* double */
REGZERO = REG_R0 /* set to zero */
REGSP = REG_R1
REGSB = REG_R2
REGRET = REG_R3
REGARG = -1 /* -1 disables passing the first argument in register */
REGRT1 = REG_R3 /* reserved for runtime, duffzero and duffcopy */
REGRT2 = REG_R4 /* reserved for runtime, duffcopy */
REGMIN = REG_R7 /* register variables allocated from here to REGMAX */
REGCTXT = REG_R11 /* context for closures */
REGTLS = REG_R13 /* C ABI TLS base pointer */
REGMAX = REG_R27
REGEXT = REG_R30 /* external registers allocated from here down */
REGG = REG_R30 /* G */
REGTMP = REG_R31 /* used by the linker */
FREGRET = REG_F0
FREGMIN = REG_F17 /* first register variable */
FREGMAX = REG_F26 /* last register variable for 9g only */
FREGEXT = REG_F26 /* first external register */
)
/*
......
......@@ -11,9 +11,6 @@
TEXT runtime·rt0_go(SB),NOSPLIT,$0
// SP = stack; R0 = argc; R1 = argv
// initialize essential registers
BL runtime·reginit(SB)
SUB $32, RSP
MOVW R0, 8(RSP) // argc
MOVD R1, 16(RSP) // argv
......@@ -100,15 +97,6 @@ TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0
TEXT runtime·asminit(SB),NOSPLIT,$-8-0
RET
TEXT runtime·reginit(SB),NOSPLIT,$-8-0
// initialize essential FP registers
FMOVD $4503601774854144.0, F27
FMOVD $0.5, F29
FSUBD F29, F29, F28
FADDD F29, F29, F30
FADDD F30, F30, F31
RET
/*
* go-routine
*/
......
......@@ -14,9 +14,6 @@
TEXT runtime·rt0_go(SB),NOSPLIT,$0
// R29 = stack; R4 = argc; R5 = argv
// initialize essential registers
JAL runtime·reginit(SB)
ADDV $-24, R29
MOVW R4, 8(R29) // argc
MOVV R5, 16(R29) // argv
......@@ -88,19 +85,6 @@ TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0
TEXT runtime·asminit(SB),NOSPLIT,$-8-0
RET
TEXT _cgo_reginit(SB),NOSPLIT,$-8-0
// crosscall1 needs to reginit, but can't
// get at the 'runtime.reginit' symbol.
JMP runtime·reginit(SB)
TEXT runtime·reginit(SB),NOSPLIT,$-8-0
// initialize essential FP registers
MOVD $0.5, F26
SUBD F26, F26, F24
ADDD F26, F26, F28
ADDD F28, F28, F30
RET
/*
* go-routine
*/
......
......@@ -106,12 +106,6 @@ TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0
// set R0 to zero, it's expected by the toolchain
XOR R0, R0
// initialize essential FP registers
FMOVD $4503601774854144.0, F27
FMOVD $0.5, F29
FSUB F29, F29, F28
FADD F29, F29, F30
FADD F30, F30, F31
RET
/*
......
......@@ -43,7 +43,6 @@ TEXT crosscall2(SB),NOSPLIT,$-8
MOVD R0, R19
// Initialize Go ABI environment
BL runtime·reginit(SB)
BL runtime·load_g(SB)
BL (R19)
......
......@@ -46,7 +46,6 @@ TEXT crosscall2(SB),NOSPLIT,$-8
BGEZAL R0, 1(PC)
SRLV $32, R31, RSB
SLLV $32, RSB
JAL runtime·reginit(SB)
JAL runtime·load_g(SB)
JAL (R4)
......
......@@ -35,8 +35,6 @@ crosscall1:
sdc1 $f30, 136($29)
sdc1 $f31, 144($29)
dla $23,_cgo_reginit
// prepare SB register = pc & 0xffffffff00000000
bal 1f
1:
......@@ -44,7 +42,6 @@ crosscall1:
dsll $28, $28, 32
move $20, $4 // save R4
jalr $23 // call _cgo_reginit, set up Go ABI constant registers
move $1, $6
jalr $5 // call setg_gcc (clobbers R4)
jalr $20 // call fn
......
// 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.
// +build mips64 mips64le
package runtime
// crosscall1 calls into the runtime to set up the registers the
// Go runtime expects and so the symbol it calls needs to be exported
// for external linking to work.
//go:cgo_export_static _cgo_reginit
......@@ -238,9 +238,6 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
SRLV $32, R31, RSB
SLLV $32, RSB
// initialize essential registers (just in case)
JAL runtime·reginit(SB)
// this might be called in external code context,
// where g is not set.
MOVB runtime·iscgo(SB), R1
......@@ -328,8 +325,6 @@ TEXT runtime·clone(SB),NOSPLIT,$-8
RET
// In child, on new stack.
// initialize essential registers
JAL runtime·reginit(SB)
MOVV -32(R29), R16
MOVV $1234, R1
BEQ R16, R1, 2(PC)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment