diff --git a/ppc64/ppc64map/map.go b/ppc64/ppc64map/map.go
index 4f90ed9..31d692d 100644
--- a/ppc64/ppc64map/map.go
+++ b/ppc64/ppc64map/map.go
@@ -12,6 +12,10 @@
 //
 //	text (default) - print decoding tree in text form
 //	decoder - print decoding tables for the ppc64asm package
+//	encoder - generate a self-contained file which can be used to encode
+//		  go obj.Progs into machine code
+//	asm - generate a gnu asm file which can be compiled by gcc containing
+//	      all opcodes discovered in ppc64.csv using macro friendly arguments.
 package main
 
 import (
@@ -20,6 +24,7 @@
 	"flag"
 	"fmt"
 	gofmt "go/format"
+	asm "golang.org/x/arch/ppc64/ppc64asm"
 	"log"
 	"math/bits"
 	"os"
@@ -28,8 +33,6 @@
 	"strconv"
 	"strings"
 	"text/template"
-
-	asm "golang.org/x/arch/ppc64/ppc64asm"
 )
 
 var format = flag.String("fmt", "text", "output format: text, decoder, asm")
@@ -37,6 +40,45 @@
 
 var inputFile string
 
+type isaversion uint32
+
+const (
+	// Sort as supersets of each other. Generally speaking, each newer ISA
+	// supports a superset of the previous instructions with a few exceptions
+	// throughout.
+	ISA_P1 isaversion = iota
+	ISA_P2
+	ISA_PPC
+	ISA_V200
+	ISA_V201
+	ISA_V202
+	ISA_V203
+	ISA_V205
+	ISA_V206
+	ISA_V207
+	ISA_V30
+	ISA_V30B
+	ISA_V30C
+	ISA_V31
+)
+
+var isaToISA = map[string]isaversion{
+	"P1":    ISA_P1,
+	"P2":    ISA_P2,
+	"PPC":   ISA_PPC,
+	"v2.00": ISA_V200,
+	"v2.01": ISA_V201,
+	"v2.02": ISA_V202,
+	"v2.03": ISA_V203,
+	"v2.05": ISA_V205,
+	"v2.06": ISA_V206,
+	"v2.07": ISA_V207,
+	"v3.0":  ISA_V30,
+	"v3.0B": ISA_V30B,
+	"v3.0C": ISA_V30C,
+	"v3.1":  ISA_V31,
+}
+
 func usage() {
 	fmt.Fprintf(os.Stderr, "usage: ppc64map [-fmt=format] ppc64.csv\n")
 	os.Exit(2)
@@ -64,6 +106,8 @@
 		print = printDecoder
 	case "asm":
 		print = printASM
+	case "encoder":
+		print = printEncoder
 	}
 
 	p, err := readCSV(flag.Arg(0))
