[dev.ssa] cmd/compile/internal/ssa: remove cgen pass

Code generation is now done in genssa.
Also remove the asm field in opInfo. It's no longer used.

Change-Id: I65fffac267e138fd424b2ef8aa7ed79f0ebb63d5
Reviewed-on: https://go-review.googlesource.com/10539
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/ssa/TODO b/src/cmd/compile/internal/ssa/TODO
index afb723a..e3ffdd2 100644
--- a/src/cmd/compile/internal/ssa/TODO
+++ b/src/cmd/compile/internal/ssa/TODO
@@ -25,7 +25,6 @@
 Opcodes
  - Rename ops to prevent cross-arch conflicts.  MOVQ -> MOVQamd64 (or
    MOVQ6?).  Other option: build opcode table in Config instead of globally.
- - Remove asm string from opinfo, no longer needed.
  - It's annoying to list the opcode both in the opcode list and an
    opInfo map entry.  Specify it one place and use go:generate to
    produce both?
diff --git a/src/cmd/compile/internal/ssa/cgen.go b/src/cmd/compile/internal/ssa/cgen.go
deleted file mode 100644
index 51c72aa..0000000
--- a/src/cmd/compile/internal/ssa/cgen.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ssa
-
-import (
-	"bytes"
-	"fmt"
-	"os"
-)
-
-// cgen selects machine instructions for the function.
-// This pass generates assembly output for now, but should
-// TODO(khr): generate binary output (via liblink?) instead of text.
-func cgen(f *Func) {
-	fmt.Printf("TEXT %s(SB),0,$0\n", f.Name) // TODO: frame size / arg size
-
-	// TODO: prolog, allocate stack frame
-
-	for idx, b := range f.Blocks {
-		fmt.Printf("%d:\n", b.ID)
-		for _, v := range b.Values {
-			var buf bytes.Buffer
-			asm := opcodeTable[v.Op].asm
-			buf.WriteString("        ")
-			for i := 0; i < len(asm); i++ {
-				switch asm[i] {
-				default:
-					buf.WriteByte(asm[i])
-				case '\t':
-					buf.WriteByte(' ')
-					for buf.Len()%8 != 0 {
-						buf.WriteByte(' ')
-					}
-				case '%':
-					i++
-					switch asm[i] {
-					case '%':
-						buf.WriteByte('%')
-					case 'I':
-						i++
-						n := asm[i] - '0'
-						if f.RegAlloc[v.Args[n].ID] != nil {
-							buf.WriteString(f.RegAlloc[v.Args[n].ID].Name())
-						} else {
-							fmt.Fprintf(&buf, "v%d", v.Args[n].ID)
-						}
-					case 'O':
-						i++
-						n := asm[i] - '0'
-						if n != 0 {
-							panic("can only handle 1 output for now")
-						}
-						if f.RegAlloc[v.ID] != nil {
-							buf.WriteString(f.RegAlloc[v.ID].Name())
-						} else {
-							fmt.Fprintf(&buf, "v%d", v.ID)
-						}
-					case 'A':
-						fmt.Fprint(&buf, v.Aux)
-					}
-				}
-			}
-			for buf.Len() < 40 {
-				buf.WriteByte(' ')
-			}
-			buf.WriteString("; ")
-			buf.WriteString(v.LongString())
-			buf.WriteByte('\n')
-			os.Stdout.Write(buf.Bytes())
-		}
-		// find next block in layout sequence
-		var next *Block
-		if idx < len(f.Blocks)-1 {
-			next = f.Blocks[idx+1]
-		}
-		// emit end of block code
-		// TODO: this is machine specific
-		switch b.Kind {
-		case BlockPlain:
-			if b.Succs[0] != next {
-				fmt.Printf("\tJMP\t%d\n", b.Succs[0].ID)
-			}
-		case BlockExit:
-			// TODO: run defers (if any)
-			// TODO: deallocate frame
-			fmt.Println("\tRET")
-		case BlockCall:
-			// nothing to emit - call instruction already happened
-		case BlockEQ:
-			if b.Succs[0] == next {
-				fmt.Printf("\tJNE\t%d\n", b.Succs[1].ID)
-			} else if b.Succs[1] == next {
-				fmt.Printf("\tJEQ\t%d\n", b.Succs[0].ID)
-			} else {
-				fmt.Printf("\tJEQ\t%d\n", b.Succs[0].ID)
-				fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID)
-			}
-		case BlockNE:
-			if b.Succs[0] == next {
-				fmt.Printf("\tJEQ\t%d\n", b.Succs[1].ID)
-			} else if b.Succs[1] == next {
-				fmt.Printf("\tJNE\t%d\n", b.Succs[0].ID)
-			} else {
-				fmt.Printf("\tJNE\t%d\n", b.Succs[0].ID)
-				fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID)
-			}
-		case BlockLT:
-			if b.Succs[0] == next {
-				fmt.Printf("\tJGE\t%d\n", b.Succs[1].ID)
-			} else if b.Succs[1] == next {
-				fmt.Printf("\tJLT\t%d\n", b.Succs[0].ID)
-			} else {
-				fmt.Printf("\tJLT\t%d\n", b.Succs[0].ID)
-				fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID)
-			}
-		case BlockULT:
-			if b.Succs[0] == next {
-				fmt.Printf("\tJAE\t%d\n", b.Succs[1].ID)
-			} else if b.Succs[1] == next {
-				fmt.Printf("\tJB\t%d\n", b.Succs[0].ID)
-			} else {
-				fmt.Printf("\tJB\t%d\n", b.Succs[0].ID)
-				fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID)
-			}
-		default:
-			fmt.Printf("\t%s ->", b.Kind.String())
-			for _, s := range b.Succs {
-				fmt.Printf(" %d", s.ID)
-			}
-			fmt.Printf("\n")
-		}
-	}
-}
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index c1f7956..b497bea 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -65,7 +65,6 @@
 	{"schedule", schedule}, // schedule values
 	{"regalloc", regalloc},
 	{"stackalloc", stackalloc},
-	{"cgen", cgen},
 }
 
 // Double-check phase ordering constraints.
@@ -85,8 +84,6 @@
 	{"schedule", "regalloc"},
 	// stack allocation requires register allocation
 	{"regalloc", "stackalloc"},
-	// code generation requires stack allocation
-	{"stackalloc", "cgen"},
 }
 
 func init() {
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
index f02c1ae..75c6557 100644
--- a/src/cmd/compile/internal/ssa/op.go
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -118,12 +118,6 @@
 type opInfo struct {
 	flags int32
 
-	// assembly template
-	// %In: location of input n
-	// %On: location of output n
-	// %A: print aux with fmt.Print
-	asm string
-
 	// returns a reg constraint for the instruction. [0] gives a reg constraint
 	// for each input, [1] gives a reg constraint for each output. (Values have
 	// exactly one output for now)
diff --git a/src/cmd/compile/internal/ssa/opamd64.go b/src/cmd/compile/internal/ssa/opamd64.go
index 46a0069..5170909 100644
--- a/src/cmd/compile/internal/ssa/opamd64.go
+++ b/src/cmd/compile/internal/ssa/opamd64.go
@@ -123,39 +123,39 @@
 
 // Opcodes that appear in an output amd64 program
 var amd64Table = map[Op]opInfo{
-	OpADDQ:      {flags: OpFlagCommutative, asm: "ADDQ\t%I0,%I1,%O0", reg: gp21}, // TODO: overwrite
-	OpADDQconst: {asm: "ADDQ\t$%A,%I0,%O0", reg: gp11},                           // aux = int64 constant to add
-	OpSUBQ:      {asm: "SUBQ\t%I0,%I1,%O0", reg: gp21},
-	OpSUBQconst: {asm: "SUBQ\t$%A,%I0,%O0", reg: gp11},
-	OpMULQ:      {asm: "MULQ\t%I0,%I1,%O0", reg: gp21},
-	OpMULQconst: {asm: "IMULQ\t$%A,%I0,%O0", reg: gp11},
-	OpSHLQ:      {asm: "SHLQ\t%I0,%I1,%O0", reg: gp21},
-	OpSHLQconst: {asm: "SHLQ\t$%A,%I0,%O0", reg: gp11},
+	OpADDQ:      {flags: OpFlagCommutative, reg: gp21}, // TODO: overwrite
+	OpADDQconst: {reg: gp11},                           // aux = int64 constant to add
+	OpSUBQ:      {reg: gp21},
+	OpSUBQconst: {reg: gp11},
+	OpMULQ:      {reg: gp21},
+	OpMULQconst: {reg: gp11},
+	OpSHLQ:      {reg: gp21},
+	OpSHLQconst: {reg: gp11},
 
-	OpCMPQ:      {asm: "CMPQ\t%I0,%I1", reg: gp2_flags}, // compute arg[0]-arg[1] and produce flags
-	OpCMPQconst: {asm: "CMPQ\t$%A,%I0", reg: gp1_flags},
-	OpTESTQ:     {asm: "TESTQ\t%I0,%I1", reg: gp2_flags},
-	OpTESTB:     {asm: "TESTB\t%I0,%I1", reg: gp2_flags},
+	OpCMPQ:      {reg: gp2_flags}, // compute arg[0]-arg[1] and produce flags
+	OpCMPQconst: {reg: gp1_flags},
+	OpTESTQ:     {reg: gp2_flags},
+	OpTESTB:     {reg: gp2_flags},
 
-	OpLEAQ:       {flags: OpFlagCommutative, asm: "LEAQ\t%A(%I0)(%I1*1),%O0", reg: gp21}, // aux = int64 constant to add
-	OpLEAQ2:      {asm: "LEAQ\t%A(%I0)(%I1*2),%O0"},
-	OpLEAQ4:      {asm: "LEAQ\t%A(%I0)(%I1*4),%O0"},
-	OpLEAQ8:      {asm: "LEAQ\t%A(%I0)(%I1*8),%O0"},
-	OpLEAQglobal: {asm: "LEAQ\t%A(SB),%O0", reg: gp01},
+	OpLEAQ:       {flags: OpFlagCommutative, reg: gp21}, // aux = int64 constant to add
+	OpLEAQ2:      {},
+	OpLEAQ4:      {},
+	OpLEAQ8:      {},
+	OpLEAQglobal: {reg: gp01},
 
 	// loads and stores
-	OpMOVBload:      {asm: "MOVB\t%A(%I0),%O0", reg: gpload},
-	OpMOVQload:      {asm: "MOVQ\t%A(%I0),%O0", reg: gpload},
-	OpMOVQstore:     {asm: "MOVQ\t%I1,%A(%I0)", reg: gpstore},
-	OpMOVQloadidx8:  {asm: "MOVQ\t%A(%I0)(%I1*8),%O0", reg: gploadidx},
-	OpMOVQstoreidx8: {asm: "MOVQ\t%I2,%A(%I0)(%I1*8)", reg: gpstoreidx},
+	OpMOVBload:      {reg: gpload},
+	OpMOVQload:      {reg: gpload},
+	OpMOVQstore:     {reg: gpstore},
+	OpMOVQloadidx8:  {reg: gploadidx},
+	OpMOVQstoreidx8: {reg: gpstoreidx},
 
-	OpMOVQconst: {asm: "MOVQ\t$%A,%O0", reg: gp01},
+	OpMOVQconst: {reg: gp01},
 
-	OpStaticCall: {asm: "CALL\t%A(SB)"},
+	OpStaticCall: {},
 
-	OpCopy:    {asm: "MOVQ\t%I0,%O0", reg: gp11}, // TODO: make arch-specific
-	OpConvNop: {asm: "MOVQ\t%I0,%O0", reg: gp11}, // TODO: make arch-specific.  Or get rid of this altogether.
+	OpCopy:    {reg: gp11}, // TODO: make arch-specific
+	OpConvNop: {reg: gp11}, // TODO: make arch-specific.  Or get rid of this altogether.
 
 	// convert from flags back to boolean
 	OpSETL: {},
@@ -164,10 +164,10 @@
 	// unlike regular loads & stores, these take no memory argument.
 	// They are just like OpCopy but we use them during register allocation.
 	// TODO: different widths, float
-	OpLoadReg8:  {asm: "MOVQ\t%I0,%O0"},
-	OpStoreReg8: {asm: "MOVQ\t%I0,%O0"},
+	OpLoadReg8:  {},
+	OpStoreReg8: {},
 
-	OpREPMOVSB: {asm: "REP MOVSB", reg: [2][]regMask{{di, si, cx, 0}, {0}}}, // TODO: record that si/di/cx are clobbered
+	OpREPMOVSB: {reg: [2][]regMask{{di, si, cx, 0}, {0}}}, // TODO: record that si/di/cx are clobbered
 }
 
 func init() {