diff options
Diffstat (limited to 'src/cmd/internal/obj/mips/obj0.go')
-rw-r--r-- | src/cmd/internal/obj/mips/obj0.go | 137 |
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, +} |