@@ -104,15 +148,17 @@
 }
 
 type Prog struct {
-	Insts    []Inst
-	OpRanges map[string]string
+	Insts     []Inst
+	OpRanges  map[string]string
+	nextOrder int // Next position value (used for Insts[x].order)
 }
 
 type Field struct {
-	Name      string
-	BitFields asm.BitFields
-	Type      asm.ArgType
-	Shift     uint8
+	Name          string
+	BitFields     asm.BitFields
+	BitFieldNames []string
+	Type          asm.ArgType
+	Shift         uint8
 }
 
 func (f Field) String() string {
@@ -130,6 +176,12 @@
 	SValue    uint32 // Likewise for the Value
 	SDontCare uint32 // Likewise for the DontCare bits
 	Fields    []Field
+	Words     int // Number of words instruction encodes to.
+	Isa       isaversion
+	memOp     bool // Is this a memory operation?
+	memOpX    bool // Is this an x-form memory operation?
+	memOpSt   bool // Is this a store memory operations?
+	order     int  // Position in pp64.csv.
 }
 
 func (i Inst) String() string {
@@ -330,7 +382,7 @@
 // detected instructions into p. One entry may generate multiple intruction
 // entries as each extended mnemonic listed in text is treated like a unique
 // instruction.
-func add(p *Prog, text, mnemonics, encoding, tags string) {
+func add(p *Prog, text, mnemonics, encoding, isa string) {
 	// Parse encoding, building size and offset of each field.
 	// The first field in the encoding is the smallest offset.
 	// And note the MSB is bit 0, not bit 31.
@@ -340,12 +392,18 @@
 	iword := int8(0)
 	ispfx := false
 
+	isaLevel, fnd := isaToISA[isa]
+	if !fnd {
+		log.Fatalf("%s: ISA level '%s' is unknown\n", text, isa)
+		return
+	}
+
 	// Is this a prefixed instruction?
 	if encoding[0] == ',' {
 		pfields := strings.Split(encoding, ",")[1:]
 
 		if len(pfields) != 2 {
-			fmt.Fprintf(os.Stderr, "%s: Prefixed instruction must be 2 words long.\n", text)
+			log.Fatalf("%s: Prefixed instruction must be 2 words long.\n", text)
 			return
 		}
 		pargs = parseFields(pfields[0], text, iword)
@@ -617,17 +675,30 @@
 				f1.Offs, f1.Bits, f1.Word = uint8(args[i].Offs), uint8(args[i].Bits), uint8(args[i].Word)
 			}
 			field.BitFields.Append(f1)
+			field.BitFieldNames = append(field.BitFieldNames, opr)
 			if f2.Bits > 0 {
 				field.BitFields.Append(f2)
+				field.BitFieldNames = append(field.BitFieldNames, opr2)
 			}
 			if f3.Bits > 0 {
 				field.BitFields.Append(f3)
+				field.BitFieldNames = append(field.BitFieldNames, opr3)
 			}
 			inst.Fields = append(inst.Fields, field)
 		}
 		if *debug {
 			fmt.Printf("%v\n", inst)
 		}
+		inst.Isa = isaLevel
+		inst.memOp = hasMemoryArg(&inst)
+		inst.memOpX = inst.memOp && inst.Op[len(inst.Op)-1] == 'x'
+		inst.memOpSt = inst.memOp && strings.Contains(inst.Text, "Store")
+		inst.Words = 1
+		inst.order = p.nextOrder
+		p.nextOrder++
+		if ispfx {
+			inst.Words = 2
+		}
 		foundInst = append(foundInst, inst)
 	}
 
@@ -658,6 +729,453 @@
 	log.Fatal("-fmt=text not implemented")
 }
 
