[dev.ssa] cmd/compile/internal/ssa: implement ORETJMP

Change-Id: I352c7b9aab053959bc74c15861339e1dbe545ddc
Reviewed-on: https://go-review.googlesource.com/14404
Reviewed-by: David Chase <drchase@google.com>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index e3a71a9f..9d87f38 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -583,6 +583,14 @@
 		b.Kind = ssa.BlockRet
 		b.Control = m
 		b.AddEdgeTo(s.exit)
+	case ORETJMP:
+		s.stmtList(n.List)
+		m := s.mem()
+		b := s.endBlock()
+		b.Kind = ssa.BlockRetJmp
+		b.Aux = n.Left.Sym
+		b.Control = m
+		b.AddEdgeTo(s.exit)
 
 	case OCONTINUE, OBREAK:
 		var op string
@@ -2054,6 +2062,11 @@
 	case PEXTERN, PPARAMOUT, PPARAMREF:
 		return false
 	}
+	if n.Class == PPARAM && n.String() == ".this" {
+		// wrappers generated by genwrapper need to update
+		// the .this pointer in place.
+		return false
+	}
 	return canSSAType(n.Type)
 	// TODO: try to make more variables SSAable?
 }
@@ -3475,6 +3488,11 @@
 			s.deferReturn()
 		}
 		Prog(obj.ARET)
+	case ssa.BlockRetJmp:
+		p := Prog(obj.AJMP)
+		p.To.Type = obj.TYPE_MEM
+		p.To.Name = obj.NAME_EXTERN
+		p.To.Sym = Linksym(b.Aux.(*Sym))
 	case ssa.BlockCall:
 		if b.Succs[0] != next {
 			p := Prog(obj.AJMP)