[dev.ssa] cmd/compile: implement OGETG

Change-Id: I7ecf62cf399c710b4a617803c43e83fce09b8a7d
Reviewed-on: https://go-review.googlesource.com/13585
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 0086fec..c8ec01f 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -1340,6 +1340,10 @@
 		}
 		a := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(fp.Type), fp.Width, s.sp)
 		return s.newValue2(ssa.OpLoad, fp.Type, a, call)
+
+	case OGETG:
+		return s.newValue0(ssa.OpGetG, n.Type)
+
 	default:
 		s.Unimplementedf("unhandled expr %s", opnames[n.Op])
 		return nil
@@ -2185,6 +2189,33 @@
 		q.From.Reg = x86.REG_AX
 		q.To.Type = obj.TYPE_MEM
 		q.To.Reg = x86.REG_AX
+	case ssa.OpAMD64LoweredGetG:
+		r := regnum(v)
+		// See the comments in cmd/internal/obj/x86/obj6.go
+		// near CanUse1InsnTLS for a detailed explanation of these instructions.
+		if x86.CanUse1InsnTLS(Ctxt) {
+			// MOVQ (TLS), r
+			p := Prog(x86.AMOVQ)
+			p.From.Type = obj.TYPE_MEM
+			p.From.Reg = x86.REG_TLS
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = r
+		} else {
+			// MOVQ TLS, r
+			// MOVQ (r)(TLS*1), r
+			p := Prog(x86.AMOVQ)
+			p.From.Type = obj.TYPE_REG
+			p.From.Reg = x86.REG_TLS
+			p.To.Type = obj.TYPE_REG
+			p.To.Reg = r
+			q := Prog(x86.AMOVQ)
+			q.From.Type = obj.TYPE_MEM
+			q.From.Reg = r
+			q.From.Index = x86.REG_TLS
+			q.From.Scale = 1
+			q.To.Type = obj.TYPE_REG
+			q.To.Reg = r
+		}
 	case ssa.OpAMD64CALLstatic:
 		p := Prog(obj.ACALL)
 		p.To.Type = obj.TYPE_MEM