+// Some ISA instructions look like memory ops, but are not.
+var isNotMemopMap = map[string]bool{
+	"lxvkq": true,
+	"lvsl":  true,
+	"lvsr":  true,
+}
+
+// Some ISA instructions are memops, but are not described like "Load ..." or "Store ..."
+var isMemopMap = map[string]bool{}
+
+// Does this instruction contain a memory argument (e.g x-form load or d-form store)
+func hasMemoryArg(insn *Inst) bool {
+	return ((strings.HasPrefix(insn.Text, "Load") || strings.HasPrefix(insn.Text, "Store") ||
+		strings.HasPrefix(insn.Text, "Prefixed Load") || strings.HasPrefix(insn.Text, "Prefixed Store")) && !isNotMemopMap[insn.Op]) ||
+		isMemopMap[insn.Op]
+}
+
+// Generate a function which takes an obj.Proj and convert it into
+// machine code in the supplied buffer. These functions are used
+// by asm9.go.
+func insnEncFuncStr(insn *Inst, firstName [2]string) string {
+	buf := new(bytes.Buffer)
+	// Argument packing order.
+	// Note, if a2 is not a register type, it is skipped.
+	argOrder := []string{
+		"p.To",               // a6
+		"p.From",             // a1
+		"p",                  // a2
+		"p.RestArgs[0].Addr", // a3
+		"p.RestArgs[1].Addr", // a4
+		"p.RestArgs[2].Addr", // a5
+	}
+	if len(insn.Fields) > len(argOrder) {
+		log.Fatalf("cannot handle %v. Only %d args supported.", insn, len(argOrder))
+	}
+
+	// Does this field require an obj.Addr.Offset?
+	isImmediate := func(t asm.ArgType) bool {
+		return t == asm.TypeImmUnsigned || t == asm.TypeSpReg || t == asm.TypeImmSigned || t == asm.TypeOffset
+	}
+
+	if insn.memOp {
+		// Swap to/from arguments if we are generating
+		// for a store operation.
+		if insn.memOpSt {
+			// Otherwise, order first three args as: p.From, p.To, p.To
+			argOrder[0], argOrder[1] = argOrder[1], argOrder[0]
+		}
+		argOrder[2] = argOrder[1] // p.Reg is either an Index or Offset (X or D-form)
+	} else if len(insn.Fields) > 2 && isImmediate(insn.Fields[2].Type) {
+		// Delete the a2 argument if it is not a register type.
+		argOrder = append(argOrder[0:2], argOrder[3:]...)
+	}
+
+	fmt.Fprintf(buf, "// %s\n", insn.Encoding)
+	fmt.Fprintf(buf, "func type_%s(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {\n", insn.Op)
+	if insn.Words > 1 {
+		fmt.Fprintf(buf, "o0 := GenPfxOpcodes[p.As - A%s]\n", firstName[1])
+	}
+	fmt.Fprintf(buf, "o%d := GenOpcodes[p.As - A%s]\n", insn.Words-1, firstName[0])
+
+	errCheck := ""
+	for j, atype := range insn.Fields {
+		itype := ".Reg"
+		if isImmediate(atype.Type) {
+			itype = ".Offset"
+		} else if insn.memOpX && atype.Name == "RA" {
+			// X-form memory operations encode RA as the index register of memory type arg.
+			itype = ".Index"
+		}
+
+		bitPos := uint64(0)
+		// VecSpReg is encoded as an even numbered VSR. It is implicitly shifted by 1.
+		if atype.Type == asm.TypeVecSpReg {
+			bitPos += 1
+		}
+		// Count the total number of bits to work backwards when shifting
+		for _, f := range atype.BitFields {
+			bitPos += uint64(f.Bits)
+		}
+		// Adjust for any shifting (e.g DQ/DS shifted instructions)
+		bitPos += uint64(atype.Shift)
+		bits := bitPos
+
+		// Generate code to twirl the respective bits into the correct position, and mask off extras.
+		for i, f := range atype.BitFields {
+			bitPos -= uint64(f.Bits)
+			argStr := argOrder[j] + itype
+			if bitPos != 0 {
+				argStr = fmt.Sprintf("(%s>>%d)", argStr, bitPos)
+			}
+			mask := (1 << uint64(f.Bits)) - 1
+			shift := 32 - uint64(f.Offs) - uint64(f.Bits)
+			fmt.Fprintf(buf, "o%d |= uint32(%s&0x%x)<<%d // %s\n", f.Word, argStr, mask, shift, atype.BitFieldNames[i])
+		}
+
+		// Generate a check to verify shifted inputs satisfy their constraints.
+		// For historical reasons this is not needed for 16 bit values shifted by 16. (i.e SI/UI constants in addis/xoris)
+		if atype.Shift != 0 && atype.Shift != 16 && bits != 32 {
+			arg := argOrder[j] + itype
+			mod := (1 << atype.Shift) - 1
+			errCheck += fmt.Sprintf("if %s & 0x%x != 0 {\n", arg, mod)
+			errCheck += fmt.Sprintf("c.ctxt.Diag(\"Constant 0x%%x (%%d) is not a multiple of %d\\n%%v\",%s,%s,p)\n", mod+1, arg, arg)
+			errCheck += fmt.Sprintf("}\n")
+		}
+		j++
+	}
+	buf.WriteString(errCheck)
+	if insn.Words > 1 {
+		fmt.Fprintf(buf, "out[1] = o1\n")
+	}
+	fmt.Fprintf(buf, "out[0] = o0\n")
+	fmt.Fprintf(buf, "}\n")
+	return buf.String()
+}
+
+// Generate a stringed name representing the type of arguments ISA
+// instruction needs to be encoded into a usable machine instruction
+func insnTypeStr(insn *Inst, uniqueRegTypes bool) string {
+	if len(insn.Fields) == 0 {
+		return "type_none"
+	}
+
+	ret := "type_"
+
+	// Tag store opcodes to give special treatment when generating
+	// assembler function. They encode similarly to their load analogues.
+	if insn.memOp {
+		if insn.memOpSt {
+			ret += "st_"
+		} else {
+			ret += "ld_"
+		}
+	}
+
+	// TODO: this is only sufficient for ISA3.1.
+	for _, atype := range insn.Fields {
+		switch atype.Type {
+		// Simple, register like 5 bit field (CR bit, FPR, GPR, VR)
+		case asm.TypeReg, asm.TypeFPReg, asm.TypeVecReg, asm.TypeCondRegBit:
+			if uniqueRegTypes {
+				ret += map[asm.ArgType]string{asm.TypeReg: "R", asm.TypeFPReg: "F", asm.TypeVecReg: "V", asm.TypeCondRegBit: "C"}[atype.Type]
+				// Handle even/odd pairs in FPR/GPR args. They encode as 5 bits too, but odd values are invalid.
+				if atype.Name[len(atype.Name)-1] == 'p' {
+					ret += "p"
+				}
+			} else {
+				ret += "R"
+			}
+		case asm.TypeMMAReg, asm.TypeCondRegField: // 3 bit register fields (MMA or CR field)
+			ret += "M"
+		case asm.TypeSpReg:
+			ret += "P"
+		case asm.TypeVecSReg: // VSX register (6 bits, usually split into 2 fields)
+			ret += "X"
+		case asm.TypeVecSpReg: // VSX register pair (5 bits, maybe split fields)
+			ret += "Y"
+		case asm.TypeImmSigned, asm.TypeOffset, asm.TypeImmUnsigned:
+			if atype.Type == asm.TypeImmUnsigned {
+				ret += "I"
+			} else {
+				ret += "S"
+			}
+			if atype.Shift != 0 {
+				ret += fmt.Sprintf("%d", atype.Shift)
+			}
+		default:
+			log.Fatalf("Unhandled type in insnTypeStr: %v\n", atype)
+		}
+
+		// And add bit packing info
+		for _, bf := range atype.BitFields {
+			ret += fmt.Sprintf("_%d_%d", bf.Word*32+bf.Offs, bf.Bits)
+		}
+	}
+	return ret
+}
+
+type AggInfo struct {
+	Insns []*Inst // List of instructions sharing this type
+	Typef string  // The generated function name matching this
+}
+
+// Generate an Optab entry for a set of instructions with identical argument types
+// and write it to buf.
+func genOptabEntry(ta *AggInfo, typeMap map[string]*Inst) string {
+	buf := new(bytes.Buffer)
+	fitArg := func(f *Field, i *Inst) string {
+		argToRegType := map[asm.ArgType]string{
+			// TODO: only complete for ISA 3.1
+			asm.TypeReg:          "C_REG",
+			asm.TypeCondRegField: "C_CREG",
+			asm.TypeCondRegBit:   "C_CRBIT",
+			asm.TypeFPReg:        "C_FREG",
+			asm.TypeVecReg:       "C_VREG",
+			asm.TypeVecSReg:      "C_VSREG",
+			asm.TypeVecSpReg:     "C_VSREG",
+			asm.TypeMMAReg:       "C_AREG",
+			asm.TypeSpReg:        "C_SPR",
+		}
+		if t, fnd := argToRegType[f.Type]; fnd {
+			if f.Name[len(f.Name)-1] == 'p' {
+				return t + "P"
+			}
+			return t
+		}
+		bits := f.Shift
+		for _, sf := range f.BitFields {
+			bits += sf.Bits
+		}
+		shift := ""
+		if f.Shift != 0 {
+			shift = fmt.Sprintf("S%d", f.Shift)
+		}
+		sign := "U"
+		if f.Type == asm.TypeImmSigned || f.Type == asm.TypeOffset {
+			sign = "S"
+			// DS/DQ offsets should explicitly test their offsets to ensure
+			// they are aligned correctly. This makes tracking down bad offset
+			// passed to the compiler more straightfoward.
+			if f.Type == asm.TypeOffset {
+				shift = ""
+			}
+		}
+		return fmt.Sprintf("C_%s%d%sCON", sign, bits, shift)
+	}
+	insn := ta.Insns[0]
+	args := [6]string{}
+	// Note, a2 is skipped if the second input argument does not map to a reg.
+	argOrder := []int{
+		5,
+		0,
+		1,
+		2,
+		3,
+		4}
+
+	i := 0
+	for _, j := range insn.Fields {
+		// skip a2 if it isn't a reg type.
+		at := fitArg(&j, insn)
+		if argOrder[i] == 1 && !strings.HasSuffix(at, "REG") {
+			i++
+		}
+		args[argOrder[i]] = at
+		i++
+	}
+
+	// Likewise, fixup memory operations. Combine imm + reg, reg + reg
+	// operations into memory type arguments.
+	if insn.memOp {
+		switch args[0] + " " + args[1] {
+		case "C_REG C_REG":
+			args[0] = "C_XOREG"
+		case "C_S16CON C_REG":
+			args[0] = "C_SOREG"
+		case "C_S34CON C_REG":
+			args[0] = "C_LOREG"
+		}
+		args[1] = ""
+		// Finally, fixup store operand ordering to match golang
+		if insn.memOpSt {
+			args[0], args[5] = args[5], args[0]
+		}
+
+	}
+	fmt.Fprintf(buf, "{as: A%s,", opName(insn.Op))
+	for i, s := range args {
+		if len(s) <= 0 {
+			continue
+		}
+		fmt.Fprintf(buf, "a%d: %s, ", i+1, s)
+	}
+	typef := typeMap[ta.Typef].Op
+
+	pfx := ""
+	if insn.Words > 1 {
+		pfx = " ispfx: true,"
+	}
+	fmt.Fprintf(buf, "asmout: type_%s,%s size: %d},\n", typef, pfx, insn.Words*4)
+	return buf.String()
+}
+
+// printEncoder implements the -fmt=encoder mode. This generates a go file named
+// asm9_gtables.go.new. It is self-contained and is called into by the PPC64
+// assembler routines.
+//
+// For now it is restricted to generating code for ISA 3.1 and newer, but it could
+// support older ISA versions with some work, and integration effort.
+func printEncoder(p *Prog) {
+	const minISA = ISA_V31
+
+	// The type map separates based on obj.Addr to a bit field.  Register types
+	// for GPR, FPR, VR pack identically, but are classified differently.
+	typeMap := map[string]*Inst{}
+	typeAggMap := map[string]*AggInfo{}
+	var oplistBuf bytes.Buffer
+	var opnameBuf bytes.Buffer
+
+	// The first opcode of 32 or 64 bits to appear in the opcode tables.
+	firstInsn := [2]string{}
+
+	// Sort the instructions by word size, then by ISA version, oldest to newest.
+	sort.Slice(p.Insts, func(i, j int) bool {
+		if p.Insts[i].Words != p.Insts[j].Words {
+			return p.Insts[i].Words < p.Insts[j].Words
+		}
+		return p.Insts[i].order > p.Insts[j].order
+	})
+
+	// Classify each opcode and it's arguments, and generate opcode name/enum values.
+	for i, insn := range p.Insts {
+		if insn.Isa < minISA {
+			continue
+		}
+		extra := ""
+		if firstInsn[insn.Words-1] == "" {
+			firstInsn[insn.Words-1] = opName(insn.Op)
+			if insn.Words == 1 {
+				extra = " = ALASTAOUT + iota"
+			}
+		}
+		opType := insnTypeStr(&insn, false)
+		opTypeOptab := insnTypeStr(&insn, true)
+		fmt.Fprintf(&oplistBuf, "A%s%s\n", opName(insn.Op), extra)
+		fmt.Fprintf(&opnameBuf, "\"%s\",\n", opName(insn.Op))
+		// Use the oldest instruction to name the encoder function.  Some names
+		// may change if minISA is lowered.
+		if _, fnd := typeMap[opType]; !fnd {
+			typeMap[opType] = &p.Insts[i]
+		}
+		at, fnd := typeAggMap[opTypeOptab]
+		if !fnd {
+			typeAggMap[opTypeOptab] = &AggInfo{[]*Inst{&p.Insts[i]}, opType}
+		} else {
+			at.Insns = append(at.Insns, &p.Insts[i])
+		}
+	}
+	fmt.Fprintf(&oplistBuf, "ALASTGEN\n")
+	fmt.Fprintf(&oplistBuf, "AFIRSTGEN = A%s\n", firstInsn[0])
+
+	// Sort type information before outputing to ensure stable ordering
+	targ := struct {
+		InputFile   string
+		Insts       []Inst
+		MinISA      isaversion
+		TypeAggList []*AggInfo
+		TypeList    []*Inst
+		FirstInsn   [2]string
+		TypeMap     map[string]*Inst
+		Oplist      string
+		Opnames     string
+	}{InputFile: inputFile, Insts: p.Insts, MinISA: minISA, FirstInsn: firstInsn, TypeMap: typeMap, Oplist: oplistBuf.String(), Opnames: opnameBuf.String()}
+	for _, v := range typeAggMap {
+		targ.TypeAggList = append(targ.TypeAggList, v)
+	}
+	for _, v := range typeMap {
+		targ.TypeList = append(targ.TypeList, v)
+	}
+	sort.Slice(targ.TypeAggList, func(i, j int) bool {
+		// Sort based on the first entry, it is the last to appear in Appendix F.
+		return targ.TypeAggList[i].Insns[0].Op < targ.TypeAggList[j].Insns[0].Op
+	})
+	sort.Slice(targ.TypeList, func(i, j int) bool {
+		return targ.TypeList[i].Op < targ.TypeList[j].Op
+	})
+
+	// Generate asm9_gtable.go from the following template.
+	asm9_gtable_go := `
+		// DO NOT EDIT
+		// generated by: ppc64map -fmt=encoder {{.InputFile}}
+
+		package ppc64
+
+		import (
+			"cmd/internal/obj"
+		)
+
+		const (
+			{{print $.Oplist -}}
+		)
+
+		var GenAnames = []string {
+			{{print $.Opnames -}}
+		}
+
+		var GenOpcodes = [...]uint32 {
+			{{range $v := .Insts}}{{if ge $v.Isa $.MinISA -}}
+			{{if (eq $v.Words 1)}}{{printf "0x%08x, // A%s" $v.Value  (opname $v.Op)}}
+			{{else}}              {{printf "0x%08x, // A%s" $v.SValue (opname $v.Op)}}
+			{{end}}{{end}}{{end -}}
+		}
+
+		var GenPfxOpcodes = [...]uint32 {
+			{{range $v := .Insts}}{{if and (ge $v.Isa $.MinISA) (eq $v.Words 2) -}}
+			{{printf "0x%08x, // A%s" $v.Value (opname $v.Op)}}
+			{{end}}{{end -}}
+		}
+
+		var optabGen = []Optab {
+			{{range $v := .TypeAggList -}}
+			{{genoptabentry $v $.TypeMap -}}
+			{{end -}}
+		}
+
+		{{range $v := .TypeList}}
+		{{genencoderfunc $v $.FirstInsn}}
+		{{end}}
+
+		func opsetGen(from obj.As) bool {
+			r0 := from & obj.AMask
+			switch from {
+			{{range $v := .TypeAggList -}}
+			case A{{opname (index $v.Insns 0).Op}}:
+				{{range $w := (slice $v.Insns 1) -}}
+				opset(A{{opname $w.Op}},r0)
+				{{end -}}
+			{{end -}}
+			default:
+				return false
+			}
+			return true
+		}
+	`
+	tmpl := template.New("asm9_gtable.go")
+	tmpl.Funcs(template.FuncMap{
+		"opname":         opName,
+		"genencoderfunc": insnEncFuncStr,
+		"genoptabentry":  genOptabEntry,
+	})
+	tmpl.Parse(asm9_gtable_go)
+
+	// Write and gofmt the new file.
+	var tbuf bytes.Buffer
+	if err := tmpl.Execute(&tbuf, targ); err != nil {
+		log.Fatal(err)
+	}
+	tout, err := gofmt.Source(tbuf.Bytes())
+	if err != nil {
+		fmt.Printf("%s", tbuf.Bytes())
+		log.Fatalf("gofmt error: %v", err)
+	}
+	if err := os.WriteFile("asm9_gtables.go.new", tout, 0666); err != nil {
+		log.Fatalf("Failed to create asm9_gtables.new: %v", err)
+	}
+}
+
 // printASM implements the -fmt=asm mode.  This prints out a gnu assembler file
 // which can be used to used to generate test output to verify the golang
 // disassembler's gnu output matches gnu binutils. This is used as an input to
