func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config {
	c := &Config{arch: arch, fe: fe}
	switch arch {
	case "amd64":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockAMD64
		c.lowerValue = rewriteValueAMD64
		c.registers = registersAMD64[:]
		c.gpRegMask = gpRegMaskAMD64
		c.fpRegMask = fpRegMaskAMD64
		c.FPReg = framepointerRegAMD64
		c.hasGReg = false
	case "amd64p32":
		c.IntSize = 4
		c.PtrSize = 4
		c.lowerBlock = rewriteBlockAMD64
		c.lowerValue = rewriteValueAMD64
		c.registers = registersAMD64[:]
		c.gpRegMask = gpRegMaskAMD64
		c.fpRegMask = fpRegMaskAMD64
		c.FPReg = framepointerRegAMD64
		c.hasGReg = false
		c.noDuffDevice = true
	case "386":
		c.IntSize = 4
		c.PtrSize = 4
		c.lowerBlock = rewriteBlock386
		c.lowerValue = rewriteValue386
		c.registers = registers386[:]
		c.gpRegMask = gpRegMask386
		c.fpRegMask = fpRegMask386
		c.FPReg = framepointerReg386
		c.hasGReg = false
	case "arm":
		c.IntSize = 4
		c.PtrSize = 4
		c.lowerBlock = rewriteBlockARM
		c.lowerValue = rewriteValueARM
		c.registers = registersARM[:]
		c.gpRegMask = gpRegMaskARM
		c.fpRegMask = fpRegMaskARM
		c.FPReg = framepointerRegARM
		c.hasGReg = true
	case "arm64":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockARM64
		c.lowerValue = rewriteValueARM64
		c.registers = registersARM64[:]
		c.gpRegMask = gpRegMaskARM64
		c.fpRegMask = fpRegMaskARM64
		c.FPReg = framepointerRegARM64
		c.hasGReg = true
		c.noDuffDevice = obj.GOOS == "darwin" // darwin linker cannot handle BR26 reloc with non-zero addend
	case "ppc64":
		c.OldArch = true
		fallthrough
	case "ppc64le":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockPPC64
		c.lowerValue = rewriteValuePPC64
		c.registers = registersPPC64[:]
		c.gpRegMask = gpRegMaskPPC64
		c.fpRegMask = fpRegMaskPPC64
		c.FPReg = framepointerRegPPC64
		c.noDuffDevice = true // TODO: Resolve PPC64 DuffDevice (has zero, but not copy)
		c.NeedsFpScratch = true
		c.hasGReg = true
	case "mips64", "mips64le":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockMIPS64
		c.lowerValue = rewriteValueMIPS64
		c.registers = registersMIPS64[:]
		c.gpRegMask = gpRegMaskMIPS64
		c.fpRegMask = fpRegMaskMIPS64
		c.specialRegMask = specialRegMaskMIPS64
		c.FPReg = framepointerRegMIPS64
		c.hasGReg = true
	case "s390x":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockS390X
		c.lowerValue = rewriteValueS390X
		c.registers = registersS390X[:]
		c.gpRegMask = gpRegMaskS390X
		c.fpRegMask = fpRegMaskS390X
		c.FPReg = framepointerRegS390X
		c.hasGReg = true
		c.noDuffDevice = true
	default:
		fe.Fatalf(0, "arch %s not implemented", arch)
	}
	c.ctxt = ctxt
	c.optimize = optimize
	c.nacl = obj.GOOS == "nacl"

	// Don't use Duff's device on Plan 9 AMD64, because floating
	// point operations are not allowed in note handler.
	if obj.GOOS == "plan9" && arch == "amd64" {
		c.noDuffDevice = true
	}

	if c.nacl {
		c.noDuffDevice = true // Don't use Duff's device on NaCl

		// runtime call clobber R12 on nacl
		opcodeTable[OpARMUDIVrtcall].reg.clobbers |= 1 << 12 // R12
	}

	// Assign IDs to preallocated values/blocks.
	for i := range c.values {
		c.values[i].ID = ID(i)
	}
	for i := range c.blocks {
		c.blocks[i].ID = ID(i)
	}

	c.logfiles = make(map[string]*os.File)

	// cutoff is compared with product of numblocks and numvalues,
	// if product is smaller than cutoff, use old non-sparse method.
	// cutoff == 0 implies all sparse.
	// cutoff == -1 implies none sparse.
	// Good cutoff values seem to be O(million) depending on constant factor cost of sparse.
	// TODO: get this from a flag, not an environment variable
	c.sparsePhiCutoff = 2500000 // 0 for testing. // 2500000 determined with crude experiments w/ make.bash
	ev := os.Getenv("GO_SSA_PHI_LOC_CUTOFF")
	if ev != "" {
		v, err := strconv.ParseInt(ev, 10, 64)
		if err != nil {
			fe.Fatalf(0, "Environment variable GO_SSA_PHI_LOC_CUTOFF (value '%s') did not parse as a number", ev)
		}
		c.sparsePhiCutoff = uint64(v) // convert -1 to maxint, for never use sparse
	}

	return c
}
// NewConfig returns a new configuration object for the given architecture.
NewConfig returns a new configuration object for the given architecture.
// NewConfig returns a new configuration object for the given architecture .
func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config {
	c := &Config{arch: arch, fe: fe}
	switch arch {
	case "amd64":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockAMD64
		c.lowerValue = rewriteValueAMD64
		c.registers = registersAMD64[:]
		c.gpRegMask = gpRegMaskAMD64
		c.fpRegMask = fpRegMaskAMD64
		c.FPReg = framepointerRegAMD64
		c.hasGReg = false
	case "amd64p32":
		c.IntSize = 4
		c.PtrSize = 4
		c.lowerBlock = rewriteBlockAMD64
		c.lowerValue = rewriteValueAMD64
		c.registers = registersAMD64[:]
		c.gpRegMask = gpRegMaskAMD64
		c.fpRegMask = fpRegMaskAMD64
		c.FPReg = framepointerRegAMD64
		c.hasGReg = false
		c.noDuffDevice = true
	case "386":
		c.IntSize = 4
		c.PtrSize = 4
		c.lowerBlock = rewriteBlock386
		c.lowerValue = rewriteValue386
		c.registers = registers386[:]
		c.gpRegMask = gpRegMask386
		c.fpRegMask = fpRegMask386
		c.FPReg = framepointerReg386
		c.hasGReg = false
	case "arm":
		c.IntSize = 4
		c.PtrSize = 4
		c.lowerBlock = rewriteBlockARM
		c.lowerValue = rewriteValueARM
		c.registers = registersARM[:]
		c.gpRegMask = gpRegMaskARM
		c.fpRegMask = fpRegMaskARM
		c.FPReg = framepointerRegARM
		c.hasGReg = true
	case "arm64":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockARM64
		c.lowerValue = rewriteValueARM64
		c.registers = registersARM64[:]
		c.gpRegMask = gpRegMaskARM64
		c.fpRegMask = fpRegMaskARM64
		c.FPReg = framepointerRegARM64
		c.hasGReg = true
		c.noDuffDevice = obj.GOOS == "darwin" 
	case "ppc64":
		c.OldArch = true
		fallthrough
	case "ppc64le":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockPPC64
		c.lowerValue = rewriteValuePPC64
		c.registers = registersPPC64[:]
		c.gpRegMask = gpRegMaskPPC64
		c.fpRegMask = fpRegMaskPPC64
		c.FPReg = framepointerRegPPC64
		c.noDuffDevice = true 
		c.NeedsFpScratch = true
		c.hasGReg = true
	case "mips64", "mips64le":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockMIPS64
		c.lowerValue = rewriteValueMIPS64
		c.registers = registersMIPS64[:]
		c.gpRegMask = gpRegMaskMIPS64
		c.fpRegMask = fpRegMaskMIPS64
		c.specialRegMask = specialRegMaskMIPS64
		c.FPReg = framepointerRegMIPS64
		c.hasGReg = true
	case "s390x":
		c.IntSize = 8
		c.PtrSize = 8
		c.lowerBlock = rewriteBlockS390X
		c.lowerValue = rewriteValueS390X
		c.registers = registersS390X[:]
		c.gpRegMask = gpRegMaskS390X
		c.fpRegMask = fpRegMaskS390X
		c.FPReg = framepointerRegS390X
		c.hasGReg = true
		c.noDuffDevice = true
	default:
		fe.Fatalf(0, "arch %s not implemented", arch)
	}
	c.ctxt = ctxt
	c.optimize = optimize
	c.nacl = obj.GOOS == "nacl"
	if obj.GOOS == "plan9" && arch == "amd64" {
		c.noDuffDevice = true
	}
	if c.nacl {
		c.noDuffDevice = true 
		opcodeTable[OpARMUDIVrtcall].reg.clobbers |= 1 << 12 
	}
	for i := range c.values {
		c.values[i].ID = ID(i)
	}
	for i := range c.blocks {
		c.blocks[i].ID = ID(i)
	}
	c.logfiles = make(map[string]*os.File)
	c.sparsePhiCutoff = 2500000 
	ev := os.Getenv("GO_SSA_PHI_LOC_CUTOFF")
	if ev != "" {
		v, err := strconv.ParseInt(ev, 10, 64)
		if err != nil {
			fe.Fatalf(0, "Environment variable GO_SSA_PHI_LOC_CUTOFF (value '%s') did not parse as a number", ev)
		}
		c.sparsePhiCutoff = uint64(v) 
	}
	return c
}
func NewConfig ( arch string , fe Frontend , ctxt * obj . Link , optimize bool ) * Config { c := & Config { arch : arch , fe : fe } switch arch { case " " : c . IntSize = 8 c . PtrSize = 8 c . lowerBlock = rewriteBlockAMD64 c . lowerValue = rewriteValueAMD64 c . registers = registersAMD64 [ : ] c . gpRegMask = gpRegMaskAMD64 c . fpRegMask = fpRegMaskAMD64 c . FPReg = framepointerRegAMD64 c . hasGReg = false case " " : c . IntSize = 4 c . PtrSize = 4 c . lowerBlock = rewriteBlockAMD64 c . lowerValue = rewriteValueAMD64 c . registers = registersAMD64 [ : ] c . gpRegMask = gpRegMaskAMD64 c . fpRegMask = fpRegMaskAMD64 c . FPReg = framepointerRegAMD64 c . hasGReg = false c . noDuffDevice = true case " " : c . IntSize = 4 c . PtrSize = 4 c . lowerBlock = rewriteBlock386 c . lowerValue = rewriteValue386 c . registers = registers386 [ : ] c . gpRegMask = gpRegMask386 c . fpRegMask = fpRegMask386 c . FPReg = framepointerReg386 c . hasGReg = false case " " : c . IntSize = 4 c . PtrSize = 4 c . lowerBlock = rewriteBlockARM c . lowerValue = rewriteValueARM c . registers = registersARM [ : ] c . gpRegMask = gpRegMaskARM c . fpRegMask = fpRegMaskARM c . FPReg = framepointerRegARM c . hasGReg = true case " " : c . IntSize = 8 c . PtrSize = 8 c . lowerBlock = rewriteBlockARM64 c . lowerValue = rewriteValueARM64 c . registers = registersARM64 [ : ] c . gpRegMask = gpRegMaskARM64 c . fpRegMask = fpRegMaskARM64 c . FPReg = framepointerRegARM64 c . hasGReg = true c . noDuffDevice = obj . GOOS == " " case " " : c . OldArch = true fallthrough case " " : c . IntSize = 8 c . PtrSize = 8 c . lowerBlock = rewriteBlockPPC64 c . lowerValue = rewriteValuePPC64 c . registers = registersPPC64 [ : ] c . gpRegMask = gpRegMaskPPC64 c . fpRegMask = fpRegMaskPPC64 c . FPReg = framepointerRegPPC64 c . noDuffDevice = true c . NeedsFpScratch = true c . hasGReg = true case " " , " " : c . IntSize = 8 c . PtrSize = 8 c . lowerBlock = rewriteBlockMIPS64 c . lowerValue = rewriteValueMIPS64 c . registers = registersMIPS64 [ : ] c . gpRegMask = gpRegMaskMIPS64 c . fpRegMask = fpRegMaskMIPS64 c . specialRegMask = specialRegMaskMIPS64 c . FPReg = framepointerRegMIPS64 c . hasGReg = true case " " : c . IntSize = 8 c . PtrSize = 8 c . lowerBlock = rewriteBlockS390X c . lowerValue = rewriteValueS390X c . registers = registersS390X [ : ] c . gpRegMask = gpRegMaskS390X c . fpRegMask = fpRegMaskS390X c . FPReg = framepointerRegS390X c . hasGReg = true c . noDuffDevice = true default : fe . Fatalf ( 0 , " " , arch ) } c . ctxt = ctxt c . optimize = optimize c . nacl = obj . GOOS == " " if obj . GOOS == " " && arch == " " { c . noDuffDevice = true } if c . nacl { c . noDuffDevice = true opcodeTable [ OpARMUDIVrtcall ] . reg . clobbers |= 1 << 12 } for i := range c . values { c . values [ i ] . ID = ID ( i ) } for i := range c . blocks { c . blocks [ i ] . ID = ID ( i ) } c . logfiles = make ( map [ string ] * os . File ) c . sparsePhiCutoff = 2500000 ev := os . Getenv ( " " ) if ev != " " { v , err := strconv . ParseInt ( ev , 10 , 64 ) if err != nil { fe . Fatalf ( 0 , " " , ev ) } c . sparsePhiCutoff = uint64 ( v ) } return c }
NewConfig returns a new configuration object for the given architecture.
NewConfig returns a new configuration object for the given architecture .
// darwin linker cannot handle BR26 reloc with non-zero addend // TODO: Resolve PPC64 DuffDevice (has zero, but not copy) // Don't use Duff's device on Plan 9 AMD64, because floating // point operations are not allowed in note handler. // Don't use Duff's device on NaCl // runtime call clobber R12 on nacl // R12 // Assign IDs to preallocated values/blocks. // cutoff is compared with product of numblocks and numvalues, // if product is smaller than cutoff, use old non-sparse method. // cutoff == 0 implies all sparse. // cutoff == -1 implies none sparse. // Good cutoff values seem to be O(million) depending on constant factor cost of sparse. // TODO: get this from a flag, not an environment variable // 0 for testing. // 2500000 determined with crude experiments w/ make.bash // convert -1 to maxint, for never use sparse