Commit 98139510 authored by Cherry Zhang's avatar Cherry Zhang Committed by Minux Ma

cmd/internal/obj/mips et al.: introduce SB register on mips64x

SB register (R28) is introduced for access external addresses with shorter
instruction sequences. It is loaded at entry points. External data within
2G of SB can be accessed this way.

cmd/internal/obj: relocaltion R_ADDRMIPS is split into two relocations
R_ADDRMIPS and R_ADDRMIPSU, handling the low 16 bits and the "upper" 16
bits of external addresses, respectively, since the instructios may not
be adjacent. It might be better if relocation Variant could be used.

cmd/link/internal/mips64: support new relocations.

cmd/compile/internal/mips64: reserve SB register.

runtime: initialize SB register at entry points.

Change-Id: I5f34868f88c5a9698c042a8a1f12f76806c187b9
Reviewed-on: https://go-review.googlesource.com/19802Reviewed-by: default avatarMinux Ma <minux@golang.org>
parent 8dc0444a
...@@ -41,6 +41,7 @@ import ( ...@@ -41,6 +41,7 @@ import (
var resvd = []int{ var resvd = []int{
mips.REGZERO, mips.REGZERO,
mips.REGSP, // reserved for SP mips.REGSP, // reserved for SP
mips.REGSB, // reserved for SB
mips.REGLINK, // reserved for link mips.REGLINK, // reserved for link
mips.REGG, mips.REGG,
mips.REGTMP, mips.REGTMP,
......
...@@ -111,7 +111,7 @@ func regnames(n *int) []string { ...@@ -111,7 +111,7 @@ func regnames(n *int) []string {
func excludedregs() uint64 { func excludedregs() uint64 {
// Exclude registers with fixed functions // Exclude registers with fixed functions
regbits := 1<<0 | RtoB(mips.REGSP) | RtoB(mips.REGG) | RtoB(mips.REGTMP) | RtoB(mips.REGLINK) | RtoB(mips.REG_R26) | RtoB(mips.REG_R27) 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 // Also exclude floating point registers with fixed constants
regbits |= RtoB(mips.FREGZERO) | RtoB(mips.FREGHALF) | RtoB(mips.FREGONE) | RtoB(mips.FREGTWO) regbits |= RtoB(mips.FREGZERO) | RtoB(mips.FREGHALF) | RtoB(mips.FREGONE) | RtoB(mips.FREGTWO)
......
...@@ -454,8 +454,8 @@ const ( ...@@ -454,8 +454,8 @@ const (
// R_ADDRARM64 relocates an adrp, add pair to compute the address of the // R_ADDRARM64 relocates an adrp, add pair to compute the address of the
// referenced symbol. // referenced symbol.
R_ADDRARM64 R_ADDRARM64
// R_ADDRMIPS (only used on mips64) resolves to a 32-bit external address, // R_ADDRMIPS (only used on mips64) resolves to the low 16 bits of an external
// by loading the address into a register with two instructions (lui, ori). // address, by encoding it into the instruction.
R_ADDRMIPS R_ADDRMIPS
// R_ADDROFF resolves to a 32-bit offset from the beginning of the section // R_ADDROFF resolves to a 32-bit offset from the beginning of the section
// holding the data being relocated to the referenced symbol. // holding the data being relocated to the referenced symbol.
...@@ -581,6 +581,10 @@ const ( ...@@ -581,6 +581,10 @@ const (
// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
// TODO(mundaym): remove once variants can be serialized - see issue 14218. // TODO(mundaym): remove once variants can be serialized - see issue 14218.
R_PCRELDBL R_PCRELDBL
// R_ADDRMIPSU (only used on mips64) resolves to the sign-adjusted "upper" 16
// bits (bit 16-31) of an external address, by encoding it into the instruction.
R_ADDRMIPSU
) )
type Auto struct { type Auto struct {
......
...@@ -60,7 +60,7 @@ var optab = []Optab{ ...@@ -60,7 +60,7 @@ var optab = []Optab{
{obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0}, {obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0},
{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0}, {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0},
{AMOVW, C_REG, C_NONE, C_REG, 14, 8, 0}, {AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0},
{AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0}, {AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0},
{AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0}, {AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0},
{AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0}, {AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0},
...@@ -121,42 +121,42 @@ var optab = []Optab{ ...@@ -121,42 +121,42 @@ var optab = []Optab{
{AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, {AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO}, {AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
{AMOVW, C_REG, C_NONE, C_LEXT, 35, 16, REGSB}, {AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVWU, C_REG, C_NONE, C_LEXT, 35, 16, REGSB}, {AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVV, C_REG, C_NONE, C_LEXT, 35, 16, REGSB}, {AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVB, C_REG, C_NONE, C_LEXT, 35, 16, REGSB}, {AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVBU, C_REG, C_NONE, C_LEXT, 35, 16, REGSB}, {AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, REGSB},
{AMOVW, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP}, {AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP}, {AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVV, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP}, {AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVB, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP}, {AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP}, {AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP},
{AMOVW, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO}, {AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVWU, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO}, {AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVV, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO}, {AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVB, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO}, {AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVBU, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO}, {AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO},
{AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVW, C_LEXT, C_NONE, C_REG, 36, 16, REGSB}, {AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVWU, C_LEXT, C_NONE, C_REG, 36, 16, REGSB}, {AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVV, C_LEXT, C_NONE, C_REG, 36, 16, REGSB}, {AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVB, C_LEXT, C_NONE, C_REG, 36, 16, REGSB}, {AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVBU, C_LEXT, C_NONE, C_REG, 36, 16, REGSB}, {AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, REGSB},
{AMOVW, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP}, {AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP}, {AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVV, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP}, {AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVB, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP}, {AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP}, {AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP},
{AMOVW, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO}, {AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVWU, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO}, {AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVV, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO}, {AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVB, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO}, {AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVBU, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO}, {AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO},
{AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0}, {AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0}, {AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0},
{AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0}, {AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0},
...@@ -167,8 +167,8 @@ var optab = []Optab{ ...@@ -167,8 +167,8 @@ var optab = []Optab{
{AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB}, {AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
{AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP}, {AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP},
{AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP}, {AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP},
{AMOVW, C_LECON, C_NONE, C_REG, 26, 12, REGSB}, {AMOVW, C_LECON, C_NONE, C_REG, 52, 12, REGSB},
{AMOVV, C_LECON, C_NONE, C_REG, 26, 12, REGSB}, {AMOVV, C_LECON, C_NONE, C_REG, 52, 12, REGSB},
{AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP}, {AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP},
{AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP}, {AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP},
{AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO}, {AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
...@@ -238,15 +238,15 @@ var optab = []Optab{ ...@@ -238,15 +238,15 @@ var optab = []Optab{
{AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, {AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
{AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO}, {AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
{AMOVW, C_LEXT, C_NONE, C_FREG, 27, 16, REGSB}, {AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB},
{AMOVF, C_LEXT, C_NONE, C_FREG, 27, 16, REGSB}, {AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB},
{AMOVD, C_LEXT, C_NONE, C_FREG, 27, 16, REGSB}, {AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, REGSB},
{AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 16, REGSP}, {AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP},
{AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 16, REGSP}, {AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP},
{AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 16, REGSP}, {AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP},
{AMOVW, C_LOREG, C_NONE, C_FREG, 27, 16, REGZERO}, {AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO},
{AMOVF, C_LOREG, C_NONE, C_FREG, 27, 16, REGZERO}, {AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO},
{AMOVD, C_LOREG, C_NONE, C_FREG, 27, 16, REGZERO}, {AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO},
{AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0}, {AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0},
{AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0}, {AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0},
...@@ -260,15 +260,15 @@ var optab = []Optab{ ...@@ -260,15 +260,15 @@ var optab = []Optab{
{AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, {AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
{AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO}, {AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
{AMOVW, C_FREG, C_NONE, C_LEXT, 28, 16, REGSB}, {AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB},
{AMOVF, C_FREG, C_NONE, C_LEXT, 28, 16, REGSB}, {AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB},
{AMOVD, C_FREG, C_NONE, C_LEXT, 28, 16, REGSB}, {AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, REGSB},
{AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 16, REGSP}, {AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP},
{AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 16, REGSP}, {AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP},
{AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 16, REGSP}, {AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP},
{AMOVW, C_FREG, C_NONE, C_LOREG, 28, 16, REGZERO}, {AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO},
{AMOVF, C_FREG, C_NONE, C_LOREG, 28, 16, REGZERO}, {AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO},
{AMOVD, C_FREG, C_NONE, C_LOREG, 28, 16, REGZERO}, {AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO},
{AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0},
{AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0}, {AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0},
...@@ -279,8 +279,6 @@ var optab = []Optab{ ...@@ -279,8 +279,6 @@ var optab = []Optab{
{AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0}, {AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0},
{AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0}, {AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0},
{AMOVW, C_UCON, C_NONE, C_FREG, 35, 8, 0},
{AMOVW, C_LCON, C_NONE, C_FREG, 36, 12, 0},
{AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0}, {AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0},
{AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0}, {AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0},
...@@ -541,9 +539,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { ...@@ -541,9 +539,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
} }
ctxt.Instoffset = a.Offset ctxt.Instoffset = a.Offset
return C_LECON
/* not sure why this barfs */
return C_LCON
case obj.NAME_AUTO: case obj.NAME_AUTO:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
...@@ -765,6 +761,7 @@ func (x ocmp) Less(i, j int) bool { ...@@ -765,6 +761,7 @@ func (x ocmp) Less(i, j int) bool {
} }
return false return false
} }
func opset(a, b0 obj.As) { func opset(a, b0 obj.As) {
oprange[a&obj.AMask] = oprange[b0] oprange[a&obj.AMask] = oprange[b0]
} }
...@@ -989,7 +986,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -989,7 +986,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
break break
case 1: /* mov r1,r2 ==> OR r1,r0,r2 */ case 1: /* mov r1,r2 ==> OR r1,r0,r2 */
o1 = OP_RRR(oprrr(ctxt, AOR), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg)) a := AOR
if p.As == AMOVW {
a = AADDU // sign-extended to high 32 bits
}
o1 = OP_RRR(oprrr(ctxt, a), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg))
case 2: /* add/sub r1,[r2],r3 */ case 2: /* add/sub r1,[r2],r3 */
r := int(p.Reg) r := int(p.Reg)
...@@ -1131,11 +1132,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1131,11 +1132,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
case 14: /* movwu r,r */ case 14: /* movwu r,r */
o1 = OP_SRR(opirr(ctxt, -ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg)) o1 = OP_SRR(opirr(ctxt, -ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
if p.As == AMOVWU { o2 = OP_SRR(opirr(ctxt, -ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
o2 = OP_SRR(opirr(ctxt, -ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
} else {
o2 = OP_SRR(opirr(ctxt, -ASRAV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
}
case 16: /* sll $c,[r1],r2 */ case 16: /* sll $c,[r1],r2 */
v := regoff(ctxt, &p.From) v := regoff(ctxt, &p.From)
...@@ -1166,14 +1163,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1166,14 +1163,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
v := regoff(ctxt, &p.From) v := regoff(ctxt, &p.From)
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
if p.From.Sym != nil {
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
rel.Type = obj.R_ADDRMIPS
}
case 20: /* mov lo/hi,r */ case 20: /* mov lo/hi,r */
a := OP(2, 0) /* mfhi */ a := OP(2, 0) /* mfhi */
...@@ -1236,11 +1225,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1236,11 +1225,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
a = -AMOVD a = -AMOVD
} }
switch o.size { switch o.size {
case 16: case 12:
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_RRR(opirr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
o4 = OP_IRR(opirr(ctxt, a), uint32(0), uint32(r), uint32(p.To.Reg))
case 4: case 4:
o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg)) o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg))
...@@ -1257,11 +1245,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1257,11 +1245,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
a = AMOVD a = AMOVD
} }
switch o.size { switch o.size {
case 16: case 12:
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_RRR(opirr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) o3 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
o4 = OP_IRR(opirr(ctxt, a), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
case 4: case 4:
o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.From.Reg)) o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.From.Reg))
...@@ -1294,27 +1281,25 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1294,27 +1281,25 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP))
o2 = OP_RRR(SP(2, 1)|(4<<21), uint32(REGTMP), uint32(0), uint32(p.To.Reg)) /* mtc1 */ o2 = OP_RRR(SP(2, 1)|(4<<21), uint32(REGTMP), uint32(0), uint32(p.To.Reg)) /* mtc1 */
case 35: /* mov r,lext/auto/oreg ==> sw o(r) */ case 35: /* mov r,lext/auto/oreg ==> sw o(REGTMP) */
v := regoff(ctxt, &p.To) v := regoff(ctxt, &p.To)
r := int(p.To.Reg) r := int(p.To.Reg)
if r == 0 { if r == 0 {
r = int(o.param) r = int(o.param)
} }
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) o3 = OP_IRR(opirr(ctxt, p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
o4 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
case 36: /* mov lext/auto/oreg,r ==> lw o(r30) */ case 36: /* mov lext/auto/oreg,r ==> lw o(REGTMP) */
v := regoff(ctxt, &p.From) v := regoff(ctxt, &p.From)
r := int(p.From.Reg) r := int(p.From.Reg)
if r == 0 { if r == 0 {
r = int(o.param) r = int(o.param)
} }
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32((v+1<<15)>>16), uint32(REGZERO), uint32(REGTMP))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP)) o3 = OP_IRR(opirr(ctxt, -p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
o4 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
case 37: /* movw r,mr */ case 37: /* movw r,mr */
a := SP(2, 0) | (4 << 21) /* mtc0 */ a := SP(2, 0) | (4 << 21) /* mtc0 */
...@@ -1349,30 +1334,59 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1349,30 +1334,59 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
case 49: /* undef */ case 49: /* undef */
o1 = 8 /* JMP (R0) */ o1 = 52 /* trap -- teq r0, r0 */
/* relocation operations */ /* relocation operations */
case 50: /* mov r,addr ==> lu + or + sw (REGTMP) */ case 50: /* mov r,addr ==> lu + add REGSB, REGTMP + sw o(REGTMP) */
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
rel := obj.Addrel(ctxt.Cursym) rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc) rel.Off = int32(ctxt.Pc)
rel.Siz = 8 rel.Siz = 4
rel.Sym = p.To.Sym rel.Sym = p.To.Sym
rel.Add = p.To.Offset rel.Add = p.To.Offset
rel.Type = obj.R_ADDRMIPS rel.Type = obj.R_ADDRMIPSU
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg)) o3 = OP_IRR(opirr(ctxt, p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
rel2 := obj.Addrel(ctxt.Cursym)
case 51: /* mov addr,r ==> lu + or + lw (REGTMP) */ rel2.Off = int32(ctxt.Pc + 8)
rel2.Siz = 4
rel2.Sym = p.To.Sym
rel2.Add = p.To.Offset
rel2.Type = obj.R_ADDRMIPS
case 51: /* mov addr,r ==> lu + add REGSB, REGTMP + lw o(REGTMP) */
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP)) o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(REGTMP))
o2 = OP_IRR(opirr(ctxt, AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
rel := obj.Addrel(ctxt.Cursym) rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc) rel.Off = int32(ctxt.Pc)
rel.Siz = 8 rel.Siz = 4
rel.Sym = p.From.Sym rel.Sym = p.From.Sym
rel.Add = p.From.Offset rel.Add = p.From.Offset
rel.Type = obj.R_ADDRMIPS rel.Type = obj.R_ADDRMIPSU
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(REGTMP), uint32(REGTMP))
o3 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg)) o3 = OP_IRR(opirr(ctxt, -p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
rel2 := obj.Addrel(ctxt.Cursym)
rel2.Off = int32(ctxt.Pc + 8)
rel2.Siz = 4
rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset
rel2.Type = obj.R_ADDRMIPS
case 52: /* mov $lext, r ==> lu + add REGSB, r + add */
o1 = OP_IRR(opirr(ctxt, ALUI), uint32(0), uint32(REGZERO), uint32(p.To.Reg))
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 4
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
rel.Type = obj.R_ADDRMIPSU
o2 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGSB), uint32(p.To.Reg), uint32(p.To.Reg))
o3 = OP_IRR(opirr(ctxt, AADDVU), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
rel2 := obj.Addrel(ctxt.Cursym)
rel2.Off = int32(ctxt.Pc + 8)
rel2.Siz = 4
rel2.Sym = p.From.Sym
rel2.Add = p.From.Offset
rel2.Type = obj.R_ADDRMIPS
} }
out[0] = o1 out[0] = o1
......
...@@ -34,7 +34,6 @@ import ( ...@@ -34,7 +34,6 @@ import (
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"encoding/binary"
"fmt" "fmt"
"log" "log"
) )
...@@ -71,24 +70,14 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { ...@@ -71,24 +70,14 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
return 0 return 0
case obj.R_ADDRMIPS: case obj.R_ADDRMIPS,
obj.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add t := ld.Symaddr(r.Sym) + r.Add
if t >= 1<<32 || t < -1<<32 {
ld.Diag("program too large, address relocation = %v", t)
}
// the first instruction is always at the lower address, this is endian neutral;
// but note that o1 and o2 should still use the target endian.
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:]) o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
o2 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off+4:]) if r.Type == obj.R_ADDRMIPS {
o1 = o1&0xffff0000 | uint32(t>>16)&0xffff *val = int64(o1&0xffff0000 | uint32(t)&0xffff)
o2 = o2&0xffff0000 | uint32(t)&0xffff
// when laid out, the instruction order must always be o1, o2.
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o1)<<32 | int64(o2)
} else { } else {
*val = int64(o2)<<32 | int64(o1) *val = int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff)
} }
return 0 return 0
......
...@@ -27,5 +27,10 @@ TEXT _main<>(SB),NOSPLIT,$-8 ...@@ -27,5 +27,10 @@ TEXT _main<>(SB),NOSPLIT,$-8
JMP main(SB) JMP main(SB)
TEXT main(SB),NOSPLIT,$-8 TEXT main(SB),NOSPLIT,$-8
// initalize REGSB = PC&0xffffffff00000000
BGEZAL R0, 1(PC)
SRLV $32, R31, RSB
SLLV $32, RSB
MOVV $runtime·rt0_go(SB), R4 MOVV $runtime·rt0_go(SB), R4
JMP (R4) JMP (R4)
...@@ -233,6 +233,11 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 ...@@ -233,6 +233,11 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
RET RET
TEXT runtime·sigtramp(SB),NOSPLIT,$64 TEXT runtime·sigtramp(SB),NOSPLIT,$64
// initialize REGSB = PC&0xffffffff00000000
BGEZAL R0, 1(PC)
SRLV $32, R31, RSB
SLLV $32, RSB
// initialize essential registers (just in case) // initialize essential registers (just in case)
JAL runtime·reginit(SB) JAL runtime·reginit(SB)
...@@ -250,8 +255,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 ...@@ -250,8 +255,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64
RET RET
TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
MOVV $runtime·sigtramp(SB), R1 JMP runtime·sigtramp(SB)
JMP (R1)
TEXT runtime·mmap(SB),NOSPLIT,$-8 TEXT runtime·mmap(SB),NOSPLIT,$-8
MOVV addr+0(FP), R4 MOVV addr+0(FP), R4
......
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