aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/mips/obj0.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/internal/obj/mips/obj0.go')
-rw-r--r--src/cmd/internal/obj/mips/obj0.go137
1 files changed, 97 insertions, 40 deletions
diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go
index 651da23955..221fd428a3 100644
--- a/src/cmd/internal/obj/mips/obj0.go
+++ b/src/cmd/internal/obj/mips/obj0.go
@@ -37,6 +37,18 @@ import (
)
func progedit(ctxt *obj.Link, p *obj.Prog) {
+ // Maintain information about code generation mode.
+ if ctxt.Mode == 0 {
+ switch ctxt.Arch.Family {
+ default:
+ ctxt.Diag("unsupported arch family")
+ case sys.MIPS:
+ ctxt.Mode = Mips32
+ case sys.MIPS64:
+ ctxt.Mode = Mips64
+ }
+ }
+
p.From.Class = 0
p.To.Class = 0
@@ -59,7 +71,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
f32 := float32(p.From.Val.(float64))
i32 := math.Float32bits(f32)
if i32 == 0 {
- p.As = AMOVV
+ p.As = AMOVW
p.From.Type = obj.TYPE_REG
p.From.Reg = REGZERO
break
@@ -76,7 +88,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
case AMOVD:
if p.From.Type == obj.TYPE_FCONST {
i64 := math.Float64bits(p.From.Val.(float64))
- if i64 == 0 {
+ if i64 == 0 && ctxt.Mode&Mips64 != 0 {
p.As = AMOVV
p.From.Type = obj.TYPE_REG
p.From.Reg = REGZERO
@@ -271,6 +283,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
}
+ var mov, add obj.As
+ if ctxt.Mode&Mips64 != 0 {
+ add = AADDV
+ mov = AMOVV
+ } else {
+ add = AADDU
+ mov = AMOVW
+ }
+
autosize := int32(0)
var p1 *obj.Prog
var p2 *obj.Prog
@@ -278,13 +299,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
o := p.As
switch o {
case obj.ATEXT:
- autosize = int32(textstksiz + 8)
- if (p.Mark&LEAF != 0) && autosize <= 8 {
+ autosize = int32(textstksiz + ctxt.FixedFrameSize())
+ if (p.Mark&LEAF != 0) && autosize <= int32(ctxt.FixedFrameSize()) {
autosize = 0
- } else if autosize&4 != 0 {
+ } else if autosize&4 != 0 && ctxt.Mode&Mips64 != 0 {
autosize += 4
}
- p.To.Offset = int64(autosize) - 8
+
+ p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
if p.From3.Offset&obj.NOSPLIT == 0 {
p = stacksplit(ctxt, p, autosize) // emit split check
@@ -299,7 +321,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame.
q = obj.Appendp(ctxt, q)
- q.As = AMOVV
+ q.As = mov
q.Lineno = p.Lineno
q.From.Type = obj.TYPE_REG
q.From.Reg = REGLINK
@@ -308,7 +330,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REGSP
q = obj.Appendp(ctxt, q)
- q.As = AADDV
+ q.As = add
q.Lineno = p.Lineno
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(-autosize)
@@ -333,13 +355,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
//
- // MOVV g_panic(g), R1
- // BEQ R1, end
- // MOVV panic_argp(R1), R2
- // ADDV $(autosize+8), R29, R3
- // BNE R2, R3, end
- // ADDV $8, R29, R2
- // MOVV R2, panic_argp(R1)
+ // MOV g_panic(g), R1
+ // BEQ R1, end
+ // MOV panic_argp(R1), R2
+ // ADD $(autosize+FIXED_FRAME), R29, R3
+ // BNE R2, R3, end
+ // ADD $FIXED_FRAME, R29, R2
+ // MOV R2, panic_argp(R1)
// end:
// NOP
//
@@ -348,7 +370,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q)
- q.As = AMOVV
+ q.As = mov
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
@@ -364,7 +386,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p1 = q
q = obj.Appendp(ctxt, q)
- q.As = AMOVV
+ q.As = mov
q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R1
q.From.Offset = 0 // Panic.argp
@@ -372,9 +394,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q)
- q.As = AADDV
+ q.As = add
q.From.Type = obj.TYPE_CONST
- q.From.Offset = int64(autosize) + 8
+ q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
@@ -389,15 +411,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p2 = q
q = obj.Appendp(ctxt, q)
- q.As = AADDV
+ q.As = add
q.From.Type = obj.TYPE_CONST
- q.From.Offset = 8
+ q.From.Offset = ctxt.FixedFrameSize()
q.Reg = REGSP
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q)
- q.As = AMOVV
+ q.As = mov
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2
q.To.Type = obj.TYPE_MEM
@@ -438,7 +460,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
break
}
- p.As = AADDV
+ p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize)
p.To.Type = obj.TYPE_REG
@@ -459,7 +481,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
break
}
- p.As = AMOVV
+ p.As = mov
p.From.Type = obj.TYPE_MEM
p.From.Offset = 0
p.From.Reg = REGSP
@@ -471,7 +493,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if autosize != 0 {
q = ctxt.NewProg()
- q.As = AADDV
+ q.As = add
q.Lineno = p.Lineno
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize)
@@ -501,7 +523,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q1.Link = q.Link
q.Link = q1
- case AADDV,
+ case AADD,
+ AADDU,
+ AADDV,
AADDVU:
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
p.Spadj = int32(-p.From.Offset)
@@ -564,10 +588,27 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
- // MOVV g_stackguard(g), R1
+ // Leaf function with no frame is effectively NOSPLIT.
+ if framesize == 0 {
+ return p
+ }
+
+ var mov, add, sub obj.As
+
+ if ctxt.Mode&Mips64 != 0 {
+ add = AADDV
+ mov = AMOVV
+ sub = ASUBVU
+ } else {
+ add = AADDU
+ mov = AMOVW
+ sub = ASUBU
+ }
+
+ // MOV g_stackguard(g), R1
p = obj.Appendp(ctxt, p)
- p.As = AMOVV
+ p.As = mov
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
@@ -591,11 +632,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R1
} else if framesize <= obj.StackBig {
// large stack: SP-framesize < stackguard-StackSmall
- // ADDV $-framesize, SP, R2
+ // ADD $-framesize, SP, R2
// SGTU R2, stackguard, R1
p = obj.Appendp(ctxt, p)
- p.As = AADDV
+ p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-framesize)
p.Reg = REGSP
@@ -619,15 +660,15 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// Preemption sets stackguard to StackPreempt, a very large value.
// That breaks the math above, so we have to check for that explicitly.
// // stackguard is R1
- // MOVV $StackPreempt, R2
+ // MOV $StackPreempt, R2
// BEQ R1, R2, label-of-call-to-morestack
- // ADDV $StackGuard, SP, R2
- // SUBVU R1, R2
- // MOVV $(framesize+(StackGuard-StackSmall)), R1
+ // ADD $StackGuard, SP, R2
+ // SUB R1, R2
+ // MOV $(framesize+(StackGuard-StackSmall)), R1
// SGTU R2, R1, R1
p = obj.Appendp(ctxt, p)
- p.As = AMOVV
+ p.As = mov
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackPreempt
p.To.Type = obj.TYPE_REG
@@ -643,7 +684,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.Mark |= BRANCH
p = obj.Appendp(ctxt, p)
- p.As = AADDV
+ p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard
p.Reg = REGSP
@@ -651,14 +692,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p)
- p.As = ASUBVU
+ p.As = sub
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p)
- p.As = AMOVV
+ p.As = mov
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = obj.TYPE_REG
@@ -683,10 +724,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_BRANCH
p.Mark |= BRANCH
- // MOVV LINK, R3
+ // MOV LINK, R3
p = obj.Appendp(ctxt, p)
- p.As = AMOVV
+ p.As = mov
p.From.Type = obj.TYPE_REG
p.From.Reg = REGLINK
p.To.Type = obj.TYPE_REG
@@ -1494,3 +1535,19 @@ var Linkmips64le = obj.LinkArch{
Follow: follow,
Progedit: progedit,
}
+
+var Linkmips = obj.LinkArch{
+ Arch: sys.ArchMIPS,
+ Preprocess: preprocess,
+ Assemble: span0,
+ Follow: follow,
+ Progedit: progedit,
+}
+
+var Linkmipsle = obj.LinkArch{
+ Arch: sys.ArchMIPSLE,
+ Preprocess: preprocess,
+ Assemble: span0,
+ Follow: follow,
+ Progedit: progedit,
+}