mirror of https://github.com/golang/go.git
[dev.ssa] cmd/compile: refactor out rulegen value parsing
Previously, genMatch0 and genResult0 contained lots of duplication: locating the op, parsing the value, validation, etc. Parsing and validation was mixed in with code gen. Extract a helper, parseValue. It is responsible for parsing the value, locating the op, and doing shared validation. As a bonus (and possibly as my original motivation), make op selection pay attention to the number of args present. This allows arch-specific ops to share a name with generic ops as long as there is no ambiguity. It also detects and reports unresolved ambiguity, unlike before, where it would simply always pick the generic op, with no warning. Also use parseValue when generating the top-level op dispatch, to ensure its opinion about ops matches genMatch0 and genResult0. The order of statements in the generated code used to depend on the exact rule. It is now somewhat independent of the rule. That is the source of some of the generated code changes in this CL. See rewritedec64 and rewritegeneric for examples. It is a one-time change. The op dispatch switch and functions used to be sorted by opname without architecture. The sort now includes the architecture, leading to further generated code changes. See rewriteARM and rewriteAMD64 for examples. Again, it is a one-time change. There are no functional changes. Change-Id: I22c989183ad5651741ebdc0566349c5fd6c6b23c Reviewed-on: https://go-review.googlesource.com/24649 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
dede2061f3
commit
6a1153acb4
|
|
@ -117,15 +117,17 @@ func genRules(arch arch) {
|
|||
if unbalanced(rule) {
|
||||
continue
|
||||
}
|
||||
op := strings.Split(rule, " ")[0][1:]
|
||||
if op[len(op)-1] == ')' {
|
||||
op = op[:len(op)-1] // rule has only opcode, e.g. (ConstNil) -> ...
|
||||
}
|
||||
|
||||
loc := fmt.Sprintf("%s.rules:%d", arch.name, ruleLineno)
|
||||
if isBlock(op, arch) {
|
||||
blockrules[op] = append(blockrules[op], Rule{rule: rule, loc: loc})
|
||||
r := Rule{rule: rule, loc: loc}
|
||||
if rawop := strings.Split(rule, " ")[0][1:]; isBlock(rawop, arch) {
|
||||
blockrules[rawop] = append(blockrules[rawop], r)
|
||||
} else {
|
||||
oprules[op] = append(oprules[op], Rule{rule: rule, loc: loc})
|
||||
// Do fancier value op matching.
|
||||
match, _, _ := r.parse()
|
||||
op, oparch, _, _, _, _ := parseValue(match, arch, loc)
|
||||
opname := fmt.Sprintf("Op%s%s", oparch, op.name)
|
||||
oprules[opname] = append(oprules[opname], r)
|
||||
}
|
||||
rule = ""
|
||||
ruleLineno = 0
|
||||
|
|
@ -157,8 +159,8 @@ func genRules(arch arch) {
|
|||
fmt.Fprintf(w, "func rewriteValue%s(v *Value, config *Config) bool {\n", arch.name)
|
||||
fmt.Fprintf(w, "switch v.Op {\n")
|
||||
for _, op := range ops {
|
||||
fmt.Fprintf(w, "case %s:\n", opName(op, arch))
|
||||
fmt.Fprintf(w, "return rewriteValue%s_%s(v, config)\n", arch.name, opName(op, arch))
|
||||
fmt.Fprintf(w, "case %s:\n", op)
|
||||
fmt.Fprintf(w, "return rewriteValue%s_%s(v, config)\n", arch.name, op)
|
||||
}
|
||||
fmt.Fprintf(w, "}\n")
|
||||
fmt.Fprintf(w, "return false\n")
|
||||
|
|
@ -167,7 +169,7 @@ func genRules(arch arch) {
|
|||
// Generate a routine per op. Note that we don't make one giant routine
|
||||
// because it is too big for some compilers.
|
||||
for _, op := range ops {
|
||||
fmt.Fprintf(w, "func rewriteValue%s_%s(v *Value, config *Config) bool {\n", arch.name, opName(op, arch))
|
||||
fmt.Fprintf(w, "func rewriteValue%s_%s(v *Value, config *Config) bool {\n", arch.name, op)
|
||||
fmt.Fprintln(w, "b := v.Block")
|
||||
fmt.Fprintln(w, "_ = b")
|
||||
var canFail bool
|
||||
|
|
@ -334,141 +336,108 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]struct{}, t
|
|||
}
|
||||
canFail := false
|
||||
|
||||
// split body up into regions. Split by spaces/tabs, except those
|
||||
// contained in () or {}.
|
||||
s := split(match[1 : len(match)-1]) // remove parens, then split
|
||||
|
||||
// Find op record
|
||||
var op opData
|
||||
for _, x := range genericOps {
|
||||
if x.name == s[0] {
|
||||
op = x
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, x := range arch.ops {
|
||||
if x.name == s[0] {
|
||||
op = x
|
||||
break
|
||||
}
|
||||
}
|
||||
if op.name == "" {
|
||||
log.Fatalf("%s: unknown op %s", loc, s[0])
|
||||
}
|
||||
op, oparch, typ, auxint, aux, args := parseValue(match, arch, loc)
|
||||
|
||||
// check op
|
||||
if !top {
|
||||
fmt.Fprintf(w, "if %s.Op != %s {\nbreak\n}\n", v, opName(s[0], arch))
|
||||
fmt.Fprintf(w, "if %s.Op != Op%s%s {\nbreak\n}\n", v, oparch, op.name)
|
||||
canFail = true
|
||||
}
|
||||
|
||||
// check type/aux/args
|
||||
argnum := 0
|
||||
for _, a := range s[1:] {
|
||||
if a[0] == '<' {
|
||||
// type restriction
|
||||
t := a[1 : len(a)-1] // remove <>
|
||||
if !isVariable(t) {
|
||||
// code. We must match the results of this code.
|
||||
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
|
||||
if typ != "" {
|
||||
if !isVariable(typ) {
|
||||
// code. We must match the results of this code.
|
||||
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, typ)
|
||||
canFail = true
|
||||
} else {
|
||||
// variable
|
||||
if _, ok := m[typ]; ok {
|
||||
// must match previous variable
|
||||
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, typ)
|
||||
canFail = true
|
||||
} else {
|
||||
// variable
|
||||
if _, ok := m[t]; ok {
|
||||
// must match previous variable
|
||||
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
|
||||
canFail = true
|
||||
} else {
|
||||
m[t] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.Type\n", t, v)
|
||||
}
|
||||
m[typ] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.Type\n", typ, v)
|
||||
}
|
||||
} else if a[0] == '[' {
|
||||
// auxint restriction
|
||||
switch op.aux {
|
||||
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64", "SymOff", "SymValAndOff", "SymInt32":
|
||||
default:
|
||||
log.Fatalf("%s: op %s %s can't have auxint", loc, op.name, op.aux)
|
||||
}
|
||||
x := a[1 : len(a)-1] // remove []
|
||||
if !isVariable(x) {
|
||||
// code
|
||||
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
|
||||
}
|
||||
}
|
||||
|
||||
if auxint != "" {
|
||||
if !isVariable(auxint) {
|
||||
// code
|
||||
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, auxint)
|
||||
canFail = true
|
||||
} else {
|
||||
// variable
|
||||
if _, ok := m[auxint]; ok {
|
||||
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, auxint)
|
||||
canFail = true
|
||||
} else {
|
||||
// variable
|
||||
if _, ok := m[x]; ok {
|
||||
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
|
||||
canFail = true
|
||||
} else {
|
||||
m[x] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.AuxInt\n", x, v)
|
||||
}
|
||||
m[auxint] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.AuxInt\n", auxint, v)
|
||||
}
|
||||
} else if a[0] == '{' {
|
||||
// aux restriction
|
||||
switch op.aux {
|
||||
case "String", "Sym", "SymOff", "SymValAndOff", "SymInt32":
|
||||
default:
|
||||
log.Fatalf("%s: op %s %s can't have aux", loc, op.name, op.aux)
|
||||
}
|
||||
x := a[1 : len(a)-1] // remove {}
|
||||
if !isVariable(x) {
|
||||
// code
|
||||
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
|
||||
}
|
||||
}
|
||||
|
||||
if aux != "" {
|
||||
|
||||
if !isVariable(aux) {
|
||||
// code
|
||||
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, aux)
|
||||
canFail = true
|
||||
} else {
|
||||
// variable
|
||||
if _, ok := m[aux]; ok {
|
||||
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, aux)
|
||||
canFail = true
|
||||
} else {
|
||||
// variable
|
||||
if _, ok := m[x]; ok {
|
||||
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
|
||||
canFail = true
|
||||
} else {
|
||||
m[x] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.Aux\n", x, v)
|
||||
}
|
||||
m[aux] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.Aux\n", aux, v)
|
||||
}
|
||||
} else if a == "_" {
|
||||
argnum++
|
||||
} else if !strings.Contains(a, "(") {
|
||||
}
|
||||
}
|
||||
|
||||
for i, arg := range args {
|
||||
if arg == "_" {
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(arg, "(") {
|
||||
// leaf variable
|
||||
if _, ok := m[a]; ok {
|
||||
if _, ok := m[arg]; ok {
|
||||
// variable already has a definition. Check whether
|
||||
// the old definition and the new definition match.
|
||||
// For example, (add x x). Equality is just pointer equality
|
||||
// on Values (so cse is important to do before lowering).
|
||||
fmt.Fprintf(w, "if %s != %s.Args[%d] {\nbreak\n}\n", a, v, argnum)
|
||||
fmt.Fprintf(w, "if %s != %s.Args[%d] {\nbreak\n}\n", arg, v, i)
|
||||
canFail = true
|
||||
} else {
|
||||
// remember that this variable references the given value
|
||||
m[a] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.Args[%d]\n", a, v, argnum)
|
||||
m[arg] = struct{}{}
|
||||
fmt.Fprintf(w, "%s := %s.Args[%d]\n", arg, v, i)
|
||||
}
|
||||
argnum++
|
||||
continue
|
||||
}
|
||||
// compound sexpr
|
||||
var argname string
|
||||
colon := strings.Index(arg, ":")
|
||||
openparen := strings.Index(arg, "(")
|
||||
if colon >= 0 && openparen >= 0 && colon < openparen {
|
||||
// rule-specified name
|
||||
argname = arg[:colon]
|
||||
arg = arg[colon+1:]
|
||||
} else {
|
||||
// compound sexpr
|
||||
var argname string
|
||||
colon := strings.Index(a, ":")
|
||||
openparen := strings.Index(a, "(")
|
||||
if colon >= 0 && openparen >= 0 && colon < openparen {
|
||||
// rule-specified name
|
||||
argname = a[:colon]
|
||||
a = a[colon+1:]
|
||||
} else {
|
||||
// autogenerated name
|
||||
argname = fmt.Sprintf("%s_%d", v, argnum)
|
||||
}
|
||||
fmt.Fprintf(w, "%s := %s.Args[%d]\n", argname, v, argnum)
|
||||
if genMatch0(w, arch, a, argname, m, false, loc) {
|
||||
canFail = true
|
||||
}
|
||||
argnum++
|
||||
// autogenerated name
|
||||
argname = fmt.Sprintf("%s_%d", v, i)
|
||||
}
|
||||
fmt.Fprintf(w, "%s := %s.Args[%d]\n", argname, v, i)
|
||||
if genMatch0(w, arch, arg, argname, m, false, loc) {
|
||||
canFail = true
|
||||
}
|
||||
}
|
||||
|
||||
if op.argLength == -1 {
|
||||
fmt.Fprintf(w, "if len(%s.Args) != %d {\nbreak\n}\n", v, argnum)
|
||||
fmt.Fprintf(w, "if len(%s.Args) != %d {\nbreak\n}\n", v, len(args))
|
||||
canFail = true
|
||||
} else if int(op.argLength) != argnum {
|
||||
log.Fatalf("%s: op %s should have %d args, has %d", loc, op.name, op.argLength, argnum)
|
||||
}
|
||||
return canFail
|
||||
}
|
||||
|
|
@ -500,105 +469,44 @@ func genResult0(w io.Writer, arch arch, result string, alloc *int, top, move boo
|
|||
return result
|
||||
}
|
||||
|
||||
s := split(result[1 : len(result)-1]) // remove parens, then split
|
||||
|
||||
// Find op record
|
||||
var op opData
|
||||
for _, x := range genericOps {
|
||||
if x.name == s[0] {
|
||||
op = x
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, x := range arch.ops {
|
||||
if x.name == s[0] {
|
||||
op = x
|
||||
break
|
||||
}
|
||||
}
|
||||
if op.name == "" {
|
||||
log.Fatalf("%s: unknown op %s", loc, s[0])
|
||||
}
|
||||
op, oparch, typ, auxint, aux, args := parseValue(result, arch, loc)
|
||||
|
||||
// Find the type of the variable.
|
||||
var opType string
|
||||
var typeOverride bool
|
||||
for _, a := range s[1:] {
|
||||
if a[0] == '<' {
|
||||
// type restriction
|
||||
opType = a[1 : len(a)-1] // remove <>
|
||||
typeOverride = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if opType == "" {
|
||||
// find default type, if any
|
||||
for _, op := range arch.ops {
|
||||
if op.name == s[0] && op.typ != "" {
|
||||
opType = typeName(op.typ)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if opType == "" {
|
||||
for _, op := range genericOps {
|
||||
if op.name == s[0] && op.typ != "" {
|
||||
opType = typeName(op.typ)
|
||||
break
|
||||
}
|
||||
}
|
||||
typeOverride := typ != ""
|
||||
if typ == "" && op.typ != "" {
|
||||
typ = typeName(op.typ)
|
||||
}
|
||||
|
||||
var v string
|
||||
if top && !move {
|
||||
v = "v"
|
||||
fmt.Fprintf(w, "v.reset(%s)\n", opName(s[0], arch))
|
||||
fmt.Fprintf(w, "v.reset(Op%s%s)\n", oparch, op.name)
|
||||
if typeOverride {
|
||||
fmt.Fprintf(w, "v.Type = %s\n", opType)
|
||||
fmt.Fprintf(w, "v.Type = %s\n", typ)
|
||||
}
|
||||
} else {
|
||||
if opType == "" {
|
||||
log.Fatalf("sub-expression %s (op=%s) must have a type", result, s[0])
|
||||
if typ == "" {
|
||||
log.Fatalf("sub-expression %s (op=Op%s%s) must have a type", result, oparch, op.name)
|
||||
}
|
||||
v = fmt.Sprintf("v%d", *alloc)
|
||||
*alloc++
|
||||
fmt.Fprintf(w, "%s := b.NewValue0(v.Line, %s, %s)\n", v, opName(s[0], arch), opType)
|
||||
fmt.Fprintf(w, "%s := b.NewValue0(v.Line, Op%s%s, %s)\n", v, oparch, op.name, typ)
|
||||
if move && top {
|
||||
// Rewrite original into a copy
|
||||
fmt.Fprintf(w, "v.reset(OpCopy)\n")
|
||||
fmt.Fprintf(w, "v.AddArg(%s)\n", v)
|
||||
}
|
||||
}
|
||||
argnum := 0
|
||||
for _, a := range s[1:] {
|
||||
if a[0] == '<' {
|
||||
// type restriction, handled above
|
||||
} else if a[0] == '[' {
|
||||
// auxint restriction
|
||||
switch op.aux {
|
||||
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64", "SymOff", "SymValAndOff", "SymInt32":
|
||||
default:
|
||||
log.Fatalf("%s: op %s %s can't have auxint", loc, op.name, op.aux)
|
||||
}
|
||||
x := a[1 : len(a)-1] // remove []
|
||||
fmt.Fprintf(w, "%s.AuxInt = %s\n", v, x)
|
||||
} else if a[0] == '{' {
|
||||
// aux restriction
|
||||
switch op.aux {
|
||||
case "String", "Sym", "SymOff", "SymValAndOff", "SymInt32":
|
||||
default:
|
||||
log.Fatalf("%s: op %s %s can't have aux", loc, op.name, op.aux)
|
||||
}
|
||||
x := a[1 : len(a)-1] // remove {}
|
||||
fmt.Fprintf(w, "%s.Aux = %s\n", v, x)
|
||||
} else {
|
||||
// regular argument (sexpr or variable)
|
||||
x := genResult0(w, arch, a, alloc, false, move, loc)
|
||||
fmt.Fprintf(w, "%s.AddArg(%s)\n", v, x)
|
||||
argnum++
|
||||
}
|
||||
|
||||
if auxint != "" {
|
||||
fmt.Fprintf(w, "%s.AuxInt = %s\n", v, auxint)
|
||||
}
|
||||
if op.argLength != -1 && int(op.argLength) != argnum {
|
||||
log.Fatalf("%s: op %s should have %d args, has %d", loc, op.name, op.argLength, argnum)
|
||||
if aux != "" {
|
||||
fmt.Fprintf(w, "%s.Aux = %s\n", v, aux)
|
||||
}
|
||||
for _, arg := range args {
|
||||
x := genResult0(w, arch, arg, alloc, false, move, loc)
|
||||
fmt.Fprintf(w, "%s.AddArg(%s)\n", v, x)
|
||||
}
|
||||
|
||||
return v
|
||||
|
|
@ -666,16 +574,102 @@ func isBlock(name string, arch arch) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// opName converts from an op name specified in a rule file to an Op enum.
|
||||
// if the name matches a generic op, returns "Op" plus the specified name.
|
||||
// Otherwise, returns "Op" plus arch name plus op name.
|
||||
func opName(name string, arch arch) string {
|
||||
for _, op := range genericOps {
|
||||
if op.name == name {
|
||||
return "Op" + name
|
||||
// parseValue parses a parenthesized value from a rule.
|
||||
// The value can be from the match or the result side.
|
||||
// It returns the op and unparsed strings for typ, auxint, and aux restrictions and for all args.
|
||||
// oparch is the architecture that op is located in, or "" for generic.
|
||||
func parseValue(val string, arch arch, loc string) (op opData, oparch string, typ string, auxint string, aux string, args []string) {
|
||||
val = val[1 : len(val)-1] // remove ()
|
||||
|
||||
// Split val up into regions.
|
||||
// Split by spaces/tabs, except those contained in (), {}, [], or <>.
|
||||
s := split(val)
|
||||
|
||||
// Extract restrictions and args.
|
||||
for _, a := range s[1:] {
|
||||
switch a[0] {
|
||||
case '<':
|
||||
typ = a[1 : len(a)-1] // remove <>
|
||||
case '[':
|
||||
auxint = a[1 : len(a)-1] // remove []
|
||||
case '{':
|
||||
aux = a[1 : len(a)-1] // remove {}
|
||||
default:
|
||||
args = append(args, a)
|
||||
}
|
||||
}
|
||||
return "Op" + arch.name + name
|
||||
|
||||
// Resolve the op.
|
||||
|
||||
// match reports whether x is a good op to select.
|
||||
// If strict is true, rule generation might succeed.
|
||||
// If strict is false, rule generation has failed,
|
||||
// but we're trying to generate a useful error.
|
||||
// Doing strict=true then strict=false allows
|
||||
// precise op matching while retaining good error messages.
|
||||
match := func(x opData, strict bool, archname string) bool {
|
||||
if x.name != s[0] {
|
||||
return false
|
||||
}
|
||||
if x.argLength != -1 && int(x.argLength) != len(args) {
|
||||
if strict {
|
||||
return false
|
||||
} else {
|
||||
log.Printf("%s: op %s (%s) should have %d args, has %d", loc, s[0], archname, op.argLength, len(args))
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
for _, x := range genericOps {
|
||||
if match(x, true, "generic") {
|
||||
op = x
|
||||
break
|
||||
}
|
||||
}
|
||||
if arch.name != "generic" {
|
||||
for _, x := range arch.ops {
|
||||
if match(x, true, arch.name) {
|
||||
if op.name != "" {
|
||||
log.Fatalf("%s: matches for op %s found in both generic and %s", loc, op.name, arch.name)
|
||||
}
|
||||
op = x
|
||||
oparch = arch.name
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if op.name == "" {
|
||||
// Failed to find the op.
|
||||
// Run through everything again with strict=false
|
||||
// to generate useful diagnosic messages before failing.
|
||||
for _, x := range genericOps {
|
||||
match(x, false, "generic")
|
||||
}
|
||||
for _, x := range arch.ops {
|
||||
match(x, false, arch.name)
|
||||
}
|
||||
log.Fatalf("%s: unknown op %s", loc, s)
|
||||
}
|
||||
|
||||
// Sanity check aux, auxint.
|
||||
if auxint != "" {
|
||||
switch op.aux {
|
||||
case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64", "SymOff", "SymValAndOff", "SymInt32":
|
||||
default:
|
||||
log.Fatalf("%s: op %s %s can't have auxint", loc, op.name, op.aux)
|
||||
}
|
||||
}
|
||||
if aux != "" {
|
||||
switch op.aux {
|
||||
case "String", "Sym", "SymOff", "SymValAndOff", "SymInt32":
|
||||
default:
|
||||
log.Fatalf("%s: op %s %s can't have aux", loc, op.name, op.aux)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func blockName(name string, arch arch) string {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -8,8 +8,6 @@ import "math"
|
|||
var _ = math.MinInt8 // in case not otherwise used
|
||||
func rewriteValuePPC64(v *Value, config *Config) bool {
|
||||
switch v.Op {
|
||||
case OpPPC64ADD:
|
||||
return rewriteValuePPC64_OpPPC64ADD(v, config)
|
||||
case OpAdd16:
|
||||
return rewriteValuePPC64_OpAdd16(v, config)
|
||||
case OpAdd32:
|
||||
|
|
@ -154,22 +152,6 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
|
|||
return rewriteValuePPC64_OpLess8U(v, config)
|
||||
case OpLoad:
|
||||
return rewriteValuePPC64_OpLoad(v, config)
|
||||
case OpPPC64MOVBstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVBstore(v, config)
|
||||
case OpPPC64MOVBstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVBstorezero(v, config)
|
||||
case OpPPC64MOVDstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVDstore(v, config)
|
||||
case OpPPC64MOVDstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVDstorezero(v, config)
|
||||
case OpPPC64MOVHstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVHstore(v, config)
|
||||
case OpPPC64MOVHstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVHstorezero(v, config)
|
||||
case OpPPC64MOVWstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVWstore(v, config)
|
||||
case OpPPC64MOVWstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVWstorezero(v, config)
|
||||
case OpMove:
|
||||
return rewriteValuePPC64_OpMove(v, config)
|
||||
case OpMul16:
|
||||
|
|
@ -216,6 +198,24 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
|
|||
return rewriteValuePPC64_OpOr64(v, config)
|
||||
case OpOr8:
|
||||
return rewriteValuePPC64_OpOr8(v, config)
|
||||
case OpPPC64ADD:
|
||||
return rewriteValuePPC64_OpPPC64ADD(v, config)
|
||||
case OpPPC64MOVBstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVBstore(v, config)
|
||||
case OpPPC64MOVBstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVBstorezero(v, config)
|
||||
case OpPPC64MOVDstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVDstore(v, config)
|
||||
case OpPPC64MOVDstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVDstorezero(v, config)
|
||||
case OpPPC64MOVHstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVHstore(v, config)
|
||||
case OpPPC64MOVHstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVHstorezero(v, config)
|
||||
case OpPPC64MOVWstore:
|
||||
return rewriteValuePPC64_OpPPC64MOVWstore(v, config)
|
||||
case OpPPC64MOVWstorezero:
|
||||
return rewriteValuePPC64_OpPPC64MOVWstorezero(v, config)
|
||||
case OpSignExt16to32:
|
||||
return rewriteValuePPC64_OpSignExt16to32(v, config)
|
||||
case OpSignExt16to64:
|
||||
|
|
@ -283,41 +283,6 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64ADD(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (ADD (MOVDconst [c]) x)
|
||||
// cond:
|
||||
// result: (ADDconst [c] x)
|
||||
for {
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_0.AuxInt
|
||||
x := v.Args[1]
|
||||
v.reset(OpPPC64ADDconst)
|
||||
v.AuxInt = c
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ADD x (MOVDconst [c]))
|
||||
// cond:
|
||||
// result: (ADDconst [c] x)
|
||||
for {
|
||||
x := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
v.reset(OpPPC64ADDconst)
|
||||
v.AuxInt = c
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpAdd16(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
|
|
@ -1691,330 +1656,6 @@ func rewriteValuePPC64_OpLoad(v *Value, config *Config) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVBstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVBstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVBstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVBstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVDstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVDstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVDstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVDstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVHstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVHstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVHstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVHstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVWstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVWstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVWstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpMove(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
|
|
@ -2347,8 +1988,8 @@ func rewriteValuePPC64_OpMove(v *Value, config *Config) bool {
|
|||
v.AddArg(dst)
|
||||
v.AddArg(src)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64ADDconst, src.Type)
|
||||
v0.AddArg(src)
|
||||
v0.AuxInt = SizeAndAlign(s).Size() - moveSize(SizeAndAlign(s).Align(), config)
|
||||
v0.AddArg(src)
|
||||
v.AddArg(v0)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
|
|
@ -2725,6 +2366,365 @@ func rewriteValuePPC64_OpOr8(v *Value, config *Config) bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64ADD(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (ADD (MOVDconst [c]) x)
|
||||
// cond:
|
||||
// result: (ADDconst [c] x)
|
||||
for {
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_0.AuxInt
|
||||
x := v.Args[1]
|
||||
v.reset(OpPPC64ADDconst)
|
||||
v.AuxInt = c
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
// match: (ADD x (MOVDconst [c]))
|
||||
// cond:
|
||||
// result: (ADDconst [c] x)
|
||||
for {
|
||||
x := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
v.reset(OpPPC64ADDconst)
|
||||
v.AuxInt = c
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVBstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVBstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVBstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVBstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVBstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVBstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVBstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVDstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVDstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVDstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVDstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVDstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVHstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVHstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVHstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVHstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVHstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVHstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVHstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWstore [off1] {sym} (ADDconst [off2] x) val mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVWstore [off1+off2] {sym} x val mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
val := v.Args[1]
|
||||
mem := v.Args[2]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstore)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(val)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem)
|
||||
// cond: c == 0
|
||||
// result: (MOVWstorezero [off] {sym} ptr mem)
|
||||
for {
|
||||
off := v.AuxInt
|
||||
sym := v.Aux
|
||||
ptr := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
if v_1.Op != OpPPC64MOVDconst {
|
||||
break
|
||||
}
|
||||
c := v_1.AuxInt
|
||||
mem := v.Args[2]
|
||||
if !(c == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstorezero)
|
||||
v.AuxInt = off
|
||||
v.Aux = sym
|
||||
v.AddArg(ptr)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (MOVWstorezero [off1] {sym} (ADDconst [off2] x) mem)
|
||||
// cond: is16Bit(off1+off2)
|
||||
// result: (MOVWstorezero [off1+off2] {sym} x mem)
|
||||
for {
|
||||
off1 := v.AuxInt
|
||||
sym := v.Aux
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpPPC64ADDconst {
|
||||
break
|
||||
}
|
||||
off2 := v_0.AuxInt
|
||||
x := v_0.Args[0]
|
||||
mem := v.Args[1]
|
||||
if !(is16Bit(off1 + off2)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpPPC64MOVWstorezero)
|
||||
v.AuxInt = off1 + off2
|
||||
v.Aux = sym
|
||||
v.AddArg(x)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuePPC64_OpSignExt16to32(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
|
|
@ -3456,8 +3456,8 @@ func rewriteValuePPC64_OpZero(v *Value, config *Config) bool {
|
|||
v.AuxInt = SizeAndAlign(s).Align()
|
||||
v.AddArg(ptr)
|
||||
v0 := b.NewValue0(v.Line, OpPPC64ADDconst, ptr.Type)
|
||||
v0.AddArg(ptr)
|
||||
v0.AuxInt = SizeAndAlign(s).Size() - moveSize(SizeAndAlign(s).Align(), config)
|
||||
v0.AddArg(ptr)
|
||||
v.AddArg(v0)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -198,19 +198,19 @@ func rewriteValuedec64_OpArg(v *Value, config *Config) bool {
|
|||
// cond: is64BitInt(v.Type) && v.Type.IsSigned()
|
||||
// result: (Int64Make (Arg <config.fe.TypeInt32()> {n} [off+4]) (Arg <config.fe.TypeUInt32()> {n} [off]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(is64BitInt(v.Type) && v.Type.IsSigned()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpInt64Make)
|
||||
v0 := b.NewValue0(v.Line, OpArg, config.fe.TypeInt32())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off + 4
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeUInt32())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -218,19 +218,19 @@ func rewriteValuedec64_OpArg(v *Value, config *Config) bool {
|
|||
// cond: is64BitInt(v.Type) && !v.Type.IsSigned()
|
||||
// result: (Int64Make (Arg <config.fe.TypeUInt32()> {n} [off+4]) (Arg <config.fe.TypeUInt32()> {n} [off]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(is64BitInt(v.Type) && !v.Type.IsSigned()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpInt64Make)
|
||||
v0 := b.NewValue0(v.Line, OpArg, config.fe.TypeUInt32())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off + 4
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeUInt32())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -738,13 +738,13 @@ func rewriteValuedec64_OpLrot64(v *Value, config *Config) bool {
|
|||
// cond: c <= 32
|
||||
// result: (Int64Make (Or32 <config.fe.TypeUInt32()> (Lsh32x32 <config.fe.TypeUInt32()> hi (Const32 <config.fe.TypeUInt32()> [c])) (Rsh32Ux32 <config.fe.TypeUInt32()> lo (Const32 <config.fe.TypeUInt32()> [32-c]))) (Or32 <config.fe.TypeUInt32()> (Lsh32x32 <config.fe.TypeUInt32()> lo (Const32 <config.fe.TypeUInt32()> [c])) (Rsh32Ux32 <config.fe.TypeUInt32()> hi (Const32 <config.fe.TypeUInt32()> [32-c]))))
|
||||
for {
|
||||
c := v.AuxInt
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpInt64Make {
|
||||
break
|
||||
}
|
||||
hi := v_0.Args[0]
|
||||
lo := v_0.Args[1]
|
||||
c := v.AuxInt
|
||||
if !(c <= 32) {
|
||||
break
|
||||
}
|
||||
|
|
@ -783,22 +783,22 @@ func rewriteValuedec64_OpLrot64(v *Value, config *Config) bool {
|
|||
// cond: c > 32
|
||||
// result: (Lrot64 (Int64Make lo hi) [c-32])
|
||||
for {
|
||||
c := v.AuxInt
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpInt64Make {
|
||||
break
|
||||
}
|
||||
hi := v_0.Args[0]
|
||||
lo := v_0.Args[1]
|
||||
c := v.AuxInt
|
||||
if !(c > 32) {
|
||||
break
|
||||
}
|
||||
v.reset(OpLrot64)
|
||||
v.AuxInt = c - 32
|
||||
v0 := b.NewValue0(v.Line, OpInt64Make, config.fe.TypeUInt64())
|
||||
v0.AddArg(lo)
|
||||
v0.AddArg(hi)
|
||||
v.AddArg(v0)
|
||||
v.AuxInt = c - 32
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -733,8 +733,8 @@ func rewriteValuegeneric_OpAddPtr(v *Value, config *Config) bool {
|
|||
c := v_1.AuxInt
|
||||
v.reset(OpOffPtr)
|
||||
v.Type = t
|
||||
v.AddArg(x)
|
||||
v.AuxInt = c
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -1370,19 +1370,19 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// cond: v.Type.IsString()
|
||||
// result: (StringMake (Arg <config.fe.TypeBytePtr()> {n} [off]) (Arg <config.fe.TypeInt()> {n} [off+config.PtrSize]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(v.Type.IsString()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStringMake)
|
||||
v0 := b.NewValue0(v.Line, OpArg, config.fe.TypeBytePtr())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeInt())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + config.PtrSize
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1390,23 +1390,23 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// cond: v.Type.IsSlice()
|
||||
// result: (SliceMake (Arg <v.Type.ElemType().PtrTo()> {n} [off]) (Arg <config.fe.TypeInt()> {n} [off+config.PtrSize]) (Arg <config.fe.TypeInt()> {n} [off+2*config.PtrSize]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(v.Type.IsSlice()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpSliceMake)
|
||||
v0 := b.NewValue0(v.Line, OpArg, v.Type.ElemType().PtrTo())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeInt())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + config.PtrSize
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
v2 := b.NewValue0(v.Line, OpArg, config.fe.TypeInt())
|
||||
v2.Aux = n
|
||||
v2.AuxInt = off + 2*config.PtrSize
|
||||
v2.Aux = n
|
||||
v.AddArg(v2)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1414,19 +1414,19 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// cond: v.Type.IsInterface()
|
||||
// result: (IMake (Arg <config.fe.TypeBytePtr()> {n} [off]) (Arg <config.fe.TypeBytePtr()> {n} [off+config.PtrSize]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(v.Type.IsInterface()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpIMake)
|
||||
v0 := b.NewValue0(v.Line, OpArg, config.fe.TypeBytePtr())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeBytePtr())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + config.PtrSize
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1434,19 +1434,19 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// cond: v.Type.IsComplex() && v.Type.Size() == 16
|
||||
// result: (ComplexMake (Arg <config.fe.TypeFloat64()> {n} [off]) (Arg <config.fe.TypeFloat64()> {n} [off+8]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(v.Type.IsComplex() && v.Type.Size() == 16) {
|
||||
break
|
||||
}
|
||||
v.reset(OpComplexMake)
|
||||
v0 := b.NewValue0(v.Line, OpArg, config.fe.TypeFloat64())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeFloat64())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + 8
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1454,19 +1454,19 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// cond: v.Type.IsComplex() && v.Type.Size() == 8
|
||||
// result: (ComplexMake (Arg <config.fe.TypeFloat32()> {n} [off]) (Arg <config.fe.TypeFloat32()> {n} [off+4]))
|
||||
for {
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(v.Type.IsComplex() && v.Type.Size() == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpComplexMake)
|
||||
v0 := b.NewValue0(v.Line, OpArg, config.fe.TypeFloat32())
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, config.fe.TypeFloat32())
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + 4
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1486,15 +1486,15 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// result: (StructMake1 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]))
|
||||
for {
|
||||
t := v.Type
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake1)
|
||||
v0 := b.NewValue0(v.Line, OpArg, t.FieldType(0))
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off + t.FieldOff(0)
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1503,19 +1503,19 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// result: (StructMake2 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]) (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]))
|
||||
for {
|
||||
t := v.Type
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake2)
|
||||
v0 := b.NewValue0(v.Line, OpArg, t.FieldType(0))
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off + t.FieldOff(0)
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, t.FieldType(1))
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + t.FieldOff(1)
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1524,23 +1524,23 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// result: (StructMake3 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]) (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]) (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)]))
|
||||
for {
|
||||
t := v.Type
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(t.IsStruct() && t.NumFields() == 3 && config.fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake3)
|
||||
v0 := b.NewValue0(v.Line, OpArg, t.FieldType(0))
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off + t.FieldOff(0)
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, t.FieldType(1))
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + t.FieldOff(1)
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
v2 := b.NewValue0(v.Line, OpArg, t.FieldType(2))
|
||||
v2.Aux = n
|
||||
v2.AuxInt = off + t.FieldOff(2)
|
||||
v2.Aux = n
|
||||
v.AddArg(v2)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1549,27 +1549,27 @@ func rewriteValuegeneric_OpArg(v *Value, config *Config) bool {
|
|||
// result: (StructMake4 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]) (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]) (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)]) (Arg <t.FieldType(3)> {n} [off+t.FieldOff(3)]))
|
||||
for {
|
||||
t := v.Type
|
||||
n := v.Aux
|
||||
off := v.AuxInt
|
||||
n := v.Aux
|
||||
if !(t.IsStruct() && t.NumFields() == 4 && config.fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake4)
|
||||
v0 := b.NewValue0(v.Line, OpArg, t.FieldType(0))
|
||||
v0.Aux = n
|
||||
v0.AuxInt = off + t.FieldOff(0)
|
||||
v0.Aux = n
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Line, OpArg, t.FieldType(1))
|
||||
v1.Aux = n
|
||||
v1.AuxInt = off + t.FieldOff(1)
|
||||
v1.Aux = n
|
||||
v.AddArg(v1)
|
||||
v2 := b.NewValue0(v.Line, OpArg, t.FieldType(2))
|
||||
v2.Aux = n
|
||||
v2.AuxInt = off + t.FieldOff(2)
|
||||
v2.Aux = n
|
||||
v.AddArg(v2)
|
||||
v3 := b.NewValue0(v.Line, OpArg, t.FieldType(3))
|
||||
v3.Aux = n
|
||||
v3.AuxInt = off + t.FieldOff(3)
|
||||
v3.Aux = n
|
||||
v.AddArg(v3)
|
||||
return true
|
||||
}
|
||||
|
|
@ -6359,26 +6359,26 @@ func rewriteValuegeneric_OpOffPtr(v *Value, config *Config) bool {
|
|||
// cond:
|
||||
// result: (OffPtr p [a+b])
|
||||
for {
|
||||
a := v.AuxInt
|
||||
v_0 := v.Args[0]
|
||||
if v_0.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
p := v_0.Args[0]
|
||||
b := v_0.AuxInt
|
||||
a := v.AuxInt
|
||||
p := v_0.Args[0]
|
||||
v.reset(OpOffPtr)
|
||||
v.AddArg(p)
|
||||
v.AuxInt = a + b
|
||||
v.AddArg(p)
|
||||
return true
|
||||
}
|
||||
// match: (OffPtr p [0])
|
||||
// cond: v.Type.Compare(p.Type) == CMPeq
|
||||
// result: p
|
||||
for {
|
||||
p := v.Args[0]
|
||||
if v.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
p := v.Args[0]
|
||||
if !(v.Type.Compare(p.Type) == CMPeq) {
|
||||
break
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue