--- /dev/null
- var argStart int64
- if HasLinkRegister() {
- argStart += int64(Widthptr)
- }
+// 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 gc
+
+import (
+ "bytes"
+ "crypto/sha1"
+ "fmt"
+ "html"
+ "math"
+ "os"
+ "strings"
+
+ "cmd/compile/internal/ssa"
+ "cmd/internal/obj"
+ "cmd/internal/obj/x86"
+)
+
+// buildssa builds an SSA function
+// and reports whether it should be used.
+// Once the SSA implementation is complete,
+// it will never return nil, and the bool can be removed.
+func buildssa(fn *Node) (ssafn *ssa.Func, usessa bool) {
+ name := fn.Func.Nname.Sym.Name
+ usessa = strings.HasSuffix(name, "_ssa") || strings.Contains(name, "_ssa.") || name == os.Getenv("GOSSAFUNC")
+
+ if usessa {
+ fmt.Println("generating SSA for", name)
+ dumplist("buildssa-enter", fn.Func.Enter)
+ dumplist("buildssa-body", fn.Nbody)
+ dumplist("buildssa-exit", fn.Func.Exit)
+ }
+
+ var s state
+ s.pushLine(fn.Lineno)
+ defer s.popLine()
+
+ // TODO(khr): build config just once at the start of the compiler binary
+
+ var e ssaExport
+ e.log = usessa
+ s.config = ssa.NewConfig(Thearch.Thestring, &e)
+ s.f = s.config.NewFunc()
+ s.f.Name = name
+ s.exitCode = fn.Func.Exit
+
+ if name == os.Getenv("GOSSAFUNC") {
+ // TODO: tempfile? it is handy to have the location
+ // of this file be stable, so you can just reload in the browser.
+ s.config.HTML = ssa.NewHTMLWriter("ssa.html", &s, name)
+ // TODO: generate and print a mapping from nodes to values and blocks
+ }
+ defer func() {
+ if !usessa {
+ s.config.HTML.Close()
+ }
+ }()
+
+ // If SSA support for the function is incomplete,
+ // assume that any panics are due to violated
+ // invariants. Swallow them silently.
+ defer func() {
+ if err := recover(); err != nil {
+ if !e.unimplemented {
+ panic(err)
+ }
+ }
+ }()
+
+ // We construct SSA using an algorithm similar to
+ // Brau, Buchwald, Hack, Leißa, Mallon, and Zwinkau
+ // http://pp.info.uni-karlsruhe.de/uploads/publikationen/braun13cc.pdf
+ // TODO: check this comment
+
+ // Allocate starting block
+ s.f.Entry = s.f.NewBlock(ssa.BlockPlain)
+
+ // Allocate starting values
+ s.labels = map[string]*ssaLabel{}
+ s.labeledNodes = map[*Node]*ssaLabel{}
+ s.startmem = s.entryNewValue0(ssa.OpArg, ssa.TypeMem)
+ s.sp = s.entryNewValue0(ssa.OpSP, Types[TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead
+ s.sb = s.entryNewValue0(ssa.OpSB, Types[TUINTPTR])
+
+ s.startBlock(s.f.Entry)
+ s.vars[&memVar] = s.startmem
+
+ s.varsyms = map[*Node]interface{}{}
+
+ // Generate addresses of local declarations
+ s.decladdrs = map[*Node]*ssa.Value{}
+ for d := fn.Func.Dcl; d != nil; d = d.Next {
+ n := d.N
+ switch n.Class {
+ case PPARAM:
+ aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n})
+ s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp)
+ case PAUTO | PHEAP:
+ // TODO this looks wrong for PAUTO|PHEAP, no vardef, but also no definition
+ aux := s.lookupSymbol(n, &ssa.AutoSymbol{Typ: n.Type, Node: n})
+ s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp)
+ case PPARAM | PHEAP, PPARAMOUT | PHEAP:
+ // This ends up wrong, have to do it at the PARAM node instead.
+ case PAUTO, PPARAMOUT:
+ // processed at each use, to prevent Addr coming
+ // before the decl.
+ case PFUNC:
+ // local function - already handled by frontend
+ default:
+ str := ""
+ if n.Class&PHEAP != 0 {
+ str = ",heap"
+ }
+ s.Unimplementedf("local variable with class %s%s unimplemented", classnames[n.Class&^PHEAP], str)
+ }
+ }
+ // nodfp is a special argument which is the function's FP.
+ aux := &ssa.ArgSymbol{Typ: Types[TUINTPTR], Node: nodfp}
+ s.decladdrs[nodfp] = s.entryNewValue1A(ssa.OpAddr, Types[TUINTPTR], aux, s.sp)
+
+ // Convert the AST-based IR to the SSA-based IR
+ s.stmtList(fn.Func.Enter)
+ s.stmtList(fn.Nbody)
+
+ // fallthrough to exit
+ if s.curBlock != nil {
+ s.stmtList(s.exitCode)
+ m := s.mem()
+ b := s.endBlock()
+ b.Kind = ssa.BlockRet
+ b.Control = m
+ }
+
+ // Check that we used all labels
+ for name, lab := range s.labels {
+ if !lab.used() && !lab.reported {
+ yyerrorl(int(lab.defNode.Lineno), "label %v defined and not used", name)
+ lab.reported = true
+ }
+ if lab.used() && !lab.defined() && !lab.reported {
+ yyerrorl(int(lab.useNode.Lineno), "label %v not defined", name)
+ lab.reported = true
+ }
+ }
+
+ // Check any forward gotos. Non-forward gotos have already been checked.
+ for _, n := range s.fwdGotos {
+ lab := s.labels[n.Left.Sym.Name]
+ // If the label is undefined, we have already have printed an error.
+ if lab.defined() {
+ s.checkgoto(n, lab.defNode)
+ }
+ }
+
+ if nerrors > 0 {
+ return nil, false
+ }
+
+ // Link up variable uses to variable definitions
+ s.linkForwardReferences()
+
+ // Don't carry reference this around longer than necessary
+ s.exitCode = nil
+
+ // Main call to ssa package to compile function
+ ssa.Compile(s.f)
+
+ // Calculate stats about what percentage of functions SSA handles.
+ if false {
+ fmt.Printf("SSA implemented: %t\n", !e.unimplemented)
+ }
+
+ if e.unimplemented {
+ return nil, false
+ }
+
+ // TODO: enable codegen more broadly once the codegen stabilizes
+ // and runtime support is in (gc maps, write barriers, etc.)
+ if usessa {
+ return s.f, true
+ }
+ if localpkg.Name != os.Getenv("GOSSAPKG") {
+ return s.f, false
+ }
+ if os.Getenv("GOSSAHASH") == "" {
+ // Use everything in the package
+ return s.f, true
+ }
+ // Check the hash of the name against a partial input hash.
+ // We use this feature to do a binary search within a package to
+ // find a function that is incorrectly compiled.
+ hstr := ""
+ for _, b := range sha1.Sum([]byte(name)) {
+ hstr += fmt.Sprintf("%08b", b)
+ }
+ if strings.HasSuffix(hstr, os.Getenv("GOSSAHASH")) {
+ fmt.Printf("GOSSAHASH triggered %s\n", name)
+ return s.f, true
+ }
+ return s.f, false
+}
+
+type state struct {
+ // configuration (arch) information
+ config *ssa.Config
+
+ // function we're building
+ f *ssa.Func
+
+ // labels and labeled control flow nodes (OFOR, OSWITCH, OSELECT) in f
+ labels map[string]*ssaLabel
+ labeledNodes map[*Node]*ssaLabel
+
+ // gotos that jump forward; required for deferred checkgoto calls
+ fwdGotos []*Node
+ // Code that must precede any return
+ // (e.g., copying value of heap-escaped paramout back to true paramout)
+ exitCode *NodeList
+
+ // unlabeled break and continue statement tracking
+ breakTo *ssa.Block // current target for plain break statement
+ continueTo *ssa.Block // current target for plain continue statement
+
+ // current location where we're interpreting the AST
+ curBlock *ssa.Block
+
+ // variable assignments in the current block (map from variable symbol to ssa value)
+ // *Node is the unique identifier (an ONAME Node) for the variable.
+ vars map[*Node]*ssa.Value
+
+ // all defined variables at the end of each block. Indexed by block ID.
+ defvars []map[*Node]*ssa.Value
+
+ // addresses of PPARAM and PPARAMOUT variables.
+ decladdrs map[*Node]*ssa.Value
+
+ // symbols for PEXTERN, PAUTO and PPARAMOUT variables so they can be reused.
+ varsyms map[*Node]interface{}
+
+ // starting values. Memory, frame pointer, and stack pointer
+ startmem *ssa.Value
+ sp *ssa.Value
+ sb *ssa.Value
+
+ // line number stack. The current line number is top of stack
+ line []int32
+}
+
+type ssaLabel struct {
+ target *ssa.Block // block identified by this label
+ breakTarget *ssa.Block // block to break to in control flow node identified by this label
+ continueTarget *ssa.Block // block to continue to in control flow node identified by this label
+ defNode *Node // label definition Node (OLABEL)
+ // Label use Node (OGOTO, OBREAK, OCONTINUE).
+ // Used only for error detection and reporting.
+ // There might be multiple uses, but we only need to track one.
+ useNode *Node
+ reported bool // reported indicates whether an error has already been reported for this label
+}
+
+// defined reports whether the label has a definition (OLABEL node).
+func (l *ssaLabel) defined() bool { return l.defNode != nil }
+
+// used reports whether the label has a use (OGOTO, OBREAK, or OCONTINUE node).
+func (l *ssaLabel) used() bool { return l.useNode != nil }
+
+// label returns the label associated with sym, creating it if necessary.
+func (s *state) label(sym *Sym) *ssaLabel {
+ lab := s.labels[sym.Name]
+ if lab == nil {
+ lab = new(ssaLabel)
+ s.labels[sym.Name] = lab
+ }
+ return lab
+}
+
+func (s *state) Logf(msg string, args ...interface{}) { s.config.Logf(msg, args...) }
+func (s *state) Fatalf(msg string, args ...interface{}) { s.config.Fatalf(msg, args...) }
+func (s *state) Unimplementedf(msg string, args ...interface{}) { s.config.Unimplementedf(msg, args...) }
+
+var (
+ // dummy node for the memory variable
+ memVar = Node{Op: ONAME, Sym: &Sym{Name: "mem"}}
+
+ // dummy nodes for temporary variables
+ ptrVar = Node{Op: ONAME, Sym: &Sym{Name: "ptr"}}
+ capVar = Node{Op: ONAME, Sym: &Sym{Name: "cap"}}
+ typVar = Node{Op: ONAME, Sym: &Sym{Name: "typ"}}
+ idataVar = Node{Op: ONAME, Sym: &Sym{Name: "idata"}}
+ okVar = Node{Op: ONAME, Sym: &Sym{Name: "ok"}}
+)
+
+// startBlock sets the current block we're generating code in to b.
+func (s *state) startBlock(b *ssa.Block) {
+ if s.curBlock != nil {
+ s.Fatalf("starting block %v when block %v has not ended", b, s.curBlock)
+ }
+ s.curBlock = b
+ s.vars = map[*Node]*ssa.Value{}
+}
+
+// endBlock marks the end of generating code for the current block.
+// Returns the (former) current block. Returns nil if there is no current
+// block, i.e. if no code flows to the current execution point.
+func (s *state) endBlock() *ssa.Block {
+ b := s.curBlock
+ if b == nil {
+ return nil
+ }
+ for len(s.defvars) <= int(b.ID) {
+ s.defvars = append(s.defvars, nil)
+ }
+ s.defvars[b.ID] = s.vars
+ s.curBlock = nil
+ s.vars = nil
+ b.Line = s.peekLine()
+ return b
+}
+
+// pushLine pushes a line number on the line number stack.
+func (s *state) pushLine(line int32) {
+ s.line = append(s.line, line)
+}
+
+// popLine pops the top of the line number stack.
+func (s *state) popLine() {
+ s.line = s.line[:len(s.line)-1]
+}
+
+// peekLine peek the top of the line number stack.
+func (s *state) peekLine() int32 {
+ return s.line[len(s.line)-1]
+}
+
+func (s *state) Error(msg string, args ...interface{}) {
+ yyerrorl(int(s.peekLine()), msg, args...)
+}
+
+// newValue0 adds a new value with no arguments to the current block.
+func (s *state) newValue0(op ssa.Op, t ssa.Type) *ssa.Value {
+ return s.curBlock.NewValue0(s.peekLine(), op, t)
+}
+
+// newValue0A adds a new value with no arguments and an aux value to the current block.
+func (s *state) newValue0A(op ssa.Op, t ssa.Type, aux interface{}) *ssa.Value {
+ return s.curBlock.NewValue0A(s.peekLine(), op, t, aux)
+}
+
+// newValue0I adds a new value with no arguments and an auxint value to the current block.
+func (s *state) newValue0I(op ssa.Op, t ssa.Type, auxint int64) *ssa.Value {
+ return s.curBlock.NewValue0I(s.peekLine(), op, t, auxint)
+}
+
+// newValue1 adds a new value with one argument to the current block.
+func (s *state) newValue1(op ssa.Op, t ssa.Type, arg *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue1(s.peekLine(), op, t, arg)
+}
+
+// newValue1A adds a new value with one argument and an aux value to the current block.
+func (s *state) newValue1A(op ssa.Op, t ssa.Type, aux interface{}, arg *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue1A(s.peekLine(), op, t, aux, arg)
+}
+
+// newValue1I adds a new value with one argument and an auxint value to the current block.
+func (s *state) newValue1I(op ssa.Op, t ssa.Type, aux int64, arg *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue1I(s.peekLine(), op, t, aux, arg)
+}
+
+// newValue2 adds a new value with two arguments to the current block.
+func (s *state) newValue2(op ssa.Op, t ssa.Type, arg0, arg1 *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue2(s.peekLine(), op, t, arg0, arg1)
+}
+
+// newValue2I adds a new value with two arguments and an auxint value to the current block.
+func (s *state) newValue2I(op ssa.Op, t ssa.Type, aux int64, arg0, arg1 *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue2I(s.peekLine(), op, t, aux, arg0, arg1)
+}
+
+// newValue3 adds a new value with three arguments to the current block.
+func (s *state) newValue3(op ssa.Op, t ssa.Type, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue3(s.peekLine(), op, t, arg0, arg1, arg2)
+}
+
+// newValue3I adds a new value with three arguments and an auxint value to the current block.
+func (s *state) newValue3I(op ssa.Op, t ssa.Type, aux int64, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
+ return s.curBlock.NewValue3I(s.peekLine(), op, t, aux, arg0, arg1, arg2)
+}
+
+// entryNewValue0 adds a new value with no arguments to the entry block.
+func (s *state) entryNewValue0(op ssa.Op, t ssa.Type) *ssa.Value {
+ return s.f.Entry.NewValue0(s.peekLine(), op, t)
+}
+
+// entryNewValue0A adds a new value with no arguments and an aux value to the entry block.
+func (s *state) entryNewValue0A(op ssa.Op, t ssa.Type, aux interface{}) *ssa.Value {
+ return s.f.Entry.NewValue0A(s.peekLine(), op, t, aux)
+}
+
+// entryNewValue0I adds a new value with no arguments and an auxint value to the entry block.
+func (s *state) entryNewValue0I(op ssa.Op, t ssa.Type, auxint int64) *ssa.Value {
+ return s.f.Entry.NewValue0I(s.peekLine(), op, t, auxint)
+}
+
+// entryNewValue1 adds a new value with one argument to the entry block.
+func (s *state) entryNewValue1(op ssa.Op, t ssa.Type, arg *ssa.Value) *ssa.Value {
+ return s.f.Entry.NewValue1(s.peekLine(), op, t, arg)
+}
+
+// entryNewValue1 adds a new value with one argument and an auxint value to the entry block.
+func (s *state) entryNewValue1I(op ssa.Op, t ssa.Type, auxint int64, arg *ssa.Value) *ssa.Value {
+ return s.f.Entry.NewValue1I(s.peekLine(), op, t, auxint, arg)
+}
+
+// entryNewValue1A adds a new value with one argument and an aux value to the entry block.
+func (s *state) entryNewValue1A(op ssa.Op, t ssa.Type, aux interface{}, arg *ssa.Value) *ssa.Value {
+ return s.f.Entry.NewValue1A(s.peekLine(), op, t, aux, arg)
+}
+
+// entryNewValue2 adds a new value with two arguments to the entry block.
+func (s *state) entryNewValue2(op ssa.Op, t ssa.Type, arg0, arg1 *ssa.Value) *ssa.Value {
+ return s.f.Entry.NewValue2(s.peekLine(), op, t, arg0, arg1)
+}
+
+// const* routines add a new const value to the entry block.
+func (s *state) constBool(c bool) *ssa.Value {
+ return s.f.ConstBool(s.peekLine(), Types[TBOOL], c)
+}
+func (s *state) constInt8(t ssa.Type, c int8) *ssa.Value {
+ return s.f.ConstInt8(s.peekLine(), t, c)
+}
+func (s *state) constInt16(t ssa.Type, c int16) *ssa.Value {
+ return s.f.ConstInt16(s.peekLine(), t, c)
+}
+func (s *state) constInt32(t ssa.Type, c int32) *ssa.Value {
+ return s.f.ConstInt32(s.peekLine(), t, c)
+}
+func (s *state) constInt64(t ssa.Type, c int64) *ssa.Value {
+ return s.f.ConstInt64(s.peekLine(), t, c)
+}
+func (s *state) constFloat32(t ssa.Type, c float64) *ssa.Value {
+ return s.f.ConstFloat32(s.peekLine(), t, c)
+}
+func (s *state) constFloat64(t ssa.Type, c float64) *ssa.Value {
+ return s.f.ConstFloat64(s.peekLine(), t, c)
+}
+func (s *state) constIntPtr(t ssa.Type, c int64) *ssa.Value {
+ if s.config.PtrSize == 4 && int64(int32(c)) != c {
+ s.Fatalf("pointer constant too big %d", c)
+ }
+ return s.f.ConstIntPtr(s.peekLine(), t, c)
+}
+func (s *state) constInt(t ssa.Type, c int64) *ssa.Value {
+ if s.config.IntSize == 8 {
+ return s.constInt64(t, c)
+ }
+ if int64(int32(c)) != c {
+ s.Fatalf("integer constant too big %d", c)
+ }
+ return s.constInt32(t, int32(c))
+}
+
+// ssaStmtList converts the statement n to SSA and adds it to s.
+func (s *state) stmtList(l *NodeList) {
+ for ; l != nil; l = l.Next {
+ s.stmt(l.N)
+ }
+}
+
+// ssaStmt converts the statement n to SSA and adds it to s.
+func (s *state) stmt(n *Node) {
+ s.pushLine(n.Lineno)
+ defer s.popLine()
+
+ // If s.curBlock is nil, then we're about to generate dead code.
+ // We can't just short-circuit here, though,
+ // because we check labels and gotos as part of SSA generation.
+ // Provide a block for the dead code so that we don't have
+ // to add special cases everywhere else.
+ if s.curBlock == nil {
+ dead := s.f.NewBlock(ssa.BlockPlain)
+ s.startBlock(dead)
+ }
+
+ s.stmtList(n.Ninit)
+ switch n.Op {
+
+ case OBLOCK:
+ s.stmtList(n.List)
+
+ // No-ops
+ case OEMPTY, ODCLCONST, ODCLTYPE, OFALL:
+
+ // Expression statements
+ case OCALLFUNC, OCALLMETH, OCALLINTER:
+ s.call(n, callNormal)
+ case ODEFER:
+ s.call(n.Left, callDefer)
+ case OPROC:
+ s.call(n.Left, callGo)
+
+ case OAS2DOTTYPE:
+ res, resok := s.dottype(n.Rlist.N, true)
+ s.assign(n.List.N, res, false)
+ s.assign(n.List.Next.N, resok, false)
+ return
+
+ case ODCL:
+ if n.Left.Class&PHEAP == 0 {
+ return
+ }
+ if compiling_runtime != 0 {
+ Fatalf("%v escapes to heap, not allowed in runtime.", n)
+ }
+
+ // TODO: the old pass hides the details of PHEAP
+ // variables behind ONAME nodes. Figure out if it's better
+ // to rewrite the tree and make the heapaddr construct explicit
+ // or to keep this detail hidden behind the scenes.
+ palloc := prealloc[n.Left]
+ if palloc == nil {
+ palloc = callnew(n.Left.Type)
+ prealloc[n.Left] = palloc
+ }
+ r := s.expr(palloc)
+ s.assign(n.Left.Name.Heapaddr, r, false)
+
+ case OLABEL:
+ sym := n.Left.Sym
+
+ if isblanksym(sym) {
+ // Empty identifier is valid but useless.
+ // See issues 11589, 11593.
+ return
+ }
+
+ lab := s.label(sym)
+
+ // Associate label with its control flow node, if any
+ if ctl := n.Name.Defn; ctl != nil {
+ switch ctl.Op {
+ case OFOR, OSWITCH, OSELECT:
+ s.labeledNodes[ctl] = lab
+ }
+ }
+
+ if !lab.defined() {
+ lab.defNode = n
+ } else {
+ s.Error("label %v already defined at %v", sym, Ctxt.Line(int(lab.defNode.Lineno)))
+ lab.reported = true
+ }
+ // The label might already have a target block via a goto.
+ if lab.target == nil {
+ lab.target = s.f.NewBlock(ssa.BlockPlain)
+ }
+
+ // go to that label (we pretend "label:" is preceded by "goto label")
+ b := s.endBlock()
+ b.AddEdgeTo(lab.target)
+ s.startBlock(lab.target)
+
+ case OGOTO:
+ sym := n.Left.Sym
+
+ lab := s.label(sym)
+ if lab.target == nil {
+ lab.target = s.f.NewBlock(ssa.BlockPlain)
+ }
+ if !lab.used() {
+ lab.useNode = n
+ }
+
+ if lab.defined() {
+ s.checkgoto(n, lab.defNode)
+ } else {
+ s.fwdGotos = append(s.fwdGotos, n)
+ }
+
+ b := s.endBlock()
+ b.AddEdgeTo(lab.target)
+
+ case OAS, OASWB:
+ // Check whether we can generate static data rather than code.
+ // If so, ignore n and defer data generation until codegen.
+ // Failure to do this causes writes to readonly symbols.
+ if gen_as_init(n, true) {
+ var data []*Node
+ if s.f.StaticData != nil {
+ data = s.f.StaticData.([]*Node)
+ }
+ s.f.StaticData = append(data, n)
+ return
+ }
+ var r *ssa.Value
+ if n.Right != nil {
+ if n.Right.Op == OSTRUCTLIT || n.Right.Op == OARRAYLIT {
+ // All literals with nonzero fields have already been
+ // rewritten during walk. Any that remain are just T{}
+ // or equivalents. Leave r = nil to get zeroing behavior.
+ if !iszero(n.Right) {
+ Fatalf("literal with nonzero value in SSA: %v", n.Right)
+ }
+ } else {
+ r = s.expr(n.Right)
+ }
+ }
+ if n.Right != nil && n.Right.Op == OAPPEND {
+ // Yuck! The frontend gets rid of the write barrier, but we need it!
+ // At least, we need it in the case where growslice is called.
+ // TODO: Do the write barrier on just the growslice branch.
+ // TODO: just add a ptr graying to the end of growslice?
+ // TODO: check whether we need to do this for ODOTTYPE and ORECV also.
+ // They get similar wb-removal treatment in walk.go:OAS.
+ s.assign(n.Left, r, true)
+ return
+ }
+ s.assign(n.Left, r, n.Op == OASWB)
+
+ case OIF:
+ cond := s.expr(n.Left)
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cond
+ b.Likely = ssa.BranchPrediction(n.Likely) // gc and ssa both use -1/0/+1 for likeliness
+
+ bThen := s.f.NewBlock(ssa.BlockPlain)
+ bEnd := s.f.NewBlock(ssa.BlockPlain)
+ var bElse *ssa.Block
+
+ if n.Rlist == nil {
+ b.AddEdgeTo(bThen)
+ b.AddEdgeTo(bEnd)
+ } else {
+ bElse = s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(bThen)
+ b.AddEdgeTo(bElse)
+ }
+
+ s.startBlock(bThen)
+ s.stmtList(n.Nbody)
+ if b := s.endBlock(); b != nil {
+ b.AddEdgeTo(bEnd)
+ }
+
+ if n.Rlist != nil {
+ s.startBlock(bElse)
+ s.stmtList(n.Rlist)
+ if b := s.endBlock(); b != nil {
+ b.AddEdgeTo(bEnd)
+ }
+ }
+ s.startBlock(bEnd)
+
+ case ORETURN:
+ s.stmtList(n.List)
+ s.stmtList(s.exitCode)
+ m := s.mem()
+ b := s.endBlock()
+ b.Kind = ssa.BlockRet
+ b.Control = m
+ case ORETJMP:
+ s.stmtList(n.List)
+ s.stmtList(s.exitCode)
+ m := s.mem()
+ b := s.endBlock()
+ b.Kind = ssa.BlockRetJmp
+ b.Aux = n.Left.Sym
+ b.Control = m
+
+ case OCONTINUE, OBREAK:
+ var op string
+ var to *ssa.Block
+ switch n.Op {
+ case OCONTINUE:
+ op = "continue"
+ to = s.continueTo
+ case OBREAK:
+ op = "break"
+ to = s.breakTo
+ }
+ if n.Left == nil {
+ // plain break/continue
+ if to == nil {
+ s.Error("%s is not in a loop", op)
+ return
+ }
+ // nothing to do; "to" is already the correct target
+ } else {
+ // labeled break/continue; look up the target
+ sym := n.Left.Sym
+ lab := s.label(sym)
+ if !lab.used() {
+ lab.useNode = n.Left
+ }
+ if !lab.defined() {
+ s.Error("%s label not defined: %v", op, sym)
+ lab.reported = true
+ return
+ }
+ switch n.Op {
+ case OCONTINUE:
+ to = lab.continueTarget
+ case OBREAK:
+ to = lab.breakTarget
+ }
+ if to == nil {
+ // Valid label but not usable with a break/continue here, e.g.:
+ // for {
+ // continue abc
+ // }
+ // abc:
+ // for {}
+ s.Error("invalid %s label %v", op, sym)
+ lab.reported = true
+ return
+ }
+ }
+
+ b := s.endBlock()
+ b.AddEdgeTo(to)
+
+ case OFOR:
+ // OFOR: for Ninit; Left; Right { Nbody }
+ bCond := s.f.NewBlock(ssa.BlockPlain)
+ bBody := s.f.NewBlock(ssa.BlockPlain)
+ bIncr := s.f.NewBlock(ssa.BlockPlain)
+ bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+ // first, jump to condition test
+ b := s.endBlock()
+ b.AddEdgeTo(bCond)
+
+ // generate code to test condition
+ s.startBlock(bCond)
+ var cond *ssa.Value
+ if n.Left != nil {
+ cond = s.expr(n.Left)
+ } else {
+ cond = s.constBool(true)
+ }
+ b = s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cond
+ b.Likely = ssa.BranchLikely
+ b.AddEdgeTo(bBody)
+ b.AddEdgeTo(bEnd)
+
+ // set up for continue/break in body
+ prevContinue := s.continueTo
+ prevBreak := s.breakTo
+ s.continueTo = bIncr
+ s.breakTo = bEnd
+ lab := s.labeledNodes[n]
+ if lab != nil {
+ // labeled for loop
+ lab.continueTarget = bIncr
+ lab.breakTarget = bEnd
+ }
+
+ // generate body
+ s.startBlock(bBody)
+ s.stmtList(n.Nbody)
+
+ // tear down continue/break
+ s.continueTo = prevContinue
+ s.breakTo = prevBreak
+ if lab != nil {
+ lab.continueTarget = nil
+ lab.breakTarget = nil
+ }
+
+ // done with body, goto incr
+ if b := s.endBlock(); b != nil {
+ b.AddEdgeTo(bIncr)
+ }
+
+ // generate incr
+ s.startBlock(bIncr)
+ if n.Right != nil {
+ s.stmt(n.Right)
+ }
+ if b := s.endBlock(); b != nil {
+ b.AddEdgeTo(bCond)
+ }
+ s.startBlock(bEnd)
+
+ case OSWITCH, OSELECT:
+ // These have been mostly rewritten by the front end into their Nbody fields.
+ // Our main task is to correctly hook up any break statements.
+ bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+ prevBreak := s.breakTo
+ s.breakTo = bEnd
+ lab := s.labeledNodes[n]
+ if lab != nil {
+ // labeled
+ lab.breakTarget = bEnd
+ }
+
+ // generate body code
+ s.stmtList(n.Nbody)
+
+ s.breakTo = prevBreak
+ if lab != nil {
+ lab.breakTarget = nil
+ }
+
+ if b := s.endBlock(); b != nil {
+ b.AddEdgeTo(bEnd)
+ }
+ s.startBlock(bEnd)
+
+ case OVARKILL:
+ // Insert a varkill op to record that a variable is no longer live.
+ // We only care about liveness info at call sites, so putting the
+ // varkill in the store chain is enough to keep it correctly ordered
+ // with respect to call ops.
+ if !canSSA(n.Left) {
+ s.vars[&memVar] = s.newValue1A(ssa.OpVarKill, ssa.TypeMem, n.Left, s.mem())
+ }
+
+ case OCHECKNIL:
+ p := s.expr(n.Left)
+ s.nilCheck(p)
+
+ default:
+ s.Unimplementedf("unhandled stmt %s", opnames[n.Op])
+ }
+}
+
+type opAndType struct {
+ op uint8
+ etype uint8
+}
+
+var opToSSA = map[opAndType]ssa.Op{
+ opAndType{OADD, TINT8}: ssa.OpAdd8,
+ opAndType{OADD, TUINT8}: ssa.OpAdd8,
+ opAndType{OADD, TINT16}: ssa.OpAdd16,
+ opAndType{OADD, TUINT16}: ssa.OpAdd16,
+ opAndType{OADD, TINT32}: ssa.OpAdd32,
+ opAndType{OADD, TUINT32}: ssa.OpAdd32,
+ opAndType{OADD, TPTR32}: ssa.OpAdd32,
+ opAndType{OADD, TINT64}: ssa.OpAdd64,
+ opAndType{OADD, TUINT64}: ssa.OpAdd64,
+ opAndType{OADD, TPTR64}: ssa.OpAdd64,
+ opAndType{OADD, TFLOAT32}: ssa.OpAdd32F,
+ opAndType{OADD, TFLOAT64}: ssa.OpAdd64F,
+
+ opAndType{OSUB, TINT8}: ssa.OpSub8,
+ opAndType{OSUB, TUINT8}: ssa.OpSub8,
+ opAndType{OSUB, TINT16}: ssa.OpSub16,
+ opAndType{OSUB, TUINT16}: ssa.OpSub16,
+ opAndType{OSUB, TINT32}: ssa.OpSub32,
+ opAndType{OSUB, TUINT32}: ssa.OpSub32,
+ opAndType{OSUB, TINT64}: ssa.OpSub64,
+ opAndType{OSUB, TUINT64}: ssa.OpSub64,
+ opAndType{OSUB, TFLOAT32}: ssa.OpSub32F,
+ opAndType{OSUB, TFLOAT64}: ssa.OpSub64F,
+
+ opAndType{ONOT, TBOOL}: ssa.OpNot,
+
+ opAndType{OMINUS, TINT8}: ssa.OpNeg8,
+ opAndType{OMINUS, TUINT8}: ssa.OpNeg8,
+ opAndType{OMINUS, TINT16}: ssa.OpNeg16,
+ opAndType{OMINUS, TUINT16}: ssa.OpNeg16,
+ opAndType{OMINUS, TINT32}: ssa.OpNeg32,
+ opAndType{OMINUS, TUINT32}: ssa.OpNeg32,
+ opAndType{OMINUS, TINT64}: ssa.OpNeg64,
+ opAndType{OMINUS, TUINT64}: ssa.OpNeg64,
+ opAndType{OMINUS, TFLOAT32}: ssa.OpNeg32F,
+ opAndType{OMINUS, TFLOAT64}: ssa.OpNeg64F,
+
+ opAndType{OCOM, TINT8}: ssa.OpCom8,
+ opAndType{OCOM, TUINT8}: ssa.OpCom8,
+ opAndType{OCOM, TINT16}: ssa.OpCom16,
+ opAndType{OCOM, TUINT16}: ssa.OpCom16,
+ opAndType{OCOM, TINT32}: ssa.OpCom32,
+ opAndType{OCOM, TUINT32}: ssa.OpCom32,
+ opAndType{OCOM, TINT64}: ssa.OpCom64,
+ opAndType{OCOM, TUINT64}: ssa.OpCom64,
+
+ opAndType{OIMAG, TCOMPLEX64}: ssa.OpComplexImag,
+ opAndType{OIMAG, TCOMPLEX128}: ssa.OpComplexImag,
+ opAndType{OREAL, TCOMPLEX64}: ssa.OpComplexReal,
+ opAndType{OREAL, TCOMPLEX128}: ssa.OpComplexReal,
+
+ opAndType{OMUL, TINT8}: ssa.OpMul8,
+ opAndType{OMUL, TUINT8}: ssa.OpMul8,
+ opAndType{OMUL, TINT16}: ssa.OpMul16,
+ opAndType{OMUL, TUINT16}: ssa.OpMul16,
+ opAndType{OMUL, TINT32}: ssa.OpMul32,
+ opAndType{OMUL, TUINT32}: ssa.OpMul32,
+ opAndType{OMUL, TINT64}: ssa.OpMul64,
+ opAndType{OMUL, TUINT64}: ssa.OpMul64,
+ opAndType{OMUL, TFLOAT32}: ssa.OpMul32F,
+ opAndType{OMUL, TFLOAT64}: ssa.OpMul64F,
+
+ opAndType{ODIV, TFLOAT32}: ssa.OpDiv32F,
+ opAndType{ODIV, TFLOAT64}: ssa.OpDiv64F,
+
+ opAndType{OHMUL, TINT8}: ssa.OpHmul8,
+ opAndType{OHMUL, TUINT8}: ssa.OpHmul8u,
+ opAndType{OHMUL, TINT16}: ssa.OpHmul16,
+ opAndType{OHMUL, TUINT16}: ssa.OpHmul16u,
+ opAndType{OHMUL, TINT32}: ssa.OpHmul32,
+ opAndType{OHMUL, TUINT32}: ssa.OpHmul32u,
+
+ opAndType{ODIV, TINT8}: ssa.OpDiv8,
+ opAndType{ODIV, TUINT8}: ssa.OpDiv8u,
+ opAndType{ODIV, TINT16}: ssa.OpDiv16,
+ opAndType{ODIV, TUINT16}: ssa.OpDiv16u,
+ opAndType{ODIV, TINT32}: ssa.OpDiv32,
+ opAndType{ODIV, TUINT32}: ssa.OpDiv32u,
+ opAndType{ODIV, TINT64}: ssa.OpDiv64,
+ opAndType{ODIV, TUINT64}: ssa.OpDiv64u,
+
+ opAndType{OMOD, TINT8}: ssa.OpMod8,
+ opAndType{OMOD, TUINT8}: ssa.OpMod8u,
+ opAndType{OMOD, TINT16}: ssa.OpMod16,
+ opAndType{OMOD, TUINT16}: ssa.OpMod16u,
+ opAndType{OMOD, TINT32}: ssa.OpMod32,
+ opAndType{OMOD, TUINT32}: ssa.OpMod32u,
+ opAndType{OMOD, TINT64}: ssa.OpMod64,
+ opAndType{OMOD, TUINT64}: ssa.OpMod64u,
+
+ opAndType{OAND, TINT8}: ssa.OpAnd8,
+ opAndType{OAND, TUINT8}: ssa.OpAnd8,
+ opAndType{OAND, TINT16}: ssa.OpAnd16,
+ opAndType{OAND, TUINT16}: ssa.OpAnd16,
+ opAndType{OAND, TINT32}: ssa.OpAnd32,
+ opAndType{OAND, TUINT32}: ssa.OpAnd32,
+ opAndType{OAND, TINT64}: ssa.OpAnd64,
+ opAndType{OAND, TUINT64}: ssa.OpAnd64,
+
+ opAndType{OOR, TINT8}: ssa.OpOr8,
+ opAndType{OOR, TUINT8}: ssa.OpOr8,
+ opAndType{OOR, TINT16}: ssa.OpOr16,
+ opAndType{OOR, TUINT16}: ssa.OpOr16,
+ opAndType{OOR, TINT32}: ssa.OpOr32,
+ opAndType{OOR, TUINT32}: ssa.OpOr32,
+ opAndType{OOR, TINT64}: ssa.OpOr64,
+ opAndType{OOR, TUINT64}: ssa.OpOr64,
+
+ opAndType{OXOR, TINT8}: ssa.OpXor8,
+ opAndType{OXOR, TUINT8}: ssa.OpXor8,
+ opAndType{OXOR, TINT16}: ssa.OpXor16,
+ opAndType{OXOR, TUINT16}: ssa.OpXor16,
+ opAndType{OXOR, TINT32}: ssa.OpXor32,
+ opAndType{OXOR, TUINT32}: ssa.OpXor32,
+ opAndType{OXOR, TINT64}: ssa.OpXor64,
+ opAndType{OXOR, TUINT64}: ssa.OpXor64,
+
+ opAndType{OEQ, TBOOL}: ssa.OpEq8,
+ opAndType{OEQ, TINT8}: ssa.OpEq8,
+ opAndType{OEQ, TUINT8}: ssa.OpEq8,
+ opAndType{OEQ, TINT16}: ssa.OpEq16,
+ opAndType{OEQ, TUINT16}: ssa.OpEq16,
+ opAndType{OEQ, TINT32}: ssa.OpEq32,
+ opAndType{OEQ, TUINT32}: ssa.OpEq32,
+ opAndType{OEQ, TINT64}: ssa.OpEq64,
+ opAndType{OEQ, TUINT64}: ssa.OpEq64,
+ opAndType{OEQ, TINTER}: ssa.OpEqInter,
+ opAndType{OEQ, TARRAY}: ssa.OpEqSlice,
+ opAndType{OEQ, TFUNC}: ssa.OpEqPtr,
+ opAndType{OEQ, TMAP}: ssa.OpEqPtr,
+ opAndType{OEQ, TCHAN}: ssa.OpEqPtr,
+ opAndType{OEQ, TPTR64}: ssa.OpEqPtr,
+ opAndType{OEQ, TUINTPTR}: ssa.OpEqPtr,
+ opAndType{OEQ, TUNSAFEPTR}: ssa.OpEqPtr,
+ opAndType{OEQ, TFLOAT64}: ssa.OpEq64F,
+ opAndType{OEQ, TFLOAT32}: ssa.OpEq32F,
+
+ opAndType{ONE, TBOOL}: ssa.OpNeq8,
+ opAndType{ONE, TINT8}: ssa.OpNeq8,
+ opAndType{ONE, TUINT8}: ssa.OpNeq8,
+ opAndType{ONE, TINT16}: ssa.OpNeq16,
+ opAndType{ONE, TUINT16}: ssa.OpNeq16,
+ opAndType{ONE, TINT32}: ssa.OpNeq32,
+ opAndType{ONE, TUINT32}: ssa.OpNeq32,
+ opAndType{ONE, TINT64}: ssa.OpNeq64,
+ opAndType{ONE, TUINT64}: ssa.OpNeq64,
+ opAndType{ONE, TINTER}: ssa.OpNeqInter,
+ opAndType{ONE, TARRAY}: ssa.OpNeqSlice,
+ opAndType{ONE, TFUNC}: ssa.OpNeqPtr,
+ opAndType{ONE, TMAP}: ssa.OpNeqPtr,
+ opAndType{ONE, TCHAN}: ssa.OpNeqPtr,
+ opAndType{ONE, TPTR64}: ssa.OpNeqPtr,
+ opAndType{ONE, TUINTPTR}: ssa.OpNeqPtr,
+ opAndType{ONE, TUNSAFEPTR}: ssa.OpNeqPtr,
+ opAndType{ONE, TFLOAT64}: ssa.OpNeq64F,
+ opAndType{ONE, TFLOAT32}: ssa.OpNeq32F,
+
+ opAndType{OLT, TINT8}: ssa.OpLess8,
+ opAndType{OLT, TUINT8}: ssa.OpLess8U,
+ opAndType{OLT, TINT16}: ssa.OpLess16,
+ opAndType{OLT, TUINT16}: ssa.OpLess16U,
+ opAndType{OLT, TINT32}: ssa.OpLess32,
+ opAndType{OLT, TUINT32}: ssa.OpLess32U,
+ opAndType{OLT, TINT64}: ssa.OpLess64,
+ opAndType{OLT, TUINT64}: ssa.OpLess64U,
+ opAndType{OLT, TFLOAT64}: ssa.OpLess64F,
+ opAndType{OLT, TFLOAT32}: ssa.OpLess32F,
+
+ opAndType{OGT, TINT8}: ssa.OpGreater8,
+ opAndType{OGT, TUINT8}: ssa.OpGreater8U,
+ opAndType{OGT, TINT16}: ssa.OpGreater16,
+ opAndType{OGT, TUINT16}: ssa.OpGreater16U,
+ opAndType{OGT, TINT32}: ssa.OpGreater32,
+ opAndType{OGT, TUINT32}: ssa.OpGreater32U,
+ opAndType{OGT, TINT64}: ssa.OpGreater64,
+ opAndType{OGT, TUINT64}: ssa.OpGreater64U,
+ opAndType{OGT, TFLOAT64}: ssa.OpGreater64F,
+ opAndType{OGT, TFLOAT32}: ssa.OpGreater32F,
+
+ opAndType{OLE, TINT8}: ssa.OpLeq8,
+ opAndType{OLE, TUINT8}: ssa.OpLeq8U,
+ opAndType{OLE, TINT16}: ssa.OpLeq16,
+ opAndType{OLE, TUINT16}: ssa.OpLeq16U,
+ opAndType{OLE, TINT32}: ssa.OpLeq32,
+ opAndType{OLE, TUINT32}: ssa.OpLeq32U,
+ opAndType{OLE, TINT64}: ssa.OpLeq64,
+ opAndType{OLE, TUINT64}: ssa.OpLeq64U,
+ opAndType{OLE, TFLOAT64}: ssa.OpLeq64F,
+ opAndType{OLE, TFLOAT32}: ssa.OpLeq32F,
+
+ opAndType{OGE, TINT8}: ssa.OpGeq8,
+ opAndType{OGE, TUINT8}: ssa.OpGeq8U,
+ opAndType{OGE, TINT16}: ssa.OpGeq16,
+ opAndType{OGE, TUINT16}: ssa.OpGeq16U,
+ opAndType{OGE, TINT32}: ssa.OpGeq32,
+ opAndType{OGE, TUINT32}: ssa.OpGeq32U,
+ opAndType{OGE, TINT64}: ssa.OpGeq64,
+ opAndType{OGE, TUINT64}: ssa.OpGeq64U,
+ opAndType{OGE, TFLOAT64}: ssa.OpGeq64F,
+ opAndType{OGE, TFLOAT32}: ssa.OpGeq32F,
+
+ opAndType{OLROT, TUINT8}: ssa.OpLrot8,
+ opAndType{OLROT, TUINT16}: ssa.OpLrot16,
+ opAndType{OLROT, TUINT32}: ssa.OpLrot32,
+ opAndType{OLROT, TUINT64}: ssa.OpLrot64,
+
+ opAndType{OSQRT, TFLOAT64}: ssa.OpSqrt,
+}
+
+func (s *state) concreteEtype(t *Type) uint8 {
+ e := t.Etype
+ switch e {
+ default:
+ return e
+ case TINT:
+ if s.config.IntSize == 8 {
+ return TINT64
+ }
+ return TINT32
+ case TUINT:
+ if s.config.IntSize == 8 {
+ return TUINT64
+ }
+ return TUINT32
+ case TUINTPTR:
+ if s.config.PtrSize == 8 {
+ return TUINT64
+ }
+ return TUINT32
+ }
+}
+
+func (s *state) ssaOp(op uint8, t *Type) ssa.Op {
+ etype := s.concreteEtype(t)
+ x, ok := opToSSA[opAndType{op, etype}]
+ if !ok {
+ s.Unimplementedf("unhandled binary op %s %s", opnames[op], Econv(int(etype), 0))
+ }
+ return x
+}
+
+func floatForComplex(t *Type) *Type {
+ if t.Size() == 8 {
+ return Types[TFLOAT32]
+ } else {
+ return Types[TFLOAT64]
+ }
+}
+
+type opAndTwoTypes struct {
+ op uint8
+ etype1 uint8
+ etype2 uint8
+}
+
+type twoTypes struct {
+ etype1 uint8
+ etype2 uint8
+}
+
+type twoOpsAndType struct {
+ op1 ssa.Op
+ op2 ssa.Op
+ intermediateType uint8
+}
+
+var fpConvOpToSSA = map[twoTypes]twoOpsAndType{
+
+ twoTypes{TINT8, TFLOAT32}: twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to32F, TINT32},
+ twoTypes{TINT16, TFLOAT32}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to32F, TINT32},
+ twoTypes{TINT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to32F, TINT32},
+ twoTypes{TINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to32F, TINT64},
+
+ twoTypes{TINT8, TFLOAT64}: twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to64F, TINT32},
+ twoTypes{TINT16, TFLOAT64}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to64F, TINT32},
+ twoTypes{TINT32, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to64F, TINT32},
+ twoTypes{TINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to64F, TINT64},
+
+ twoTypes{TFLOAT32, TINT8}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, TINT32},
+ twoTypes{TFLOAT32, TINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, TINT32},
+ twoTypes{TFLOAT32, TINT32}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpCopy, TINT32},
+ twoTypes{TFLOAT32, TINT64}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpCopy, TINT64},
+
+ twoTypes{TFLOAT64, TINT8}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, TINT32},
+ twoTypes{TFLOAT64, TINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, TINT32},
+ twoTypes{TFLOAT64, TINT32}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpCopy, TINT32},
+ twoTypes{TFLOAT64, TINT64}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpCopy, TINT64},
+ // unsigned
+ twoTypes{TUINT8, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to32F, TINT32},
+ twoTypes{TUINT16, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to32F, TINT32},
+ twoTypes{TUINT32, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to32F, TINT64}, // go wide to dodge unsigned
+ twoTypes{TUINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, TUINT64}, // Cvt64Uto32F, branchy code expansion instead
+
+ twoTypes{TUINT8, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to64F, TINT32},
+ twoTypes{TUINT16, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to64F, TINT32},
+ twoTypes{TUINT32, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to64F, TINT64}, // go wide to dodge unsigned
+ twoTypes{TUINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, TUINT64}, // Cvt64Uto64F, branchy code expansion instead
+
+ twoTypes{TFLOAT32, TUINT8}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, TINT32},
+ twoTypes{TFLOAT32, TUINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, TINT32},
+ twoTypes{TFLOAT32, TUINT32}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpTrunc64to32, TINT64}, // go wide to dodge unsigned
+ twoTypes{TFLOAT32, TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, TUINT64}, // Cvt32Fto64U, branchy code expansion instead
+
+ twoTypes{TFLOAT64, TUINT8}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, TINT32},
+ twoTypes{TFLOAT64, TUINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, TINT32},
+ twoTypes{TFLOAT64, TUINT32}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpTrunc64to32, TINT64}, // go wide to dodge unsigned
+ twoTypes{TFLOAT64, TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, TUINT64}, // Cvt64Fto64U, branchy code expansion instead
+
+ // float
+ twoTypes{TFLOAT64, TFLOAT32}: twoOpsAndType{ssa.OpCvt64Fto32F, ssa.OpCopy, TFLOAT32},
+ twoTypes{TFLOAT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCopy, TFLOAT64},
+ twoTypes{TFLOAT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCopy, TFLOAT32},
+ twoTypes{TFLOAT32, TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, TFLOAT64},
+}
+
+var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{
+ opAndTwoTypes{OLSH, TINT8, TUINT8}: ssa.OpLsh8x8,
+ opAndTwoTypes{OLSH, TUINT8, TUINT8}: ssa.OpLsh8x8,
+ opAndTwoTypes{OLSH, TINT8, TUINT16}: ssa.OpLsh8x16,
+ opAndTwoTypes{OLSH, TUINT8, TUINT16}: ssa.OpLsh8x16,
+ opAndTwoTypes{OLSH, TINT8, TUINT32}: ssa.OpLsh8x32,
+ opAndTwoTypes{OLSH, TUINT8, TUINT32}: ssa.OpLsh8x32,
+ opAndTwoTypes{OLSH, TINT8, TUINT64}: ssa.OpLsh8x64,
+ opAndTwoTypes{OLSH, TUINT8, TUINT64}: ssa.OpLsh8x64,
+
+ opAndTwoTypes{OLSH, TINT16, TUINT8}: ssa.OpLsh16x8,
+ opAndTwoTypes{OLSH, TUINT16, TUINT8}: ssa.OpLsh16x8,
+ opAndTwoTypes{OLSH, TINT16, TUINT16}: ssa.OpLsh16x16,
+ opAndTwoTypes{OLSH, TUINT16, TUINT16}: ssa.OpLsh16x16,
+ opAndTwoTypes{OLSH, TINT16, TUINT32}: ssa.OpLsh16x32,
+ opAndTwoTypes{OLSH, TUINT16, TUINT32}: ssa.OpLsh16x32,
+ opAndTwoTypes{OLSH, TINT16, TUINT64}: ssa.OpLsh16x64,
+ opAndTwoTypes{OLSH, TUINT16, TUINT64}: ssa.OpLsh16x64,
+
+ opAndTwoTypes{OLSH, TINT32, TUINT8}: ssa.OpLsh32x8,
+ opAndTwoTypes{OLSH, TUINT32, TUINT8}: ssa.OpLsh32x8,
+ opAndTwoTypes{OLSH, TINT32, TUINT16}: ssa.OpLsh32x16,
+ opAndTwoTypes{OLSH, TUINT32, TUINT16}: ssa.OpLsh32x16,
+ opAndTwoTypes{OLSH, TINT32, TUINT32}: ssa.OpLsh32x32,
+ opAndTwoTypes{OLSH, TUINT32, TUINT32}: ssa.OpLsh32x32,
+ opAndTwoTypes{OLSH, TINT32, TUINT64}: ssa.OpLsh32x64,
+ opAndTwoTypes{OLSH, TUINT32, TUINT64}: ssa.OpLsh32x64,
+
+ opAndTwoTypes{OLSH, TINT64, TUINT8}: ssa.OpLsh64x8,
+ opAndTwoTypes{OLSH, TUINT64, TUINT8}: ssa.OpLsh64x8,
+ opAndTwoTypes{OLSH, TINT64, TUINT16}: ssa.OpLsh64x16,
+ opAndTwoTypes{OLSH, TUINT64, TUINT16}: ssa.OpLsh64x16,
+ opAndTwoTypes{OLSH, TINT64, TUINT32}: ssa.OpLsh64x32,
+ opAndTwoTypes{OLSH, TUINT64, TUINT32}: ssa.OpLsh64x32,
+ opAndTwoTypes{OLSH, TINT64, TUINT64}: ssa.OpLsh64x64,
+ opAndTwoTypes{OLSH, TUINT64, TUINT64}: ssa.OpLsh64x64,
+
+ opAndTwoTypes{ORSH, TINT8, TUINT8}: ssa.OpRsh8x8,
+ opAndTwoTypes{ORSH, TUINT8, TUINT8}: ssa.OpRsh8Ux8,
+ opAndTwoTypes{ORSH, TINT8, TUINT16}: ssa.OpRsh8x16,
+ opAndTwoTypes{ORSH, TUINT8, TUINT16}: ssa.OpRsh8Ux16,
+ opAndTwoTypes{ORSH, TINT8, TUINT32}: ssa.OpRsh8x32,
+ opAndTwoTypes{ORSH, TUINT8, TUINT32}: ssa.OpRsh8Ux32,
+ opAndTwoTypes{ORSH, TINT8, TUINT64}: ssa.OpRsh8x64,
+ opAndTwoTypes{ORSH, TUINT8, TUINT64}: ssa.OpRsh8Ux64,
+
+ opAndTwoTypes{ORSH, TINT16, TUINT8}: ssa.OpRsh16x8,
+ opAndTwoTypes{ORSH, TUINT16, TUINT8}: ssa.OpRsh16Ux8,
+ opAndTwoTypes{ORSH, TINT16, TUINT16}: ssa.OpRsh16x16,
+ opAndTwoTypes{ORSH, TUINT16, TUINT16}: ssa.OpRsh16Ux16,
+ opAndTwoTypes{ORSH, TINT16, TUINT32}: ssa.OpRsh16x32,
+ opAndTwoTypes{ORSH, TUINT16, TUINT32}: ssa.OpRsh16Ux32,
+ opAndTwoTypes{ORSH, TINT16, TUINT64}: ssa.OpRsh16x64,
+ opAndTwoTypes{ORSH, TUINT16, TUINT64}: ssa.OpRsh16Ux64,
+
+ opAndTwoTypes{ORSH, TINT32, TUINT8}: ssa.OpRsh32x8,
+ opAndTwoTypes{ORSH, TUINT32, TUINT8}: ssa.OpRsh32Ux8,
+ opAndTwoTypes{ORSH, TINT32, TUINT16}: ssa.OpRsh32x16,
+ opAndTwoTypes{ORSH, TUINT32, TUINT16}: ssa.OpRsh32Ux16,
+ opAndTwoTypes{ORSH, TINT32, TUINT32}: ssa.OpRsh32x32,
+ opAndTwoTypes{ORSH, TUINT32, TUINT32}: ssa.OpRsh32Ux32,
+ opAndTwoTypes{ORSH, TINT32, TUINT64}: ssa.OpRsh32x64,
+ opAndTwoTypes{ORSH, TUINT32, TUINT64}: ssa.OpRsh32Ux64,
+
+ opAndTwoTypes{ORSH, TINT64, TUINT8}: ssa.OpRsh64x8,
+ opAndTwoTypes{ORSH, TUINT64, TUINT8}: ssa.OpRsh64Ux8,
+ opAndTwoTypes{ORSH, TINT64, TUINT16}: ssa.OpRsh64x16,
+ opAndTwoTypes{ORSH, TUINT64, TUINT16}: ssa.OpRsh64Ux16,
+ opAndTwoTypes{ORSH, TINT64, TUINT32}: ssa.OpRsh64x32,
+ opAndTwoTypes{ORSH, TUINT64, TUINT32}: ssa.OpRsh64Ux32,
+ opAndTwoTypes{ORSH, TINT64, TUINT64}: ssa.OpRsh64x64,
+ opAndTwoTypes{ORSH, TUINT64, TUINT64}: ssa.OpRsh64Ux64,
+}
+
+func (s *state) ssaShiftOp(op uint8, t *Type, u *Type) ssa.Op {
+ etype1 := s.concreteEtype(t)
+ etype2 := s.concreteEtype(u)
+ x, ok := shiftOpToSSA[opAndTwoTypes{op, etype1, etype2}]
+ if !ok {
+ s.Unimplementedf("unhandled shift op %s etype=%s/%s", opnames[op], Econv(int(etype1), 0), Econv(int(etype2), 0))
+ }
+ return x
+}
+
+func (s *state) ssaRotateOp(op uint8, t *Type) ssa.Op {
+ etype1 := s.concreteEtype(t)
+ x, ok := opToSSA[opAndType{op, etype1}]
+ if !ok {
+ s.Unimplementedf("unhandled rotate op %s etype=%s", opnames[op], Econv(int(etype1), 0))
+ }
+ return x
+}
+
+// expr converts the expression n to ssa, adds it to s and returns the ssa result.
+func (s *state) expr(n *Node) *ssa.Value {
+ s.pushLine(n.Lineno)
+ defer s.popLine()
+
+ s.stmtList(n.Ninit)
+ switch n.Op {
+ case OCFUNC:
+ aux := s.lookupSymbol(n, &ssa.ExternSymbol{n.Type, n.Left.Sym})
+ return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
+ case OPARAM:
+ addr := s.addr(n, false)
+ return s.newValue2(ssa.OpLoad, n.Left.Type, addr, s.mem())
+ case ONAME:
+ if n.Class == PFUNC {
+ // "value" of a function is the address of the function's closure
+ sym := funcsym(n.Sym)
+ aux := &ssa.ExternSymbol{n.Type, sym}
+ return s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sb)
+ }
+ if canSSA(n) {
+ return s.variable(n, n.Type)
+ }
+ addr := s.addr(n, false)
+ return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
+ case OCLOSUREVAR:
+ addr := s.addr(n, false)
+ return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
+ case OLITERAL:
+ switch n.Val().Ctype() {
+ case CTINT:
+ i := Mpgetfix(n.Val().U.(*Mpint))
+ switch n.Type.Size() {
+ case 1:
+ return s.constInt8(n.Type, int8(i))
+ case 2:
+ return s.constInt16(n.Type, int16(i))
+ case 4:
+ return s.constInt32(n.Type, int32(i))
+ case 8:
+ return s.constInt64(n.Type, i)
+ default:
+ s.Fatalf("bad integer size %d", n.Type.Size())
+ return nil
+ }
+ case CTSTR:
+ return s.entryNewValue0A(ssa.OpConstString, n.Type, n.Val().U)
+ case CTBOOL:
+ return s.constBool(n.Val().U.(bool))
+ case CTNIL:
+ t := n.Type
+ switch {
+ case t.IsSlice():
+ return s.entryNewValue0(ssa.OpConstSlice, t)
+ case t.IsInterface():
+ return s.entryNewValue0(ssa.OpConstInterface, t)
+ default:
+ return s.entryNewValue0(ssa.OpConstNil, t)
+ }
+ case CTFLT:
+ f := n.Val().U.(*Mpflt)
+ switch n.Type.Size() {
+ case 4:
+ // -0.0 literals need to be treated as if they were 0.0, adding 0.0 here
+ // accomplishes this while not affecting other values.
+ return s.constFloat32(n.Type, mpgetflt32(f)+0.0)
+ case 8:
+ return s.constFloat64(n.Type, mpgetflt(f)+0.0)
+ default:
+ s.Fatalf("bad float size %d", n.Type.Size())
+ return nil
+ }
+ case CTCPLX:
+ c := n.Val().U.(*Mpcplx)
+ r := &c.Real
+ i := &c.Imag
+ switch n.Type.Size() {
+ case 8:
+ {
+ pt := Types[TFLOAT32]
+ // -0.0 literals need to be treated as if they were 0.0, adding 0.0 here
+ // accomplishes this while not affecting other values.
+ return s.newValue2(ssa.OpComplexMake, n.Type,
+ s.constFloat32(pt, mpgetflt32(r)+0.0),
+ s.constFloat32(pt, mpgetflt32(i)+0.0))
+ }
+ case 16:
+ {
+ pt := Types[TFLOAT64]
+ return s.newValue2(ssa.OpComplexMake, n.Type,
+ s.constFloat64(pt, mpgetflt(r)+0.0),
+ s.constFloat64(pt, mpgetflt(i)+0.0))
+ }
+ default:
+ s.Fatalf("bad float size %d", n.Type.Size())
+ return nil
+ }
+
+ default:
+ s.Unimplementedf("unhandled OLITERAL %v", n.Val().Ctype())
+ return nil
+ }
+ case OCONVNOP:
+ to := n.Type
+ from := n.Left.Type
+
+ // Assume everything will work out, so set up our return value.
+ // Anything interesting that happens from here is a fatal.
+ x := s.expr(n.Left)
+ v := s.newValue1(ssa.OpCopy, to, x) // ensure that v has the right type
+
+ // CONVNOP closure
+ if to.Etype == TFUNC && from.IsPtr() {
+ return v
+ }
+
+ // named <--> unnamed type or typed <--> untyped const
+ if from.Etype == to.Etype {
+ return v
+ }
+ // unsafe.Pointer <--> *T
+ if to.Etype == TUNSAFEPTR && from.IsPtr() || from.Etype == TUNSAFEPTR && to.IsPtr() {
+ return v
+ }
+
+ dowidth(from)
+ dowidth(to)
+ if from.Width != to.Width {
+ s.Fatalf("CONVNOP width mismatch %v (%d) -> %v (%d)\n", from, from.Width, to, to.Width)
+ return nil
+ }
+ if etypesign(from.Etype) != etypesign(to.Etype) {
+ s.Fatalf("CONVNOP sign mismatch %v (%s) -> %v (%s)\n", from, Econv(int(from.Etype), 0), to, Econv(int(to.Etype), 0))
+ return nil
+ }
+
+ if flag_race != 0 {
+ // These appear to be fine, but they fail the
+ // integer constraint below, so okay them here.
+ // Sample non-integer conversion: map[string]string -> *uint8
+ return v
+ }
+
+ if etypesign(from.Etype) == 0 {
+ s.Fatalf("CONVNOP unrecognized non-integer %v -> %v\n", from, to)
+ return nil
+ }
+
+ // integer, same width, same sign
+ return v
+
+ case OCONV:
+ x := s.expr(n.Left)
+ ft := n.Left.Type // from type
+ tt := n.Type // to type
+ if ft.IsInteger() && tt.IsInteger() {
+ var op ssa.Op
+ if tt.Size() == ft.Size() {
+ op = ssa.OpCopy
+ } else if tt.Size() < ft.Size() {
+ // truncation
+ switch 10*ft.Size() + tt.Size() {
+ case 21:
+ op = ssa.OpTrunc16to8
+ case 41:
+ op = ssa.OpTrunc32to8
+ case 42:
+ op = ssa.OpTrunc32to16
+ case 81:
+ op = ssa.OpTrunc64to8
+ case 82:
+ op = ssa.OpTrunc64to16
+ case 84:
+ op = ssa.OpTrunc64to32
+ default:
+ s.Fatalf("weird integer truncation %s -> %s", ft, tt)
+ }
+ } else if ft.IsSigned() {
+ // sign extension
+ switch 10*ft.Size() + tt.Size() {
+ case 12:
+ op = ssa.OpSignExt8to16
+ case 14:
+ op = ssa.OpSignExt8to32
+ case 18:
+ op = ssa.OpSignExt8to64
+ case 24:
+ op = ssa.OpSignExt16to32
+ case 28:
+ op = ssa.OpSignExt16to64
+ case 48:
+ op = ssa.OpSignExt32to64
+ default:
+ s.Fatalf("bad integer sign extension %s -> %s", ft, tt)
+ }
+ } else {
+ // zero extension
+ switch 10*ft.Size() + tt.Size() {
+ case 12:
+ op = ssa.OpZeroExt8to16
+ case 14:
+ op = ssa.OpZeroExt8to32
+ case 18:
+ op = ssa.OpZeroExt8to64
+ case 24:
+ op = ssa.OpZeroExt16to32
+ case 28:
+ op = ssa.OpZeroExt16to64
+ case 48:
+ op = ssa.OpZeroExt32to64
+ default:
+ s.Fatalf("weird integer sign extension %s -> %s", ft, tt)
+ }
+ }
+ return s.newValue1(op, n.Type, x)
+ }
+
+ if ft.IsFloat() || tt.IsFloat() {
+ conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
+ if !ok {
+ s.Fatalf("weird float conversion %s -> %s", ft, tt)
+ }
+ op1, op2, it := conv.op1, conv.op2, conv.intermediateType
+
+ if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
+ // normal case, not tripping over unsigned 64
+ if op1 == ssa.OpCopy {
+ if op2 == ssa.OpCopy {
+ return x
+ }
+ return s.newValue1(op2, n.Type, x)
+ }
+ if op2 == ssa.OpCopy {
+ return s.newValue1(op1, n.Type, x)
+ }
+ return s.newValue1(op2, n.Type, s.newValue1(op1, Types[it], x))
+ }
+ // Tricky 64-bit unsigned cases.
+ if ft.IsInteger() {
+ // therefore tt is float32 or float64, and ft is also unsigned
+ if tt.Size() == 4 {
+ return s.uint64Tofloat32(n, x, ft, tt)
+ }
+ if tt.Size() == 8 {
+ return s.uint64Tofloat64(n, x, ft, tt)
+ }
+ s.Fatalf("weird unsigned integer to float conversion %s -> %s", ft, tt)
+ }
+ // therefore ft is float32 or float64, and tt is unsigned integer
+ if ft.Size() == 4 {
+ return s.float32ToUint64(n, x, ft, tt)
+ }
+ if ft.Size() == 8 {
+ return s.float64ToUint64(n, x, ft, tt)
+ }
+ s.Fatalf("weird float to unsigned integer conversion %s -> %s", ft, tt)
+ return nil
+ }
+
+ if ft.IsComplex() && tt.IsComplex() {
+ var op ssa.Op
+ if ft.Size() == tt.Size() {
+ op = ssa.OpCopy
+ } else if ft.Size() == 8 && tt.Size() == 16 {
+ op = ssa.OpCvt32Fto64F
+ } else if ft.Size() == 16 && tt.Size() == 8 {
+ op = ssa.OpCvt64Fto32F
+ } else {
+ s.Fatalf("weird complex conversion %s -> %s", ft, tt)
+ }
+ ftp := floatForComplex(ft)
+ ttp := floatForComplex(tt)
+ return s.newValue2(ssa.OpComplexMake, tt,
+ s.newValue1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, x)),
+ s.newValue1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x)))
+ }
+
+ s.Unimplementedf("unhandled OCONV %s -> %s", Econv(int(n.Left.Type.Etype), 0), Econv(int(n.Type.Etype), 0))
+ return nil
+
+ case ODOTTYPE:
+ res, _ := s.dottype(n, false)
+ return res
+
+ // binary ops
+ case OLT, OEQ, ONE, OLE, OGE, OGT:
+ a := s.expr(n.Left)
+ b := s.expr(n.Right)
+ if n.Left.Type.IsComplex() {
+ pt := floatForComplex(n.Left.Type)
+ op := s.ssaOp(OEQ, pt)
+ r := s.newValue2(op, Types[TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b))
+ i := s.newValue2(op, Types[TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))
+ c := s.newValue2(ssa.OpAnd8, Types[TBOOL], r, i)
+ switch n.Op {
+ case OEQ:
+ return c
+ case ONE:
+ return s.newValue1(ssa.OpNot, Types[TBOOL], c)
+ default:
+ s.Fatalf("ordered complex compare %s", opnames[n.Op])
+ }
+ }
+ return s.newValue2(s.ssaOp(n.Op, n.Left.Type), Types[TBOOL], a, b)
+ case OMUL:
+ a := s.expr(n.Left)
+ b := s.expr(n.Right)
+ if n.Type.IsComplex() {
+ mulop := ssa.OpMul64F
+ addop := ssa.OpAdd64F
+ subop := ssa.OpSub64F
+ pt := floatForComplex(n.Type) // Could be Float32 or Float64
+ wt := Types[TFLOAT64] // Compute in Float64 to minimize cancellation error
+
+ areal := s.newValue1(ssa.OpComplexReal, pt, a)
+ breal := s.newValue1(ssa.OpComplexReal, pt, b)
+ aimag := s.newValue1(ssa.OpComplexImag, pt, a)
+ bimag := s.newValue1(ssa.OpComplexImag, pt, b)
+
+ if pt != wt { // Widen for calculation
+ areal = s.newValue1(ssa.OpCvt32Fto64F, wt, areal)
+ breal = s.newValue1(ssa.OpCvt32Fto64F, wt, breal)
+ aimag = s.newValue1(ssa.OpCvt32Fto64F, wt, aimag)
+ bimag = s.newValue1(ssa.OpCvt32Fto64F, wt, bimag)
+ }
+
+ xreal := s.newValue2(subop, wt, s.newValue2(mulop, wt, areal, breal), s.newValue2(mulop, wt, aimag, bimag))
+ ximag := s.newValue2(addop, wt, s.newValue2(mulop, wt, areal, bimag), s.newValue2(mulop, wt, aimag, breal))
+
+ if pt != wt { // Narrow to store back
+ xreal = s.newValue1(ssa.OpCvt64Fto32F, pt, xreal)
+ ximag = s.newValue1(ssa.OpCvt64Fto32F, pt, ximag)
+ }
+
+ return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag)
+ }
+ return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+
+ case ODIV:
+ a := s.expr(n.Left)
+ b := s.expr(n.Right)
+ if n.Type.IsComplex() {
+ // TODO this is not executed because the front-end substitutes a runtime call.
+ // That probably ought to change; with modest optimization the widen/narrow
+ // conversions could all be elided in larger expression trees.
+ mulop := ssa.OpMul64F
+ addop := ssa.OpAdd64F
+ subop := ssa.OpSub64F
+ divop := ssa.OpDiv64F
+ pt := floatForComplex(n.Type) // Could be Float32 or Float64
+ wt := Types[TFLOAT64] // Compute in Float64 to minimize cancellation error
+
+ areal := s.newValue1(ssa.OpComplexReal, pt, a)
+ breal := s.newValue1(ssa.OpComplexReal, pt, b)
+ aimag := s.newValue1(ssa.OpComplexImag, pt, a)
+ bimag := s.newValue1(ssa.OpComplexImag, pt, b)
+
+ if pt != wt { // Widen for calculation
+ areal = s.newValue1(ssa.OpCvt32Fto64F, wt, areal)
+ breal = s.newValue1(ssa.OpCvt32Fto64F, wt, breal)
+ aimag = s.newValue1(ssa.OpCvt32Fto64F, wt, aimag)
+ bimag = s.newValue1(ssa.OpCvt32Fto64F, wt, bimag)
+ }
+
+ denom := s.newValue2(addop, wt, s.newValue2(mulop, wt, breal, breal), s.newValue2(mulop, wt, bimag, bimag))
+ xreal := s.newValue2(addop, wt, s.newValue2(mulop, wt, areal, breal), s.newValue2(mulop, wt, aimag, bimag))
+ ximag := s.newValue2(subop, wt, s.newValue2(mulop, wt, aimag, breal), s.newValue2(mulop, wt, areal, bimag))
+
+ // TODO not sure if this is best done in wide precision or narrow
+ // Double-rounding might be an issue.
+ // Note that the pre-SSA implementation does the entire calculation
+ // in wide format, so wide is compatible.
+ xreal = s.newValue2(divop, wt, xreal, denom)
+ ximag = s.newValue2(divop, wt, ximag, denom)
+
+ if pt != wt { // Narrow to store back
+ xreal = s.newValue1(ssa.OpCvt64Fto32F, pt, xreal)
+ ximag = s.newValue1(ssa.OpCvt64Fto32F, pt, ximag)
+ }
+
+ return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag)
+ }
+ return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+ case OADD, OSUB:
+ a := s.expr(n.Left)
+ b := s.expr(n.Right)
+ if n.Type.IsComplex() {
+ pt := floatForComplex(n.Type)
+ op := s.ssaOp(n.Op, pt)
+ return s.newValue2(ssa.OpComplexMake, n.Type,
+ s.newValue2(op, pt, s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b)),
+ s.newValue2(op, pt, s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)))
+ }
+ return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+ case OAND, OOR, OMOD, OHMUL, OXOR:
+ a := s.expr(n.Left)
+ b := s.expr(n.Right)
+ return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+ case OLSH, ORSH:
+ a := s.expr(n.Left)
+ b := s.expr(n.Right)
+ return s.newValue2(s.ssaShiftOp(n.Op, n.Type, n.Right.Type), a.Type, a, b)
+ case OLROT:
+ a := s.expr(n.Left)
+ i := n.Right.Int()
+ if i <= 0 || i >= n.Type.Size()*8 {
+ s.Fatalf("Wrong rotate distance for LROT, expected 1 through %d, saw %d", n.Type.Size()*8-1, i)
+ }
+ return s.newValue1I(s.ssaRotateOp(n.Op, n.Type), a.Type, i, a)
+ case OANDAND, OOROR:
+ // To implement OANDAND (and OOROR), we introduce a
+ // new temporary variable to hold the result. The
+ // variable is associated with the OANDAND node in the
+ // s.vars table (normally variables are only
+ // associated with ONAME nodes). We convert
+ // A && B
+ // to
+ // var = A
+ // if var {
+ // var = B
+ // }
+ // Using var in the subsequent block introduces the
+ // necessary phi variable.
+ el := s.expr(n.Left)
+ s.vars[n] = el
+
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = el
+ // In theory, we should set b.Likely here based on context.
+ // However, gc only gives us likeliness hints
+ // in a single place, for plain OIF statements,
+ // and passing around context is finnicky, so don't bother for now.
+
+ bRight := s.f.NewBlock(ssa.BlockPlain)
+ bResult := s.f.NewBlock(ssa.BlockPlain)
+ if n.Op == OANDAND {
+ b.AddEdgeTo(bRight)
+ b.AddEdgeTo(bResult)
+ } else if n.Op == OOROR {
+ b.AddEdgeTo(bResult)
+ b.AddEdgeTo(bRight)
+ }
+
+ s.startBlock(bRight)
+ er := s.expr(n.Right)
+ s.vars[n] = er
+
+ b = s.endBlock()
+ b.AddEdgeTo(bResult)
+
+ s.startBlock(bResult)
+ return s.variable(n, Types[TBOOL])
+ case OCOMPLEX:
+ r := s.expr(n.Left)
+ i := s.expr(n.Right)
+ return s.newValue2(ssa.OpComplexMake, n.Type, r, i)
+
+ // unary ops
+ case OMINUS:
+ a := s.expr(n.Left)
+ if n.Type.IsComplex() {
+ tp := floatForComplex(n.Type)
+ negop := s.ssaOp(n.Op, tp)
+ return s.newValue2(ssa.OpComplexMake, n.Type,
+ s.newValue1(negop, tp, s.newValue1(ssa.OpComplexReal, tp, a)),
+ s.newValue1(negop, tp, s.newValue1(ssa.OpComplexImag, tp, a)))
+ }
+ return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a)
+ case ONOT, OCOM, OSQRT:
+ a := s.expr(n.Left)
+ return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a)
+ case OIMAG, OREAL:
+ a := s.expr(n.Left)
+ return s.newValue1(s.ssaOp(n.Op, n.Left.Type), n.Type, a)
+ case OPLUS:
+ return s.expr(n.Left)
+
+ case OADDR:
+ return s.addr(n.Left, n.Bounded)
+
+ case OINDREG:
+ if int(n.Reg) != Thearch.REGSP {
+ s.Unimplementedf("OINDREG of non-SP register %s in expr: %v", obj.Rconv(int(n.Reg)), n)
+ return nil
+ }
+ addr := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.sp)
+ return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
+
+ case OIND:
+ p := s.expr(n.Left)
+ s.nilCheck(p)
+ return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
+
+ case ODOT:
+ // TODO: fix when we can SSA struct types.
+ p := s.addr(n, false)
+ return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
+
+ case ODOTPTR:
+ p := s.expr(n.Left)
+ s.nilCheck(p)
+ p = s.newValue2(ssa.OpAddPtr, p.Type, p, s.constIntPtr(Types[TUINTPTR], n.Xoffset))
+ return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
+
+ case OINDEX:
+ switch {
+ case n.Left.Type.IsString():
+ a := s.expr(n.Left)
+ i := s.expr(n.Right)
+ i = s.extendIndex(i)
+ if !n.Bounded {
+ len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
+ s.boundsCheck(i, len)
+ }
+ ptrtyp := Ptrto(Types[TUINT8])
+ ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
+ ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i)
+ return s.newValue2(ssa.OpLoad, Types[TUINT8], ptr, s.mem())
+ case n.Left.Type.IsSlice():
+ p := s.addr(n, false)
+ return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())
+ case n.Left.Type.IsArray():
+ // TODO: fix when we can SSA arrays of length 1.
+ p := s.addr(n, false)
+ return s.newValue2(ssa.OpLoad, n.Left.Type.Type, p, s.mem())
+ default:
+ s.Fatalf("bad type for index %v", n.Left.Type)
+ return nil
+ }
+
+ case OLEN, OCAP:
+ switch {
+ case n.Left.Type.IsSlice():
+ op := ssa.OpSliceLen
+ if n.Op == OCAP {
+ op = ssa.OpSliceCap
+ }
+ return s.newValue1(op, Types[TINT], s.expr(n.Left))
+ case n.Left.Type.IsString(): // string; not reachable for OCAP
+ return s.newValue1(ssa.OpStringLen, Types[TINT], s.expr(n.Left))
+ case n.Left.Type.IsMap(), n.Left.Type.IsChan():
+ return s.referenceTypeBuiltin(n, s.expr(n.Left))
+ default: // array
+ return s.constInt(Types[TINT], n.Left.Type.Bound)
+ }
+
+ case OSPTR:
+ a := s.expr(n.Left)
+ if n.Left.Type.IsSlice() {
+ return s.newValue1(ssa.OpSlicePtr, n.Type, a)
+ } else {
+ return s.newValue1(ssa.OpStringPtr, n.Type, a)
+ }
+
+ case OITAB:
+ a := s.expr(n.Left)
+ return s.newValue1(ssa.OpITab, n.Type, a)
+
+ case OEFACE:
+ tab := s.expr(n.Left)
+ data := s.expr(n.Right)
+ // The frontend allows putting things like struct{*byte} in
+ // the data portion of an eface. But we don't want struct{*byte}
+ // as a register type because (among other reasons) the liveness
+ // analysis is confused by the "fat" variables that result from
+ // such types being spilled.
+ // So here we ensure that we are selecting the underlying pointer
+ // when we build an eface.
+ for !data.Type.IsPtr() {
+ switch {
+ case data.Type.IsArray():
+ data = s.newValue2(ssa.OpArrayIndex, data.Type.Elem(), data, s.constInt(Types[TINT], 0))
+ case data.Type.IsStruct():
+ for i := data.Type.NumFields() - 1; i >= 0; i-- {
+ f := data.Type.FieldType(i)
+ if f.Size() == 0 {
+ // eface type could also be struct{p *byte; q [0]int}
+ continue
+ }
+ data = s.newValue1I(ssa.OpStructSelect, f, data.Type.FieldOff(i), data)
+ break
+ }
+ default:
+ s.Fatalf("type being put into an eface isn't a pointer")
+ }
+ }
+ return s.newValue2(ssa.OpIMake, n.Type, tab, data)
+
+ case OSLICE, OSLICEARR:
+ v := s.expr(n.Left)
+ var i, j *ssa.Value
+ if n.Right.Left != nil {
+ i = s.extendIndex(s.expr(n.Right.Left))
+ }
+ if n.Right.Right != nil {
+ j = s.extendIndex(s.expr(n.Right.Right))
+ }
+ p, l, c := s.slice(n.Left.Type, v, i, j, nil)
+ return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
+ case OSLICESTR:
+ v := s.expr(n.Left)
+ var i, j *ssa.Value
+ if n.Right.Left != nil {
+ i = s.extendIndex(s.expr(n.Right.Left))
+ }
+ if n.Right.Right != nil {
+ j = s.extendIndex(s.expr(n.Right.Right))
+ }
+ p, l, _ := s.slice(n.Left.Type, v, i, j, nil)
+ return s.newValue2(ssa.OpStringMake, n.Type, p, l)
+ case OSLICE3, OSLICE3ARR:
+ v := s.expr(n.Left)
+ var i *ssa.Value
+ if n.Right.Left != nil {
+ i = s.extendIndex(s.expr(n.Right.Left))
+ }
+ j := s.extendIndex(s.expr(n.Right.Right.Left))
+ k := s.extendIndex(s.expr(n.Right.Right.Right))
+ p, l, c := s.slice(n.Left.Type, v, i, j, k)
+ return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
+
+ case OCALLFUNC, OCALLINTER, OCALLMETH:
+ return s.call(n, callNormal)
+
+ case OGETG:
+ return s.newValue0(ssa.OpGetG, n.Type)
+
+ case OAPPEND:
+ // append(s, e1, e2, e3). Compile like:
+ // ptr,len,cap := s
+ // newlen := len + 3
+ // if newlen > s.cap {
+ // ptr,_,cap = growslice(s, newlen)
+ // }
+ // *(ptr+len) = e1
+ // *(ptr+len+1) = e2
+ // *(ptr+len+2) = e3
+ // makeslice(ptr,newlen,cap)
+
+ et := n.Type.Type
+ pt := Ptrto(et)
+
+ // Evaluate slice
+ slice := s.expr(n.List.N)
+
+ // Allocate new blocks
+ grow := s.f.NewBlock(ssa.BlockPlain)
+ assign := s.f.NewBlock(ssa.BlockPlain)
+
+ // Decide if we need to grow
+ nargs := int64(count(n.List) - 1)
+ p := s.newValue1(ssa.OpSlicePtr, pt, slice)
+ l := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
+ c := s.newValue1(ssa.OpSliceCap, Types[TINT], slice)
+ nl := s.newValue2(s.ssaOp(OADD, Types[TINT]), Types[TINT], l, s.constInt(Types[TINT], nargs))
+ cmp := s.newValue2(s.ssaOp(OGT, Types[TINT]), Types[TBOOL], nl, c)
+ s.vars[&ptrVar] = p
+ s.vars[&capVar] = c
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Likely = ssa.BranchUnlikely
+ b.Control = cmp
+ b.AddEdgeTo(grow)
+ b.AddEdgeTo(assign)
+
+ // Call growslice
+ s.startBlock(grow)
+ taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Types[TUINTPTR], typenamesym(n.Type)}, s.sb)
+
+ r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl)
+
+ s.vars[&ptrVar] = r[0]
+ // Note: we don't need to read r[1], the result's length. It will be nl.
+ // (or maybe we should, we just have to spill/restore nl otherwise?)
+ s.vars[&capVar] = r[2]
+ b = s.endBlock()
+ b.AddEdgeTo(assign)
+
+ // assign new elements to slots
+ s.startBlock(assign)
+
+ // Evaluate args
+ args := make([]*ssa.Value, 0, nargs)
+ store := make([]bool, 0, nargs)
+ for l := n.List.Next; l != nil; l = l.Next {
+ if canSSAType(l.N.Type) {
+ args = append(args, s.expr(l.N))
+ store = append(store, true)
+ } else {
+ args = append(args, s.addr(l.N, false))
+ store = append(store, false)
+ }
+ }
+
+ p = s.variable(&ptrVar, pt) // generates phi for ptr
+ c = s.variable(&capVar, Types[TINT]) // generates phi for cap
+ p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l)
+ for i, arg := range args {
+ addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(Types[TUINTPTR], int64(i)))
+ if store[i] {
+ s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, et.Size(), addr, arg, s.mem())
+ } else {
+ s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, et.Size(), addr, arg, s.mem())
+ }
+ if haspointers(et) {
+ // TODO: just one write barrier call for all of these writes?
+ // TODO: maybe just one writeBarrierEnabled check?
+ s.insertWB(et, addr)
+ }
+ }
+
+ // make result
+ delete(s.vars, &ptrVar)
+ delete(s.vars, &capVar)
+ return s.newValue3(ssa.OpSliceMake, n.Type, p, nl, c)
+
+ default:
+ s.Unimplementedf("unhandled expr %s", opnames[n.Op])
+ return nil
+ }
+}
+
+func (s *state) assign(left *Node, right *ssa.Value, wb bool) {
+ if left.Op == ONAME && isblank(left) {
+ return
+ }
+ t := left.Type
+ dowidth(t)
+ if right == nil {
+ // right == nil means use the zero value of the assigned type.
+ if !canSSA(left) {
+ // if we can't ssa this memory, treat it as just zeroing out the backing memory
+ addr := s.addr(left, false)
+ if left.Op == ONAME {
+ s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, left, s.mem())
+ }
+ s.vars[&memVar] = s.newValue2I(ssa.OpZero, ssa.TypeMem, t.Size(), addr, s.mem())
+ return
+ }
+ right = s.zeroVal(t)
+ }
+ if left.Op == ONAME && canSSA(left) {
+ // Update variable assignment.
+ s.vars[left] = right
+ return
+ }
+ // not ssa-able. Treat as a store.
+ addr := s.addr(left, false)
+ if left.Op == ONAME {
+ s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, left, s.mem())
+ }
+ s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), addr, right, s.mem())
+ if wb {
+ s.insertWB(left.Type, addr)
+ }
+}
+
+// zeroVal returns the zero value for type t.
+func (s *state) zeroVal(t *Type) *ssa.Value {
+ switch {
+ case t.IsInteger():
+ switch t.Size() {
+ case 1:
+ return s.constInt8(t, 0)
+ case 2:
+ return s.constInt16(t, 0)
+ case 4:
+ return s.constInt32(t, 0)
+ case 8:
+ return s.constInt64(t, 0)
+ default:
+ s.Fatalf("bad sized integer type %s", t)
+ }
+ case t.IsFloat():
+ switch t.Size() {
+ case 4:
+ return s.constFloat32(t, 0)
+ case 8:
+ return s.constFloat64(t, 0)
+ default:
+ s.Fatalf("bad sized float type %s", t)
+ }
+ case t.IsComplex():
+ switch t.Size() {
+ case 8:
+ z := s.constFloat32(Types[TFLOAT32], 0)
+ return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
+ case 16:
+ z := s.constFloat64(Types[TFLOAT64], 0)
+ return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
+ default:
+ s.Fatalf("bad sized complex type %s", t)
+ }
+
+ case t.IsString():
+ return s.entryNewValue0A(ssa.OpConstString, t, "")
+ case t.IsPtr():
+ return s.entryNewValue0(ssa.OpConstNil, t)
+ case t.IsBoolean():
+ return s.constBool(false)
+ case t.IsInterface():
+ return s.entryNewValue0(ssa.OpConstInterface, t)
+ case t.IsSlice():
+ return s.entryNewValue0(ssa.OpConstSlice, t)
+ }
+ s.Unimplementedf("zero for type %v not implemented", t)
+ return nil
+}
+
+type callKind int8
+
+const (
+ callNormal callKind = iota
+ callDefer
+ callGo
+)
+
+func (s *state) call(n *Node, k callKind) *ssa.Value {
+ var sym *Sym // target symbol (if static)
+ var closure *ssa.Value // ptr to closure to run (if dynamic)
+ var codeptr *ssa.Value // ptr to target code (if dynamic)
+ var rcvr *ssa.Value // receiver to set
+ fn := n.Left
+ switch n.Op {
+ case OCALLFUNC:
+ if k == callNormal && fn.Op == ONAME && fn.Class == PFUNC {
+ sym = fn.Sym
+ break
+ }
+ closure = s.expr(fn)
+ if closure == nil {
+ return nil // TODO: remove when expr always returns non-nil
+ }
+ case OCALLMETH:
+ if fn.Op != ODOTMETH {
+ Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
+ }
+ if fn.Right.Op != ONAME {
+ Fatalf("OCALLMETH: n.Left.Right not a ONAME: %v", fn.Right)
+ }
+ if k == callNormal {
+ sym = fn.Right.Sym
+ break
+ }
+ n2 := *fn.Right
+ n2.Class = PFUNC
+ closure = s.expr(&n2)
+ // Note: receiver is already assigned in n.List, so we don't
+ // want to set it here.
+ case OCALLINTER:
+ if fn.Op != ODOTINTER {
+ Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", Oconv(int(fn.Op), 0))
+ }
+ i := s.expr(fn.Left)
+ itab := s.newValue1(ssa.OpITab, Types[TUINTPTR], i)
+ itabidx := fn.Xoffset + 3*int64(Widthptr) + 8 // offset of fun field in runtime.itab
+ itab = s.newValue1I(ssa.OpOffPtr, Types[TUINTPTR], itabidx, itab)
+ if k == callNormal {
+ codeptr = s.newValue2(ssa.OpLoad, Types[TUINTPTR], itab, s.mem())
+ } else {
+ closure = itab
+ }
+ rcvr = s.newValue1(ssa.OpIData, Types[TUINTPTR], i)
+ }
+ dowidth(fn.Type)
+ stksize := fn.Type.Argwid // includes receiver
+
+ // Run all argument assignments. The arg slots have already
+ // been offset by the appropriate amount (+2*widthptr for go/defer,
+ // +widthptr for interface calls).
+ // For OCALLMETH, the receiver is set in these statements.
+ s.stmtList(n.List)
+
+ // Set receiver (for interface calls)
+ if rcvr != nil {
++ argStart := Ctxt.FixedFrameSize()
+ if k != callNormal {
+ argStart += int64(2 * Widthptr)
+ }
+ addr := s.entryNewValue1I(ssa.OpOffPtr, Types[TUINTPTR], argStart, s.sp)
+ s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
+ }
+
+ // Defer/go args
+ if k != callNormal {
+ // Write argsize and closure (args to Newproc/Deferproc).
+ argsize := s.constInt32(Types[TUINT32], int32(stksize))
+ s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, s.sp, argsize, s.mem())
+ addr := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(Types[TUINTPTR]), int64(Widthptr), s.sp)
+ s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
+ stksize += 2 * int64(Widthptr)
+ }
+
+ // call target
+ bNext := s.f.NewBlock(ssa.BlockPlain)
+ var call *ssa.Value
+ switch {
+ case k == callDefer:
+ call = s.newValue1(ssa.OpDeferCall, ssa.TypeMem, s.mem())
+ case k == callGo:
+ call = s.newValue1(ssa.OpGoCall, ssa.TypeMem, s.mem())
+ case closure != nil:
+ codeptr = s.newValue2(ssa.OpLoad, Types[TUINTPTR], closure, s.mem())
+ call = s.newValue3(ssa.OpClosureCall, ssa.TypeMem, codeptr, closure, s.mem())
+ case codeptr != nil:
+ call = s.newValue2(ssa.OpInterCall, ssa.TypeMem, codeptr, s.mem())
+ case sym != nil:
+ call = s.newValue1A(ssa.OpStaticCall, ssa.TypeMem, sym, s.mem())
+ default:
+ Fatalf("bad call type %s %v", opnames[n.Op], n)
+ }
+ call.AuxInt = stksize // Call operations carry the argsize of the callee along with them
+
+ // Finish call block
+ s.vars[&memVar] = call
+ b := s.endBlock()
+ b.Kind = ssa.BlockCall
+ b.Control = call
+ b.AddEdgeTo(bNext)
+
+ // Read result from stack at the start of the fallthrough block
+ s.startBlock(bNext)
+ var titer Iter
+ fp := Structfirst(&titer, Getoutarg(n.Left.Type))
+ if fp == nil || k != callNormal {
+ // call has no return value. Continue with the next statement.
+ return nil
+ }
+ a := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(fp.Type), fp.Width, s.sp)
+ return s.newValue2(ssa.OpLoad, fp.Type, a, call)
+}
+
+// etypesign returns the signed-ness of e, for integer/pointer etypes.
+// -1 means signed, +1 means unsigned, 0 means non-integer/non-pointer.
+func etypesign(e uint8) int8 {
+ switch e {
+ case TINT8, TINT16, TINT32, TINT64, TINT:
+ return -1
+ case TUINT8, TUINT16, TUINT32, TUINT64, TUINT, TUINTPTR, TUNSAFEPTR:
+ return +1
+ }
+ return 0
+}
+
+// lookupSymbol is used to retrieve the symbol (Extern, Arg or Auto) used for a particular node.
+// This improves the effectiveness of cse by using the same Aux values for the
+// same symbols.
+func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
+ switch sym.(type) {
+ default:
+ s.Fatalf("sym %v is of uknown type %T", sym, sym)
+ case *ssa.ExternSymbol, *ssa.ArgSymbol, *ssa.AutoSymbol:
+ // these are the only valid types
+ }
+
+ if lsym, ok := s.varsyms[n]; ok {
+ return lsym
+ } else {
+ s.varsyms[n] = sym
+ return sym
+ }
+}
+
+// addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
+// The value that the returned Value represents is guaranteed to be non-nil.
+// If bounded is true then this address does not require a nil check for its operand
+// even if that would otherwise be implied.
+func (s *state) addr(n *Node, bounded bool) *ssa.Value {
+ switch n.Op {
+ case ONAME:
+ switch n.Class {
+ case PEXTERN:
+ // global variable
+ aux := &ssa.ExternSymbol{n.Type, n.Sym}
+ v := s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sb)
+ // TODO: Make OpAddr use AuxInt as well as Aux.
+ if n.Xoffset != 0 {
+ v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, n.Xoffset, v)
+ }
+ return v
+ case PPARAM:
+ // parameter slot
+ v := s.decladdrs[n]
+ if v == nil {
+ if flag_race != 0 && n.String() == ".fp" {
+ s.Unimplementedf("race detector mishandles nodfp")
+ }
+ s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
+ }
+ return v
+ case PAUTO:
+ // We need to regenerate the address of autos
+ // at every use. This prevents LEA instructions
+ // from occurring before the corresponding VarDef
+ // op and confusing the liveness analysis into thinking
+ // the variable is live at function entry.
+ // TODO: I'm not sure if this really works or we're just
+ // getting lucky. We might need a real dependency edge
+ // between vardef and addr ops.
+ aux := &ssa.AutoSymbol{Typ: n.Type, Node: n}
+ return s.newValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp)
+ case PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
+ // ensure that we reuse symbols for out parameters so
+ // that cse works on their addresses
+ aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n})
+ return s.newValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp)
+ case PAUTO | PHEAP, PPARAM | PHEAP, PPARAMOUT | PHEAP, PPARAMREF:
+ return s.expr(n.Name.Heapaddr)
+ default:
+ s.Unimplementedf("variable address class %v not implemented", n.Class)
+ return nil
+ }
+ case OINDREG:
+ // indirect off a register
+ // used for storing/loading arguments/returns to/from callees
+ if int(n.Reg) != Thearch.REGSP {
+ s.Unimplementedf("OINDREG of non-SP register %s in addr: %v", obj.Rconv(int(n.Reg)), n)
+ return nil
+ }
+ return s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.sp)
+ case OINDEX:
+ if n.Left.Type.IsSlice() {
+ a := s.expr(n.Left)
+ i := s.expr(n.Right)
+ i = s.extendIndex(i)
+ len := s.newValue1(ssa.OpSliceLen, Types[TUINTPTR], a)
+ if !n.Bounded {
+ s.boundsCheck(i, len)
+ }
+ p := s.newValue1(ssa.OpSlicePtr, Ptrto(n.Left.Type.Type), a)
+ return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), p, i)
+ } else { // array
+ a := s.addr(n.Left, bounded)
+ i := s.expr(n.Right)
+ i = s.extendIndex(i)
+ len := s.constInt(Types[TINT], n.Left.Type.Bound)
+ if !n.Bounded {
+ s.boundsCheck(i, len)
+ }
+ return s.newValue2(ssa.OpPtrIndex, Ptrto(n.Left.Type.Type), a, i)
+ }
+ case OIND:
+ p := s.expr(n.Left)
+ if !bounded {
+ s.nilCheck(p)
+ }
+ return p
+ case ODOT:
+ p := s.addr(n.Left, bounded)
+ return s.newValue2(ssa.OpAddPtr, p.Type, p, s.constIntPtr(Types[TUINTPTR], n.Xoffset))
+ case ODOTPTR:
+ p := s.expr(n.Left)
+ if !bounded {
+ s.nilCheck(p)
+ }
+ return s.newValue2(ssa.OpAddPtr, p.Type, p, s.constIntPtr(Types[TUINTPTR], n.Xoffset))
+ case OCLOSUREVAR:
+ return s.newValue2(ssa.OpAddPtr, Ptrto(n.Type),
+ s.entryNewValue0(ssa.OpGetClosurePtr, Types[TUINTPTR]),
+ s.constIntPtr(Types[TUINTPTR], n.Xoffset))
+ case OPARAM:
+ p := n.Left
+ if p.Op != ONAME || !(p.Class == PPARAM|PHEAP || p.Class == PPARAMOUT|PHEAP) {
+ s.Fatalf("OPARAM not of ONAME,{PPARAM,PPARAMOUT}|PHEAP, instead %s", nodedump(p, 0))
+ }
+
+ // Recover original offset to address passed-in param value.
+ original_p := *p
+ original_p.Xoffset = n.Xoffset
+ aux := &ssa.ArgSymbol{Typ: n.Type, Node: &original_p}
+ return s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp)
+ case OCONVNOP:
+ addr := s.addr(n.Left, bounded)
+ to := Ptrto(n.Type)
+ return s.newValue1(ssa.OpCopy, to, addr) // ensure that addr has the right type
+
+ default:
+ s.Unimplementedf("unhandled addr %v", Oconv(int(n.Op), 0))
+ return nil
+ }
+}
+
+// canSSA reports whether n is SSA-able.
+// n must be an ONAME.
+func canSSA(n *Node) bool {
+ if n.Op != ONAME {
+ return false
+ }
+ if n.Addrtaken {
+ return false
+ }
+ if n.Class&PHEAP != 0 {
+ return false
+ }
+ switch n.Class {
+ case PEXTERN, PPARAMOUT, PPARAMREF:
+ return false
+ }
+ if n.Class == PPARAM && n.String() == ".this" {
+ // wrappers generated by genwrapper need to update
+ // the .this pointer in place.
+ return false
+ }
+ return canSSAType(n.Type)
+ // TODO: try to make more variables SSAable?
+}
+
+// canSSA reports whether variables of type t are SSA-able.
+func canSSAType(t *Type) bool {
+ dowidth(t)
+ if t.Width > int64(4*Widthptr) {
+ // 4*Widthptr is an arbitrary constant. We want it
+ // to be at least 3*Widthptr so slices can be registerized.
+ // Too big and we'll introduce too much register pressure.
+ return false
+ }
+ switch t.Etype {
+ case TARRAY:
+ if Isslice(t) {
+ return true
+ }
+ // We can't do arrays because dynamic indexing is
+ // not supported on SSA variables.
+ // TODO: maybe allow if length is <=1? All indexes
+ // are constant? Might be good for the arrays
+ // introduced by the compiler for variadic functions.
+ return false
+ case TSTRUCT:
+ if countfield(t) > 4 {
+ // 4 is an arbitrary constant. Same reasoning
+ // as above, lots of small fields would waste
+ // register space needed by other values.
+ return false
+ }
+ for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ if !canSSAType(t1.Type) {
+ return false
+ }
+ }
+ return false // until it is implemented
+ //return true
+ default:
+ return true
+ }
+}
+
+// nilCheck generates nil pointer checking code.
+// Starts a new block on return, unless nil checks are disabled.
+// Used only for automatically inserted nil checks,
+// not for user code like 'x != nil'.
+func (s *state) nilCheck(ptr *ssa.Value) {
+ if Disable_checknil != 0 {
+ return
+ }
+ c := s.newValue1(ssa.OpIsNonNil, Types[TBOOL], ptr)
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = c
+ b.Likely = ssa.BranchLikely
+ bNext := s.f.NewBlock(ssa.BlockPlain)
+ bPanic := s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(bNext)
+ b.AddEdgeTo(bPanic)
+ s.startBlock(bPanic)
+ // TODO: implicit nil checks somehow?
+ chk := s.newValue2(ssa.OpPanicNilCheck, ssa.TypeMem, ptr, s.mem())
+ s.endBlock()
+ bPanic.Kind = ssa.BlockExit
+ bPanic.Control = chk
+ s.startBlock(bNext)
+}
+
+// boundsCheck generates bounds checking code. Checks if 0 <= idx < len, branches to exit if not.
+// Starts a new block on return.
+func (s *state) boundsCheck(idx, len *ssa.Value) {
+ if Debug['B'] != 0 {
+ return
+ }
+ // TODO: convert index to full width?
+ // TODO: if index is 64-bit and we're compiling to 32-bit, check that high 32 bits are zero.
+
+ // bounds check
+ cmp := s.newValue2(ssa.OpIsInBounds, Types[TBOOL], idx, len)
+ s.check(cmp, Panicindex)
+}
+
+// sliceBoundsCheck generates slice bounds checking code. Checks if 0 <= idx <= len, branches to exit if not.
+// Starts a new block on return.
+func (s *state) sliceBoundsCheck(idx, len *ssa.Value) {
+ if Debug['B'] != 0 {
+ return
+ }
+ // TODO: convert index to full width?
+ // TODO: if index is 64-bit and we're compiling to 32-bit, check that high 32 bits are zero.
+
+ // bounds check
+ cmp := s.newValue2(ssa.OpIsSliceInBounds, Types[TBOOL], idx, len)
+ s.check(cmp, panicslice)
+}
+
+// If cmp (a bool) is true, panic using the given function.
+func (s *state) check(cmp *ssa.Value, fn *Node) {
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cmp
+ b.Likely = ssa.BranchLikely
+ bNext := s.f.NewBlock(ssa.BlockPlain)
+ bPanic := s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(bNext)
+ b.AddEdgeTo(bPanic)
+ s.startBlock(bPanic)
+ // The panic call takes/returns memory to ensure that the right
+ // memory state is observed if the panic happens.
+ s.rtcall(fn, false, nil)
+
+ s.startBlock(bNext)
+}
+
+// rtcall issues a call to the given runtime function fn with the listed args.
+// Returns a slice of results of the given result types.
+// The call is added to the end of the current block.
+// If returns is false, the block is marked as an exit block.
+// If returns is true, the block is marked as a call block. A new block
+// is started to load the return values.
+func (s *state) rtcall(fn *Node, returns bool, results []*Type, args ...*ssa.Value) []*ssa.Value {
+ // Write args to the stack
+ var off int64 // TODO: arch-dependent starting offset?
+ for _, arg := range args {
+ t := arg.Type
+ off = Rnd(off, t.Alignment())
+ ptr := s.sp
+ if off != 0 {
+ ptr = s.newValue1I(ssa.OpOffPtr, Types[TUINTPTR], off, s.sp)
+ }
+ size := t.Size()
+ s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, size, ptr, arg, s.mem())
+ off += size
+ }
+ off = Rnd(off, int64(Widthptr))
+
+ // Issue call
+ call := s.newValue1A(ssa.OpStaticCall, ssa.TypeMem, fn.Sym, s.mem())
+ s.vars[&memVar] = call
+
+ // Finish block
+ b := s.endBlock()
+ if !returns {
+ b.Kind = ssa.BlockExit
+ b.Control = call
+ call.AuxInt = off
+ if len(results) > 0 {
+ Fatalf("panic call can't have results")
+ }
+ return nil
+ }
+ b.Kind = ssa.BlockCall
+ b.Control = call
+ bNext := s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(bNext)
+ s.startBlock(bNext)
+
+ // Load results
+ res := make([]*ssa.Value, len(results))
+ for i, t := range results {
+ off = Rnd(off, t.Alignment())
+ ptr := s.sp
+ if off != 0 {
+ ptr = s.newValue1I(ssa.OpOffPtr, Types[TUINTPTR], off, s.sp)
+ }
+ res[i] = s.newValue2(ssa.OpLoad, t, ptr, s.mem())
+ off += t.Size()
+ }
+ off = Rnd(off, int64(Widthptr))
+
+ // Remember how much callee stack space we needed.
+ call.AuxInt = off
+
+ return res
+}
+
+// insertWB inserts a write barrier. A value of type t has already
+// been stored at location p. Tell the runtime about this write.
+// Note: there must be no GC suspension points between the write and
+// the call that this function inserts.
+func (s *state) insertWB(t *Type, p *ssa.Value) {
+ // if writeBarrierEnabled {
+ // typedmemmove_nostore(&t, p)
+ // }
+ bThen := s.f.NewBlock(ssa.BlockPlain)
+
+ aux := &ssa.ExternSymbol{Types[TBOOL], syslook("writeBarrierEnabled", 0).Sym}
+ flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TBOOL]), aux, s.sb)
+ flag := s.newValue2(ssa.OpLoad, Types[TBOOL], flagaddr, s.mem())
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Likely = ssa.BranchUnlikely
+ b.Control = flag
+ b.AddEdgeTo(bThen)
+
+ s.startBlock(bThen)
+ // TODO: writebarrierptr_nostore if just one pointer word (or a few?)
+ taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Types[TUINTPTR], typenamesym(t)}, s.sb)
+ s.rtcall(typedmemmove_nostore, true, nil, taddr, p)
+
+ b.AddEdgeTo(s.curBlock)
+}
+
+// slice computes the slice v[i:j:k] and returns ptr, len, and cap of result.
+// i,j,k may be nil, in which case they are set to their default value.
+// t is a slice, ptr to array, or string type.
+func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) {
+ var elemtype *Type
+ var ptrtype *Type
+ var ptr *ssa.Value
+ var len *ssa.Value
+ var cap *ssa.Value
+ zero := s.constInt(Types[TINT], 0)
+ switch {
+ case t.IsSlice():
+ elemtype = t.Type
+ ptrtype = Ptrto(elemtype)
+ ptr = s.newValue1(ssa.OpSlicePtr, ptrtype, v)
+ len = s.newValue1(ssa.OpSliceLen, Types[TINT], v)
+ cap = s.newValue1(ssa.OpSliceCap, Types[TINT], v)
+ case t.IsString():
+ elemtype = Types[TUINT8]
+ ptrtype = Ptrto(elemtype)
+ ptr = s.newValue1(ssa.OpStringPtr, ptrtype, v)
+ len = s.newValue1(ssa.OpStringLen, Types[TINT], v)
+ cap = len
+ case t.IsPtr():
+ if !t.Type.IsArray() {
+ s.Fatalf("bad ptr to array in slice %v\n", t)
+ }
+ elemtype = t.Type.Type
+ ptrtype = Ptrto(elemtype)
+ s.nilCheck(v)
+ ptr = v
+ len = s.constInt(Types[TINT], t.Type.Bound)
+ cap = len
+ default:
+ s.Fatalf("bad type in slice %v\n", t)
+ }
+
+ // Set default values
+ if i == nil {
+ i = zero
+ }
+ if j == nil {
+ j = len
+ }
+ if k == nil {
+ k = cap
+ }
+
+ // Panic if slice indices are not in bounds.
+ s.sliceBoundsCheck(i, j)
+ if j != k {
+ s.sliceBoundsCheck(j, k)
+ }
+ if k != cap {
+ s.sliceBoundsCheck(k, cap)
+ }
+
+ // Generate the following code assuming that indexes are in bounds.
+ // The conditional is to make sure that we don't generate a slice
+ // that points to the next object in memory.
+ // rlen = (SubPtr j i)
+ // rcap = (SubPtr k i)
+ // p = ptr
+ // if rcap != 0 {
+ // p = (AddPtr ptr (MulPtr low (ConstPtr size)))
+ // }
+ // result = (SliceMake p size)
+ rlen := s.newValue2(ssa.OpSubPtr, Types[TINT], j, i)
+ var rcap *ssa.Value
+ switch {
+ case t.IsString():
+ // Capacity of the result is unimportant. However, we use
+ // rcap to test if we've generated a zero-length slice.
+ // Use length of strings for that.
+ rcap = rlen
+ case j == k:
+ rcap = rlen
+ default:
+ rcap = s.newValue2(ssa.OpSubPtr, Types[TINT], k, i)
+ }
+
+ s.vars[&ptrVar] = ptr
+
+ // Generate code to test the resulting slice length.
+ var cmp *ssa.Value
+ if s.config.IntSize == 8 {
+ cmp = s.newValue2(ssa.OpNeq64, Types[TBOOL], rcap, s.constInt(Types[TINT], 0))
+ } else {
+ cmp = s.newValue2(ssa.OpNeq32, Types[TBOOL], rcap, s.constInt(Types[TINT], 0))
+ }
+
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Likely = ssa.BranchLikely
+ b.Control = cmp
+
+ // Generate code for non-zero length slice case.
+ nz := s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(nz)
+ s.startBlock(nz)
+ var inc *ssa.Value
+ if elemtype.Width == 1 {
+ inc = i
+ } else {
+ inc = s.newValue2(ssa.OpMulPtr, Types[TUINTPTR], i, s.constInt(Types[TINT], elemtype.Width))
+ }
+ s.vars[&ptrVar] = s.newValue2(ssa.OpAddPtr, ptrtype, ptr, inc)
+ s.endBlock()
+
+ // All done.
+ merge := s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(merge)
+ nz.AddEdgeTo(merge)
+ s.startBlock(merge)
+ rptr := s.variable(&ptrVar, ptrtype)
+ delete(s.vars, &ptrVar)
+ return rptr, rlen, rcap
+}
+
+type u2fcvtTab struct {
+ geq, cvt2F, and, rsh, or, add ssa.Op
+ one func(*state, ssa.Type, int64) *ssa.Value
+}
+
+var u64_f64 u2fcvtTab = u2fcvtTab{
+ geq: ssa.OpGeq64,
+ cvt2F: ssa.OpCvt64to64F,
+ and: ssa.OpAnd64,
+ rsh: ssa.OpRsh64Ux64,
+ or: ssa.OpOr64,
+ add: ssa.OpAdd64F,
+ one: (*state).constInt64,
+}
+
+var u64_f32 u2fcvtTab = u2fcvtTab{
+ geq: ssa.OpGeq64,
+ cvt2F: ssa.OpCvt64to32F,
+ and: ssa.OpAnd64,
+ rsh: ssa.OpRsh64Ux64,
+ or: ssa.OpOr64,
+ add: ssa.OpAdd32F,
+ one: (*state).constInt64,
+}
+
+// Excess generality on a machine with 64-bit integer registers.
+// Not used on AMD64.
+var u32_f32 u2fcvtTab = u2fcvtTab{
+ geq: ssa.OpGeq32,
+ cvt2F: ssa.OpCvt32to32F,
+ and: ssa.OpAnd32,
+ rsh: ssa.OpRsh32Ux32,
+ or: ssa.OpOr32,
+ add: ssa.OpAdd32F,
+ one: func(s *state, t ssa.Type, x int64) *ssa.Value {
+ return s.constInt32(t, int32(x))
+ },
+}
+
+func (s *state) uint64Tofloat64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value {
+ return s.uintTofloat(&u64_f64, n, x, ft, tt)
+}
+
+func (s *state) uint64Tofloat32(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value {
+ return s.uintTofloat(&u64_f32, n, x, ft, tt)
+}
+
+func (s *state) uintTofloat(cvttab *u2fcvtTab, n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value {
+ // if x >= 0 {
+ // result = (floatY) x
+ // } else {
+ // y = uintX(x) ; y = x & 1
+ // z = uintX(x) ; z = z >> 1
+ // z = z >> 1
+ // z = z | y
+ // result = floatY(z)
+ // result = result + result
+ // }
+ //
+ // Code borrowed from old code generator.
+ // What's going on: large 64-bit "unsigned" looks like
+ // negative number to hardware's integer-to-float
+ // conversion. However, because the mantissa is only
+ // 63 bits, we don't need the LSB, so instead we do an
+ // unsigned right shift (divide by two), convert, and
+ // double. However, before we do that, we need to be
+ // sure that we do not lose a "1" if that made the
+ // difference in the resulting rounding. Therefore, we
+ // preserve it, and OR (not ADD) it back in. The case
+ // that matters is when the eleven discarded bits are
+ // equal to 10000000001; that rounds up, and the 1 cannot
+ // be lost else it would round down if the LSB of the
+ // candidate mantissa is 0.
+ cmp := s.newValue2(cvttab.geq, Types[TBOOL], x, s.zeroVal(ft))
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cmp
+ b.Likely = ssa.BranchLikely
+
+ bThen := s.f.NewBlock(ssa.BlockPlain)
+ bElse := s.f.NewBlock(ssa.BlockPlain)
+ bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+ b.AddEdgeTo(bThen)
+ s.startBlock(bThen)
+ a0 := s.newValue1(cvttab.cvt2F, tt, x)
+ s.vars[n] = a0
+ s.endBlock()
+ bThen.AddEdgeTo(bAfter)
+
+ b.AddEdgeTo(bElse)
+ s.startBlock(bElse)
+ one := cvttab.one(s, ft, 1)
+ y := s.newValue2(cvttab.and, ft, x, one)
+ z := s.newValue2(cvttab.rsh, ft, x, one)
+ z = s.newValue2(cvttab.or, ft, z, y)
+ a := s.newValue1(cvttab.cvt2F, tt, z)
+ a1 := s.newValue2(cvttab.add, tt, a, a)
+ s.vars[n] = a1
+ s.endBlock()
+ bElse.AddEdgeTo(bAfter)
+
+ s.startBlock(bAfter)
+ return s.variable(n, n.Type)
+}
+
+// referenceTypeBuiltin generates code for the len/cap builtins for maps and channels.
+func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
+ if !n.Left.Type.IsMap() && !n.Left.Type.IsChan() {
+ s.Fatalf("node must be a map or a channel")
+ }
+ // if n == nil {
+ // return 0
+ // } else {
+ // // len
+ // return *((*int)n)
+ // // cap
+ // return *(((*int)n)+1)
+ // }
+ lenType := n.Type
+ nilValue := s.newValue0(ssa.OpConstNil, Types[TUINTPTR])
+ cmp := s.newValue2(ssa.OpEqPtr, Types[TBOOL], x, nilValue)
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cmp
+ b.Likely = ssa.BranchUnlikely
+
+ bThen := s.f.NewBlock(ssa.BlockPlain)
+ bElse := s.f.NewBlock(ssa.BlockPlain)
+ bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+ // length/capacity of a nil map/chan is zero
+ b.AddEdgeTo(bThen)
+ s.startBlock(bThen)
+ s.vars[n] = s.zeroVal(lenType)
+ s.endBlock()
+ bThen.AddEdgeTo(bAfter)
+
+ b.AddEdgeTo(bElse)
+ s.startBlock(bElse)
+ if n.Op == OLEN {
+ // length is stored in the first word for map/chan
+ s.vars[n] = s.newValue2(ssa.OpLoad, lenType, x, s.mem())
+ } else if n.Op == OCAP {
+ // capacity is stored in the second word for chan
+ sw := s.newValue1I(ssa.OpOffPtr, lenType.PtrTo(), lenType.Width, x)
+ s.vars[n] = s.newValue2(ssa.OpLoad, lenType, sw, s.mem())
+ } else {
+ s.Fatalf("op must be OLEN or OCAP")
+ }
+ s.endBlock()
+ bElse.AddEdgeTo(bAfter)
+
+ s.startBlock(bAfter)
+ return s.variable(n, lenType)
+}
+
+type f2uCvtTab struct {
+ ltf, cvt2U, subf ssa.Op
+ value func(*state, ssa.Type, float64) *ssa.Value
+}
+
+var f32_u64 f2uCvtTab = f2uCvtTab{
+ ltf: ssa.OpLess32F,
+ cvt2U: ssa.OpCvt32Fto64,
+ subf: ssa.OpSub32F,
+ value: (*state).constFloat32,
+}
+
+var f64_u64 f2uCvtTab = f2uCvtTab{
+ ltf: ssa.OpLess64F,
+ cvt2U: ssa.OpCvt64Fto64,
+ subf: ssa.OpSub64F,
+ value: (*state).constFloat64,
+}
+
+func (s *state) float32ToUint64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value {
+ return s.floatToUint(&f32_u64, n, x, ft, tt)
+}
+func (s *state) float64ToUint64(n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value {
+ return s.floatToUint(&f64_u64, n, x, ft, tt)
+}
+
+func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Type) *ssa.Value {
+ // if x < 9223372036854775808.0 {
+ // result = uintY(x)
+ // } else {
+ // y = x - 9223372036854775808.0
+ // z = uintY(y)
+ // result = z | -9223372036854775808
+ // }
+ twoToThe63 := cvttab.value(s, ft, 9223372036854775808.0)
+ cmp := s.newValue2(cvttab.ltf, Types[TBOOL], x, twoToThe63)
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cmp
+ b.Likely = ssa.BranchLikely
+
+ bThen := s.f.NewBlock(ssa.BlockPlain)
+ bElse := s.f.NewBlock(ssa.BlockPlain)
+ bAfter := s.f.NewBlock(ssa.BlockPlain)
+
+ b.AddEdgeTo(bThen)
+ s.startBlock(bThen)
+ a0 := s.newValue1(cvttab.cvt2U, tt, x)
+ s.vars[n] = a0
+ s.endBlock()
+ bThen.AddEdgeTo(bAfter)
+
+ b.AddEdgeTo(bElse)
+ s.startBlock(bElse)
+ y := s.newValue2(cvttab.subf, ft, x, twoToThe63)
+ y = s.newValue1(cvttab.cvt2U, tt, y)
+ z := s.constInt64(tt, -9223372036854775808)
+ a1 := s.newValue2(ssa.OpOr64, tt, y, z)
+ s.vars[n] = a1
+ s.endBlock()
+ bElse.AddEdgeTo(bAfter)
+
+ s.startBlock(bAfter)
+ return s.variable(n, n.Type)
+}
+
+// ifaceType returns the value for the word containing the type.
+// n is the node for the interface expression.
+// v is the corresponding value.
+func (s *state) ifaceType(n *Node, v *ssa.Value) *ssa.Value {
+ byteptr := Ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte)
+
+ if isnilinter(n.Type) {
+ // Have *eface. The type is the first word in the struct.
+ return s.newValue1(ssa.OpITab, byteptr, v)
+ }
+
+ // Have *iface.
+ // The first word in the struct is the *itab.
+ // If the *itab is nil, return 0.
+ // Otherwise, the second word in the *itab is the type.
+
+ tab := s.newValue1(ssa.OpITab, byteptr, v)
+ s.vars[&typVar] = tab
+ isnonnil := s.newValue2(ssa.OpNeqPtr, Types[TBOOL], tab, s.entryNewValue0(ssa.OpConstNil, byteptr))
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = isnonnil
+ b.Likely = ssa.BranchLikely
+
+ bLoad := s.f.NewBlock(ssa.BlockPlain)
+ bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+ b.AddEdgeTo(bLoad)
+ b.AddEdgeTo(bEnd)
+ bLoad.AddEdgeTo(bEnd)
+
+ s.startBlock(bLoad)
+ off := s.newValue1I(ssa.OpOffPtr, byteptr, int64(Widthptr), tab)
+ s.vars[&typVar] = s.newValue2(ssa.OpLoad, byteptr, off, s.mem())
+ s.endBlock()
+
+ s.startBlock(bEnd)
+ typ := s.variable(&typVar, byteptr)
+ delete(s.vars, &typVar)
+ return typ
+}
+
+// dottype generates SSA for a type assertion node.
+// commaok indicates whether to panic or return a bool.
+// If commaok is false, resok will be nil.
+func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
+ iface := s.expr(n.Left)
+ typ := s.ifaceType(n.Left, iface) // actual concrete type
+ target := s.expr(typename(n.Type)) // target type
+ if !isdirectiface(n.Type) {
+ // walk rewrites ODOTTYPE/OAS2DOTTYPE into runtime calls except for this case.
+ Fatalf("dottype needs a direct iface type %s", n.Type)
+ }
+
+ // TODO: If we have a nonempty interface and its itab field is nil,
+ // then this test is redundant and ifaceType should just branch directly to bFail.
+ cond := s.newValue2(ssa.OpEqPtr, Types[TBOOL], typ, target)
+ b := s.endBlock()
+ b.Kind = ssa.BlockIf
+ b.Control = cond
+ b.Likely = ssa.BranchLikely
+
+ byteptr := Ptrto(Types[TUINT8])
+
+ bOk := s.f.NewBlock(ssa.BlockPlain)
+ bFail := s.f.NewBlock(ssa.BlockPlain)
+ b.AddEdgeTo(bOk)
+ b.AddEdgeTo(bFail)
+
+ if !commaok {
+ // on failure, panic by calling panicdottype
+ s.startBlock(bFail)
+ taddr := s.newValue1A(ssa.OpAddr, byteptr, &ssa.ExternSymbol{byteptr, typenamesym(n.Left.Type)}, s.sb)
+ s.rtcall(panicdottype, false, nil, typ, target, taddr)
+
+ // on success, return idata field
+ s.startBlock(bOk)
+ return s.newValue1(ssa.OpIData, n.Type, iface), nil
+ }
+
+ // commaok is the more complicated case because we have
+ // a control flow merge point.
+ bEnd := s.f.NewBlock(ssa.BlockPlain)
+
+ // type assertion succeeded
+ s.startBlock(bOk)
+ s.vars[&idataVar] = s.newValue1(ssa.OpIData, n.Type, iface)
+ s.vars[&okVar] = s.constBool(true)
+ s.endBlock()
+ bOk.AddEdgeTo(bEnd)
+
+ // type assertion failed
+ s.startBlock(bFail)
+ s.vars[&idataVar] = s.entryNewValue0(ssa.OpConstNil, byteptr)
+ s.vars[&okVar] = s.constBool(false)
+ s.endBlock()
+ bFail.AddEdgeTo(bEnd)
+
+ // merge point
+ s.startBlock(bEnd)
+ res = s.variable(&idataVar, byteptr)
+ resok = s.variable(&okVar, Types[TBOOL])
+ delete(s.vars, &idataVar)
+ delete(s.vars, &okVar)
+ return res, resok
+}
+
+// checkgoto checks that a goto from from to to does not
+// jump into a block or jump over variable declarations.
+// It is a copy of checkgoto in the pre-SSA backend,
+// modified only for line number handling.
+// TODO: document how this works and why it is designed the way it is.
+func (s *state) checkgoto(from *Node, to *Node) {
+ if from.Sym == to.Sym {
+ return
+ }
+
+ nf := 0
+ for fs := from.Sym; fs != nil; fs = fs.Link {
+ nf++
+ }
+ nt := 0
+ for fs := to.Sym; fs != nil; fs = fs.Link {
+ nt++
+ }
+ fs := from.Sym
+ for ; nf > nt; nf-- {
+ fs = fs.Link
+ }
+ if fs != to.Sym {
+ // decide what to complain about.
+ // prefer to complain about 'into block' over declarations,
+ // so scan backward to find most recent block or else dcl.
+ var block *Sym
+
+ var dcl *Sym
+ ts := to.Sym
+ for ; nt > nf; nt-- {
+ if ts.Pkg == nil {
+ block = ts
+ } else {
+ dcl = ts
+ }
+ ts = ts.Link
+ }
+
+ for ts != fs {
+ if ts.Pkg == nil {
+ block = ts
+ } else {
+ dcl = ts
+ }
+ ts = ts.Link
+ fs = fs.Link
+ }
+
+ lno := int(from.Left.Lineno)
+ if block != nil {
+ yyerrorl(lno, "goto %v jumps into block starting at %v", from.Left.Sym, Ctxt.Line(int(block.Lastlineno)))
+ } else {
+ yyerrorl(lno, "goto %v jumps over declaration of %v at %v", from.Left.Sym, dcl, Ctxt.Line(int(dcl.Lastlineno)))
+ }
+ }
+}
+
+// variable returns the value of a variable at the current location.
+func (s *state) variable(name *Node, t ssa.Type) *ssa.Value {
+ v := s.vars[name]
+ if v == nil {
+ // TODO: get type? Take Sym as arg?
+ v = s.newValue0A(ssa.OpFwdRef, t, name)
+ s.vars[name] = v
+ }
+ return v
+}
+
+func (s *state) mem() *ssa.Value {
+ return s.variable(&memVar, ssa.TypeMem)
+}
+
+func (s *state) linkForwardReferences() {
+ // Build ssa graph. Each variable on its first use in a basic block
+ // leaves a FwdRef in that block representing the incoming value
+ // of that variable. This function links that ref up with possible definitions,
+ // inserting Phi values as needed. This is essentially the algorithm
+ // described by Brau, Buchwald, Hack, Leißa, Mallon, and Zwinkau:
+ // http://pp.info.uni-karlsruhe.de/uploads/publikationen/braun13cc.pdf
+ for _, b := range s.f.Blocks {
+ for _, v := range b.Values {
+ if v.Op != ssa.OpFwdRef {
+ continue
+ }
+ name := v.Aux.(*Node)
+ v.Op = ssa.OpCopy
+ v.Aux = nil
+ v.SetArgs1(s.lookupVarIncoming(b, v.Type, name))
+ }
+ }
+}
+
+// lookupVarIncoming finds the variable's value at the start of block b.
+func (s *state) lookupVarIncoming(b *ssa.Block, t ssa.Type, name *Node) *ssa.Value {
+ // TODO(khr): have lookupVarIncoming overwrite the fwdRef or copy it
+ // will be used in, instead of having the result used in a copy value.
+ if b == s.f.Entry {
+ if name == &memVar {
+ return s.startmem
+ }
+ // variable is live at the entry block. Load it.
+ addr := s.decladdrs[name]
+ if addr == nil {
+ // TODO: closure args reach here.
+ s.Unimplementedf("unhandled closure arg %s at entry to function %s", name, b.Func.Name)
+ }
+ if _, ok := addr.Aux.(*ssa.ArgSymbol); !ok {
+ s.Fatalf("variable live at start of function %s is not an argument %s", b.Func.Name, name)
+ }
+ return s.entryNewValue2(ssa.OpLoad, t, addr, s.startmem)
+ }
+ var vals []*ssa.Value
+ for _, p := range b.Preds {
+ vals = append(vals, s.lookupVarOutgoing(p, t, name))
+ }
+ if len(vals) == 0 {
+ // This block is dead; we have no predecessors and we're not the entry block.
+ // It doesn't matter what we use here as long as it is well-formed,
+ // so use the default/zero value.
+ if name == &memVar {
+ return s.startmem
+ }
+ return s.zeroVal(name.Type)
+ }
+ v0 := vals[0]
+ for i := 1; i < len(vals); i++ {
+ if vals[i] != v0 {
+ // need a phi value
+ v := b.NewValue0(s.peekLine(), ssa.OpPhi, t)
+ v.AddArgs(vals...)
+ return v
+ }
+ }
+ return v0
+}
+
+// lookupVarOutgoing finds the variable's value at the end of block b.
+func (s *state) lookupVarOutgoing(b *ssa.Block, t ssa.Type, name *Node) *ssa.Value {
+ m := s.defvars[b.ID]
+ if v, ok := m[name]; ok {
+ return v
+ }
+ // The variable is not defined by b and we haven't
+ // looked it up yet. Generate v, a copy value which
+ // will be the outgoing value of the variable. Then
+ // look up w, the incoming value of the variable.
+ // Make v = copy(w). We need the extra copy to
+ // prevent infinite recursion when looking up the
+ // incoming value of the variable.
+ v := b.NewValue0(s.peekLine(), ssa.OpCopy, t)
+ m[name] = v
+ v.AddArg(s.lookupVarIncoming(b, t, name))
+ return v
+}
+
+// TODO: the above mutually recursive functions can lead to very deep stacks. Fix that.
+
+// an unresolved branch
+type branch struct {
+ p *obj.Prog // branch instruction
+ b *ssa.Block // target
+}
+
+type genState struct {
+ // branches remembers all the branch instructions we've seen
+ // and where they would like to go.
+ branches []branch
+
+ // bstart remembers where each block starts (indexed by block ID)
+ bstart []*obj.Prog
+
+ // deferBranches remembers all the defer branches we've seen.
+ deferBranches []*obj.Prog
+
+ // deferTarget remembers the (last) deferreturn call site.
+ deferTarget *obj.Prog
+}
+
+// genssa appends entries to ptxt for each instruction in f.
+// gcargs and gclocals are filled in with pointer maps for the frame.
+func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
+ var s genState
+
+ e := f.Config.Frontend().(*ssaExport)
+ // We're about to emit a bunch of Progs.
+ // Since the only way to get here is to explicitly request it,
+ // just fail on unimplemented instead of trying to unwind our mess.
+ e.mustImplement = true
+
+ // Remember where each block starts.
+ s.bstart = make([]*obj.Prog, f.NumBlocks())
+
+ var valueProgs map[*obj.Prog]*ssa.Value
+ var blockProgs map[*obj.Prog]*ssa.Block
+ const logProgs = true
+ if logProgs {
+ valueProgs = make(map[*obj.Prog]*ssa.Value, f.NumValues())
+ blockProgs = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
+ f.Logf("genssa %s\n", f.Name)
+ blockProgs[Pc] = f.Blocks[0]
+ }
+
+ // Emit basic blocks
+ for i, b := range f.Blocks {
+ s.bstart[b.ID] = Pc
+ // Emit values in block
+ for _, v := range b.Values {
+ x := Pc
+ s.genValue(v)
+ if logProgs {
+ for ; x != Pc; x = x.Link {
+ valueProgs[x] = v
+ }
+ }
+ }
+ // Emit control flow instructions for block
+ var next *ssa.Block
+ if i < len(f.Blocks)-1 {
+ next = f.Blocks[i+1]
+ }
+ x := Pc
+ s.genBlock(b, next)
+ if logProgs {
+ for ; x != Pc; x = x.Link {
+ blockProgs[x] = b
+ }
+ }
+ }
+
+ // Resolve branches
+ for _, br := range s.branches {
+ br.p.To.Val = s.bstart[br.b.ID]
+ }
+ if s.deferBranches != nil && s.deferTarget == nil {
+ // This can happen when the function has a defer but
+ // no return (because it has an infinite loop).
+ s.deferReturn()
+ Prog(obj.ARET)
+ }
+ for _, p := range s.deferBranches {
+ p.To.Val = s.deferTarget
+ }
+
+ if logProgs {
+ for p := ptxt; p != nil; p = p.Link {
+ var s string
+ if v, ok := valueProgs[p]; ok {
+ s = v.String()
+ } else if b, ok := blockProgs[p]; ok {
+ s = b.String()
+ } else {
+ s = " " // most value and branch strings are 2-3 characters long
+ }
+ f.Logf("%s\t%s\n", s, p)
+ }
+ if f.Config.HTML != nil {
+ saved := ptxt.Ctxt.LineHist.PrintFilenameOnly
+ ptxt.Ctxt.LineHist.PrintFilenameOnly = true
+ var buf bytes.Buffer
+ buf.WriteString("<code>")
+ buf.WriteString("<dl class=\"ssa-gen\">")
+ for p := ptxt; p != nil; p = p.Link {
+ buf.WriteString("<dt class=\"ssa-prog-src\">")
+ if v, ok := valueProgs[p]; ok {
+ buf.WriteString(v.HTML())
+ } else if b, ok := blockProgs[p]; ok {
+ buf.WriteString(b.HTML())
+ }
+ buf.WriteString("</dt>")
+ buf.WriteString("<dd class=\"ssa-prog\">")
+ buf.WriteString(html.EscapeString(p.String()))
+ buf.WriteString("</dd>")
+ buf.WriteString("</li>")
+ }
+ buf.WriteString("</dl>")
+ buf.WriteString("</code>")
+ f.Config.HTML.WriteColumn("genssa", buf.String())
+ ptxt.Ctxt.LineHist.PrintFilenameOnly = saved
+ }
+ }
+
+ // Emit static data
+ if f.StaticData != nil {
+ for _, n := range f.StaticData.([]*Node) {
+ if !gen_as_init(n, false) {
+ Fatalf("non-static data marked as static: %v\n\n", n, f)
+ }
+ }
+ }
+
+ // Allocate stack frame
+ allocauto(ptxt)
+
+ // Generate gc bitmaps.
+ liveness(Curfn, ptxt, gcargs, gclocals)
+ gcsymdup(gcargs)
+ gcsymdup(gclocals)
+
+ // Add frame prologue. Zero ambiguously live variables.
+ Thearch.Defframe(ptxt)
+ if Debug['f'] != 0 {
+ frame(0)
+ }
+
+ // Remove leftover instrumentation from the instruction stream.
+ removevardef(ptxt)
+
+ f.Config.HTML.Close()
+}
+
+// opregreg emits instructions for
+// dest := dest(To) op src(From)
+// and also returns the created obj.Prog so it
+// may be further adjusted (offset, scale, etc).
+func opregreg(op int, dest, src int16) *obj.Prog {
+ p := Prog(op)
+ p.From.Type = obj.TYPE_REG
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = dest
+ p.From.Reg = src
+ return p
+}
+
+func (s *genState) genValue(v *ssa.Value) {
+ lineno = v.Line
+ switch v.Op {
+ case ssa.OpAMD64ADDQ:
+ // TODO: use addq instead of leaq if target is in the right register.
+ p := Prog(x86.ALEAQ)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ p.From.Scale = 1
+ p.From.Index = regnum(v.Args[1])
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64ADDL:
+ p := Prog(x86.ALEAL)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ p.From.Scale = 1
+ p.From.Index = regnum(v.Args[1])
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64ADDW:
+ p := Prog(x86.ALEAW)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ p.From.Scale = 1
+ p.From.Index = regnum(v.Args[1])
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ // 2-address opcode arithmetic, symmetric
+ case ssa.OpAMD64ADDB, ssa.OpAMD64ADDSS, ssa.OpAMD64ADDSD,
+ ssa.OpAMD64ANDQ, ssa.OpAMD64ANDL, ssa.OpAMD64ANDW, ssa.OpAMD64ANDB,
+ ssa.OpAMD64ORQ, ssa.OpAMD64ORL, ssa.OpAMD64ORW, ssa.OpAMD64ORB,
+ ssa.OpAMD64XORQ, ssa.OpAMD64XORL, ssa.OpAMD64XORW, ssa.OpAMD64XORB,
+ ssa.OpAMD64MULQ, ssa.OpAMD64MULL, ssa.OpAMD64MULW, ssa.OpAMD64MULB,
+ ssa.OpAMD64MULSS, ssa.OpAMD64MULSD, ssa.OpAMD64PXOR:
+ r := regnum(v)
+ x := regnum(v.Args[0])
+ y := regnum(v.Args[1])
+ if x != r && y != r {
+ opregreg(regMoveByTypeAMD64(v.Type), r, x)
+ x = r
+ }
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ if x == r {
+ p.From.Reg = y
+ } else {
+ p.From.Reg = x
+ }
+ // 2-address opcode arithmetic, not symmetric
+ case ssa.OpAMD64SUBQ, ssa.OpAMD64SUBL, ssa.OpAMD64SUBW, ssa.OpAMD64SUBB:
+ r := regnum(v)
+ x := regnum(v.Args[0])
+ y := regnum(v.Args[1])
+ var neg bool
+ if y == r {
+ // compute -(y-x) instead
+ x, y = y, x
+ neg = true
+ }
+ if x != r {
+ opregreg(regMoveByTypeAMD64(v.Type), r, x)
+ }
+ opregreg(v.Op.Asm(), r, y)
+
+ if neg {
+ p := Prog(x86.ANEGQ) // TODO: use correct size? This is mostly a hack until regalloc does 2-address correctly
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ }
+ case ssa.OpAMD64SUBSS, ssa.OpAMD64SUBSD, ssa.OpAMD64DIVSS, ssa.OpAMD64DIVSD:
+ r := regnum(v)
+ x := regnum(v.Args[0])
+ y := regnum(v.Args[1])
+ if y == r && x != r {
+ // r/y := x op r/y, need to preserve x and rewrite to
+ // r/y := r/y op x15
+ x15 := int16(x86.REG_X15)
+ // register move y to x15
+ // register move x to y
+ // rename y with x15
+ opregreg(regMoveByTypeAMD64(v.Type), x15, y)
+ opregreg(regMoveByTypeAMD64(v.Type), r, x)
+ y = x15
+ } else if x != r {
+ opregreg(regMoveByTypeAMD64(v.Type), r, x)
+ }
+ opregreg(v.Op.Asm(), r, y)
+
+ case ssa.OpAMD64DIVQ, ssa.OpAMD64DIVL, ssa.OpAMD64DIVW,
+ ssa.OpAMD64DIVQU, ssa.OpAMD64DIVLU, ssa.OpAMD64DIVWU,
+ ssa.OpAMD64MODQ, ssa.OpAMD64MODL, ssa.OpAMD64MODW,
+ ssa.OpAMD64MODQU, ssa.OpAMD64MODLU, ssa.OpAMD64MODWU:
+
+ // Arg[0] is already in AX as it's the only register we allow
+ // and AX is the only output
+ x := regnum(v.Args[1])
+
+ // CPU faults upon signed overflow, which occurs when most
+ // negative int is divided by -1.
+ var j *obj.Prog
+ if v.Op == ssa.OpAMD64DIVQ || v.Op == ssa.OpAMD64DIVL ||
+ v.Op == ssa.OpAMD64DIVW || v.Op == ssa.OpAMD64MODQ ||
+ v.Op == ssa.OpAMD64MODL || v.Op == ssa.OpAMD64MODW {
+
+ var c *obj.Prog
+ switch v.Op {
+ case ssa.OpAMD64DIVQ, ssa.OpAMD64MODQ:
+ c = Prog(x86.ACMPQ)
+ j = Prog(x86.AJEQ)
+ // go ahead and sign extend to save doing it later
+ Prog(x86.ACQO)
+
+ case ssa.OpAMD64DIVL, ssa.OpAMD64MODL:
+ c = Prog(x86.ACMPL)
+ j = Prog(x86.AJEQ)
+ Prog(x86.ACDQ)
+
+ case ssa.OpAMD64DIVW, ssa.OpAMD64MODW:
+ c = Prog(x86.ACMPW)
+ j = Prog(x86.AJEQ)
+ Prog(x86.ACWD)
+ }
+ c.From.Type = obj.TYPE_REG
+ c.From.Reg = x
+ c.To.Type = obj.TYPE_CONST
+ c.To.Offset = -1
+
+ j.To.Type = obj.TYPE_BRANCH
+
+ }
+
+ // for unsigned ints, we sign extend by setting DX = 0
+ // signed ints were sign extended above
+ if v.Op == ssa.OpAMD64DIVQU || v.Op == ssa.OpAMD64MODQU ||
+ v.Op == ssa.OpAMD64DIVLU || v.Op == ssa.OpAMD64MODLU ||
+ v.Op == ssa.OpAMD64DIVWU || v.Op == ssa.OpAMD64MODWU {
+ c := Prog(x86.AXORQ)
+ c.From.Type = obj.TYPE_REG
+ c.From.Reg = x86.REG_DX
+ c.To.Type = obj.TYPE_REG
+ c.To.Reg = x86.REG_DX
+ }
+
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x
+
+ // signed division, rest of the check for -1 case
+ if j != nil {
+ j2 := Prog(obj.AJMP)
+ j2.To.Type = obj.TYPE_BRANCH
+
+ var n *obj.Prog
+ if v.Op == ssa.OpAMD64DIVQ || v.Op == ssa.OpAMD64DIVL ||
+ v.Op == ssa.OpAMD64DIVW {
+ // n * -1 = -n
+ n = Prog(x86.ANEGQ)
+ n.To.Type = obj.TYPE_REG
+ n.To.Reg = x86.REG_AX
+ } else {
+ // n % -1 == 0
+ n = Prog(x86.AXORQ)
+ n.From.Type = obj.TYPE_REG
+ n.From.Reg = x86.REG_DX
+ n.To.Type = obj.TYPE_REG
+ n.To.Reg = x86.REG_DX
+ }
+
+ j.To.Val = n
+ j2.To.Val = Pc
+ }
+
+ case ssa.OpAMD64HMULL, ssa.OpAMD64HMULW, ssa.OpAMD64HMULB,
+ ssa.OpAMD64HMULLU, ssa.OpAMD64HMULWU, ssa.OpAMD64HMULBU:
+ // the frontend rewrites constant division by 8/16/32 bit integers into
+ // HMUL by a constant
+
+ // Arg[0] is already in AX as it's the only register we allow
+ // and DX is the only output we care about (the high bits)
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[1])
+
+ // IMULB puts the high portion in AH instead of DL,
+ // so move it to DL for consistency
+ if v.Type.Size() == 1 {
+ m := Prog(x86.AMOVB)
+ m.From.Type = obj.TYPE_REG
+ m.From.Reg = x86.REG_AH
+ m.To.Type = obj.TYPE_REG
+ m.To.Reg = x86.REG_DX
+ }
+
+ case ssa.OpAMD64SHLQ, ssa.OpAMD64SHLL, ssa.OpAMD64SHLW, ssa.OpAMD64SHLB,
+ ssa.OpAMD64SHRQ, ssa.OpAMD64SHRL, ssa.OpAMD64SHRW, ssa.OpAMD64SHRB,
+ ssa.OpAMD64SARQ, ssa.OpAMD64SARL, ssa.OpAMD64SARW, ssa.OpAMD64SARB:
+ x := regnum(v.Args[0])
+ r := regnum(v)
+ if x != r {
+ if r == x86.REG_CX {
+ v.Fatalf("can't implement %s, target and shift both in CX", v.LongString())
+ }
+ p := Prog(regMoveAMD64(v.Type.Size()))
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ }
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[1]) // should be CX
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ case ssa.OpAMD64ADDQconst, ssa.OpAMD64ADDLconst, ssa.OpAMD64ADDWconst:
+ // TODO: use addq instead of leaq if target is in the right register.
+ var asm int
+ switch v.Op {
+ case ssa.OpAMD64ADDQconst:
+ asm = x86.ALEAQ
+ case ssa.OpAMD64ADDLconst:
+ asm = x86.ALEAL
+ case ssa.OpAMD64ADDWconst:
+ asm = x86.ALEAW
+ }
+ p := Prog(asm)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ p.From.Offset = v.AuxInt
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst, ssa.OpAMD64MULWconst, ssa.OpAMD64MULBconst:
+ r := regnum(v)
+ x := regnum(v.Args[0])
+ if r != x {
+ p := Prog(regMoveAMD64(v.Type.Size()))
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ }
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = v.AuxInt
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ // TODO: Teach doasm to compile the three-address multiply imul $c, r1, r2
+ // instead of using the MOVQ above.
+ //p.From3 = new(obj.Addr)
+ //p.From3.Type = obj.TYPE_REG
+ //p.From3.Reg = regnum(v.Args[0])
+ case ssa.OpAMD64ADDBconst,
+ ssa.OpAMD64ANDQconst, ssa.OpAMD64ANDLconst, ssa.OpAMD64ANDWconst, ssa.OpAMD64ANDBconst,
+ ssa.OpAMD64ORQconst, ssa.OpAMD64ORLconst, ssa.OpAMD64ORWconst, ssa.OpAMD64ORBconst,
+ ssa.OpAMD64XORQconst, ssa.OpAMD64XORLconst, ssa.OpAMD64XORWconst, ssa.OpAMD64XORBconst,
+ ssa.OpAMD64SUBQconst, ssa.OpAMD64SUBLconst, ssa.OpAMD64SUBWconst, ssa.OpAMD64SUBBconst,
+ ssa.OpAMD64SHLQconst, ssa.OpAMD64SHLLconst, ssa.OpAMD64SHLWconst, ssa.OpAMD64SHLBconst,
+ ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst,
+ ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst,
+ ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst:
+ // This code compensates for the fact that the register allocator
+ // doesn't understand 2-address instructions yet. TODO: fix that.
+ x := regnum(v.Args[0])
+ r := regnum(v)
+ if x != r {
+ p := Prog(regMoveAMD64(v.Type.Size()))
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ }
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = v.AuxInt
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ case ssa.OpAMD64SBBQcarrymask, ssa.OpAMD64SBBLcarrymask:
+ r := regnum(v)
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = r
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ case ssa.OpAMD64LEAQ1, ssa.OpAMD64LEAQ2, ssa.OpAMD64LEAQ4, ssa.OpAMD64LEAQ8:
+ p := Prog(x86.ALEAQ)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ switch v.Op {
+ case ssa.OpAMD64LEAQ1:
+ p.From.Scale = 1
+ case ssa.OpAMD64LEAQ2:
+ p.From.Scale = 2
+ case ssa.OpAMD64LEAQ4:
+ p.From.Scale = 4
+ case ssa.OpAMD64LEAQ8:
+ p.From.Scale = 8
+ }
+ p.From.Index = regnum(v.Args[1])
+ addAux(&p.From, v)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64LEAQ:
+ p := Prog(x86.ALEAQ)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ addAux(&p.From, v)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64CMPQ, ssa.OpAMD64CMPL, ssa.OpAMD64CMPW, ssa.OpAMD64CMPB,
+ ssa.OpAMD64TESTQ, ssa.OpAMD64TESTL, ssa.OpAMD64TESTW, ssa.OpAMD64TESTB:
+ opregreg(v.Op.Asm(), regnum(v.Args[1]), regnum(v.Args[0]))
+ case ssa.OpAMD64UCOMISS, ssa.OpAMD64UCOMISD:
+ // Go assembler has swapped operands for UCOMISx relative to CMP,
+ // must account for that right here.
+ opregreg(v.Op.Asm(), regnum(v.Args[0]), regnum(v.Args[1]))
+ case ssa.OpAMD64CMPQconst, ssa.OpAMD64CMPLconst, ssa.OpAMD64CMPWconst, ssa.OpAMD64CMPBconst,
+ ssa.OpAMD64TESTQconst, ssa.OpAMD64TESTLconst, ssa.OpAMD64TESTWconst, ssa.OpAMD64TESTBconst:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[0])
+ p.To.Type = obj.TYPE_CONST
+ p.To.Offset = v.AuxInt
+ case ssa.OpAMD64MOVBconst, ssa.OpAMD64MOVWconst, ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst:
+ x := regnum(v)
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_CONST
+ var i int64
+ switch v.Op {
+ case ssa.OpAMD64MOVBconst:
+ i = int64(int8(v.AuxInt))
+ case ssa.OpAMD64MOVWconst:
+ i = int64(int16(v.AuxInt))
+ case ssa.OpAMD64MOVLconst:
+ i = int64(int32(v.AuxInt))
+ case ssa.OpAMD64MOVQconst:
+ i = v.AuxInt
+ }
+ p.From.Offset = i
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = x
+ case ssa.OpAMD64MOVSSconst, ssa.OpAMD64MOVSDconst:
+ x := regnum(v)
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_FCONST
+ p.From.Val = math.Float64frombits(uint64(v.AuxInt))
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = x
+ case ssa.OpAMD64MOVQload, ssa.OpAMD64MOVSSload, ssa.OpAMD64MOVSDload, ssa.OpAMD64MOVLload, ssa.OpAMD64MOVWload, ssa.OpAMD64MOVBload, ssa.OpAMD64MOVBQSXload, ssa.OpAMD64MOVBQZXload:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ addAux(&p.From, v)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64MOVQloadidx8, ssa.OpAMD64MOVSDloadidx8:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ addAux(&p.From, v)
+ p.From.Scale = 8
+ p.From.Index = regnum(v.Args[1])
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64MOVSSloadidx4:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = regnum(v.Args[0])
+ addAux(&p.From, v)
+ p.From.Scale = 4
+ p.From.Index = regnum(v.Args[1])
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpAMD64MOVQstore, ssa.OpAMD64MOVSSstore, ssa.OpAMD64MOVSDstore, ssa.OpAMD64MOVLstore, ssa.OpAMD64MOVWstore, ssa.OpAMD64MOVBstore:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[1])
+ p.To.Type = obj.TYPE_MEM
+ p.To.Reg = regnum(v.Args[0])
+ addAux(&p.To, v)
+ case ssa.OpAMD64MOVQstoreidx8, ssa.OpAMD64MOVSDstoreidx8:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[2])
+ p.To.Type = obj.TYPE_MEM
+ p.To.Reg = regnum(v.Args[0])
+ p.To.Scale = 8
+ p.To.Index = regnum(v.Args[1])
+ addAux(&p.To, v)
+ case ssa.OpAMD64MOVSSstoreidx4:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[2])
+ p.To.Type = obj.TYPE_MEM
+ p.To.Reg = regnum(v.Args[0])
+ p.To.Scale = 4
+ p.To.Index = regnum(v.Args[1])
+ addAux(&p.To, v)
+ case ssa.OpAMD64MOVLQSX, ssa.OpAMD64MOVWQSX, ssa.OpAMD64MOVBQSX, ssa.OpAMD64MOVLQZX, ssa.OpAMD64MOVWQZX, ssa.OpAMD64MOVBQZX,
+ ssa.OpAMD64CVTSL2SS, ssa.OpAMD64CVTSL2SD, ssa.OpAMD64CVTSQ2SS, ssa.OpAMD64CVTSQ2SD,
+ ssa.OpAMD64CVTTSS2SL, ssa.OpAMD64CVTTSD2SL, ssa.OpAMD64CVTTSS2SQ, ssa.OpAMD64CVTTSD2SQ,
+ ssa.OpAMD64CVTSS2SD, ssa.OpAMD64CVTSD2SS:
+ opregreg(v.Op.Asm(), regnum(v), regnum(v.Args[0]))
+ case ssa.OpAMD64DUFFZERO:
+ p := Prog(obj.ADUFFZERO)
+ p.To.Type = obj.TYPE_ADDR
+ p.To.Sym = Linksym(Pkglookup("duffzero", Runtimepkg))
+ p.To.Offset = v.AuxInt
++ case ssa.OpAMD64MOVOconst:
++ if v.AuxInt != 0 {
++ v.Unimplementedf("MOVOconst can only do constant=0")
++ }
++ r := regnum(v)
++ opregreg(x86.AXORPS, r, r)
+
+ case ssa.OpCopy: // TODO: lower to MOVQ earlier?
+ if v.Type.IsMemory() {
+ return
+ }
+ x := regnum(v.Args[0])
+ y := regnum(v)
+ if x != y {
+ opregreg(regMoveByTypeAMD64(v.Type), y, x)
+ }
+ case ssa.OpLoadReg:
+ if v.Type.IsFlags() {
+ v.Unimplementedf("load flags not implemented: %v", v.LongString())
+ return
+ }
+ p := Prog(movSizeByType(v.Type))
+ n := autoVar(v.Args[0])
+ p.From.Type = obj.TYPE_MEM
+ p.From.Name = obj.NAME_AUTO
+ p.From.Node = n
+ p.From.Sym = Linksym(n.Sym)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+
+ case ssa.OpStoreReg:
+ if v.Type.IsFlags() {
+ v.Unimplementedf("store flags not implemented: %v", v.LongString())
+ return
+ }
+ p := Prog(movSizeByType(v.Type))
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[0])
+ n := autoVar(v)
+ p.To.Type = obj.TYPE_MEM
+ p.To.Name = obj.NAME_AUTO
+ p.To.Node = n
+ p.To.Sym = Linksym(n.Sym)
+ case ssa.OpPhi:
+ // just check to make sure regalloc and stackalloc did it right
+ if v.Type.IsMemory() {
+ return
+ }
+ f := v.Block.Func
+ loc := f.RegAlloc[v.ID]
+ for _, a := range v.Args {
+ if aloc := f.RegAlloc[a.ID]; aloc != loc { // TODO: .Equal() instead?
+ v.Fatalf("phi arg at different location than phi: %v @ %v, but arg %v @ %v\n%s\n", v, loc, a, aloc, v.Block.Func)
+ }
+ }
+ case ssa.OpConst8, ssa.OpConst16, ssa.OpConst32, ssa.OpConst64, ssa.OpConstString, ssa.OpConstNil, ssa.OpConstBool,
+ ssa.OpConst32F, ssa.OpConst64F:
+ if v.Block.Func.RegAlloc[v.ID] != nil {
+ v.Fatalf("const value %v shouldn't have a location", v)
+ }
+
+ case ssa.OpArg:
+ // memory arg needs no code
+ // TODO: check that only mem arg goes here.
+ case ssa.OpAMD64LoweredPanicNilCheck:
+ if Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ Warnl(int(v.Line), "generated nil check")
+ }
+ // Write to memory address 0. It doesn't matter what we write; use AX.
+ // Input 0 is the pointer we just checked, use it as the destination.
+ r := regnum(v.Args[0])
+ q := Prog(x86.AMOVL)
+ q.From.Type = obj.TYPE_REG
+ q.From.Reg = x86.REG_AX
+ q.To.Type = obj.TYPE_MEM
+ q.To.Reg = r
+ case ssa.OpAMD64LoweredGetClosurePtr:
+ // Output is hardwired to DX only,
+ // and DX contains the closure pointer on
+ // closure entry, and this "instruction"
+ // is scheduled to the very beginning
+ // of the entry block.
+ case ssa.OpAMD64LoweredGetG:
+ r := regnum(v)
+ // See the comments in cmd/internal/obj/x86/obj6.go
+ // near CanUse1InsnTLS for a detailed explanation of these instructions.
+ if x86.CanUse1InsnTLS(Ctxt) {
+ // MOVQ (TLS), r
+ p := Prog(x86.AMOVQ)
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = x86.REG_TLS
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ } else {
+ // MOVQ TLS, r
+ // MOVQ (r)(TLS*1), r
+ p := Prog(x86.AMOVQ)
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x86.REG_TLS
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ q := Prog(x86.AMOVQ)
+ q.From.Type = obj.TYPE_MEM
+ q.From.Reg = r
+ q.From.Index = x86.REG_TLS
+ q.From.Scale = 1
+ q.To.Type = obj.TYPE_REG
+ q.To.Reg = r
+ }
+ case ssa.OpAMD64CALLstatic:
+ p := Prog(obj.ACALL)
+ p.To.Type = obj.TYPE_MEM
+ p.To.Name = obj.NAME_EXTERN
+ p.To.Sym = Linksym(v.Aux.(*Sym))
+ if Maxarg < v.AuxInt {
+ Maxarg = v.AuxInt
+ }
+ case ssa.OpAMD64CALLclosure:
+ p := Prog(obj.ACALL)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v.Args[0])
+ if Maxarg < v.AuxInt {
+ Maxarg = v.AuxInt
+ }
+ case ssa.OpAMD64CALLdefer:
+ p := Prog(obj.ACALL)
+ p.To.Type = obj.TYPE_MEM
+ p.To.Name = obj.NAME_EXTERN
+ p.To.Sym = Linksym(Deferproc.Sym)
+ if Maxarg < v.AuxInt {
+ Maxarg = v.AuxInt
+ }
+ // defer returns in rax:
+ // 0 if we should continue executing
+ // 1 if we should jump to deferreturn call
+ p = Prog(x86.ATESTL)
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x86.REG_AX
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = x86.REG_AX
+ p = Prog(x86.AJNE)
+ p.To.Type = obj.TYPE_BRANCH
+ s.deferBranches = append(s.deferBranches, p)
+ case ssa.OpAMD64CALLgo:
+ p := Prog(obj.ACALL)
+ p.To.Type = obj.TYPE_MEM
+ p.To.Name = obj.NAME_EXTERN
+ p.To.Sym = Linksym(Newproc.Sym)
+ if Maxarg < v.AuxInt {
+ Maxarg = v.AuxInt
+ }
+ case ssa.OpAMD64CALLinter:
+ p := Prog(obj.ACALL)
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v.Args[0])
+ if Maxarg < v.AuxInt {
+ Maxarg = v.AuxInt
+ }
+ case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL, ssa.OpAMD64NEGW, ssa.OpAMD64NEGB,
+ ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL, ssa.OpAMD64NOTW, ssa.OpAMD64NOTB:
+ x := regnum(v.Args[0])
+ r := regnum(v)
+ if x != r {
+ p := Prog(regMoveAMD64(v.Type.Size()))
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = x
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ }
+ p := Prog(v.Op.Asm())
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
+ case ssa.OpAMD64SQRTSD:
+ p := Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = regnum(v.Args[0])
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ case ssa.OpSP, ssa.OpSB:
+ // nothing to do
+ case ssa.OpAMD64SETEQ, ssa.OpAMD64SETNE,
+ ssa.OpAMD64SETL, ssa.OpAMD64SETLE,
+ ssa.OpAMD64SETG, ssa.OpAMD64SETGE,
+ ssa.OpAMD64SETGF, ssa.OpAMD64SETGEF,
+ ssa.OpAMD64SETB, ssa.OpAMD64SETBE,
+ ssa.OpAMD64SETORD, ssa.OpAMD64SETNAN,
+ ssa.OpAMD64SETA, ssa.OpAMD64SETAE:
+ p := Prog(v.Op.Asm())
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+
+ case ssa.OpAMD64SETNEF:
+ p := Prog(v.Op.Asm())
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ q := Prog(x86.ASETPS)
+ q.To.Type = obj.TYPE_REG
+ q.To.Reg = x86.REG_AX
+ // TODO AORQ copied from old code generator, why not AORB?
+ opregreg(x86.AORQ, regnum(v), x86.REG_AX)
+
+ case ssa.OpAMD64SETEQF:
+ p := Prog(v.Op.Asm())
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = regnum(v)
+ q := Prog(x86.ASETPC)
+ q.To.Type = obj.TYPE_REG
+ q.To.Reg = x86.REG_AX
+ // TODO AANDQ copied from old code generator, why not AANDB?
+ opregreg(x86.AANDQ, regnum(v), x86.REG_AX)
+
+ case ssa.OpAMD64InvertFlags:
+ v.Fatalf("InvertFlags should never make it to codegen %v", v)
+ case ssa.OpAMD64REPSTOSQ:
+ Prog(x86.AREP)
+ Prog(x86.ASTOSQ)
+ case ssa.OpAMD64REPMOVSB:
+ Prog(x86.AREP)
+ Prog(x86.AMOVSB)
+ case ssa.OpVarDef:
+ Gvardef(v.Aux.(*Node))
+ case ssa.OpVarKill:
+ gvarkill(v.Aux.(*Node))
+ default:
+ v.Unimplementedf("genValue not implemented: %s", v.LongString())
+ }
+}
+
+// movSizeByType returns the MOV instruction of the given type.
+func movSizeByType(t ssa.Type) (asm int) {
+ // For x86, there's no difference between reg move opcodes
+ // and memory move opcodes.
+ asm = regMoveByTypeAMD64(t)
+ return
+}
+
+// movZero generates a register indirect move with a 0 immediate and keeps track of bytes left and next offset
+func movZero(as int, width int64, nbytes int64, offset int64, regnum int16) (nleft int64, noff int64) {
+ p := Prog(as)
+ // TODO: use zero register on archs that support it.
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 0
+ p.To.Type = obj.TYPE_MEM
+ p.To.Reg = regnum
+ p.To.Offset = offset
+ offset += width
+ nleft = nbytes - width
+ return nleft, offset
+}
+
+var blockJump = [...]struct {
+ asm, invasm int
+}{
+ ssa.BlockAMD64EQ: {x86.AJEQ, x86.AJNE},
+ ssa.BlockAMD64NE: {x86.AJNE, x86.AJEQ},
+ ssa.BlockAMD64LT: {x86.AJLT, x86.AJGE},
+ ssa.BlockAMD64GE: {x86.AJGE, x86.AJLT},
+ ssa.BlockAMD64LE: {x86.AJLE, x86.AJGT},
+ ssa.BlockAMD64GT: {x86.AJGT, x86.AJLE},
+ ssa.BlockAMD64ULT: {x86.AJCS, x86.AJCC},
+ ssa.BlockAMD64UGE: {x86.AJCC, x86.AJCS},
+ ssa.BlockAMD64UGT: {x86.AJHI, x86.AJLS},
+ ssa.BlockAMD64ULE: {x86.AJLS, x86.AJHI},
+ ssa.BlockAMD64ORD: {x86.AJPC, x86.AJPS},
+ ssa.BlockAMD64NAN: {x86.AJPS, x86.AJPC},
+}
+
+type floatingEQNEJump struct {
+ jump, index int
+}
+
+var eqfJumps = [2][2]floatingEQNEJump{
+ {{x86.AJNE, 1}, {x86.AJPS, 1}}, // next == b.Succs[0]
+ {{x86.AJNE, 1}, {x86.AJPC, 0}}, // next == b.Succs[1]
+}
+var nefJumps = [2][2]floatingEQNEJump{
+ {{x86.AJNE, 0}, {x86.AJPC, 1}}, // next == b.Succs[0]
+ {{x86.AJNE, 0}, {x86.AJPS, 0}}, // next == b.Succs[1]
+}
+
+func oneFPJump(b *ssa.Block, jumps *floatingEQNEJump, likely ssa.BranchPrediction, branches []branch) []branch {
+ p := Prog(jumps.jump)
+ p.To.Type = obj.TYPE_BRANCH
+ to := jumps.index
+ branches = append(branches, branch{p, b.Succs[to]})
+ if to == 1 {
+ likely = -likely
+ }
+ // liblink reorders the instruction stream as it sees fit.
+ // Pass along what we know so liblink can make use of it.
+ // TODO: Once we've fully switched to SSA,
+ // make liblink leave our output alone.
+ switch likely {
+ case ssa.BranchUnlikely:
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 0
+ case ssa.BranchLikely:
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 1
+ }
+ return branches
+}
+
+func genFPJump(s *genState, b, next *ssa.Block, jumps *[2][2]floatingEQNEJump) {
+ likely := b.Likely
+ switch next {
+ case b.Succs[0]:
+ s.branches = oneFPJump(b, &jumps[0][0], likely, s.branches)
+ s.branches = oneFPJump(b, &jumps[0][1], likely, s.branches)
+ case b.Succs[1]:
+ s.branches = oneFPJump(b, &jumps[1][0], likely, s.branches)
+ s.branches = oneFPJump(b, &jumps[1][1], likely, s.branches)
+ default:
+ s.branches = oneFPJump(b, &jumps[1][0], likely, s.branches)
+ s.branches = oneFPJump(b, &jumps[1][1], likely, s.branches)
+ q := Prog(obj.AJMP)
+ q.To.Type = obj.TYPE_BRANCH
+ s.branches = append(s.branches, branch{q, b.Succs[1]})
+ }
+}
+
+func (s *genState) genBlock(b, next *ssa.Block) {
+ lineno = b.Line
+
+ switch b.Kind {
+ case ssa.BlockPlain, ssa.BlockCall:
+ if b.Succs[0] != next {
+ p := Prog(obj.AJMP)
+ p.To.Type = obj.TYPE_BRANCH
+ s.branches = append(s.branches, branch{p, b.Succs[0]})
+ }
+ case ssa.BlockExit:
+ Prog(obj.AUNDEF) // tell plive.go that we never reach here
+ case ssa.BlockRet:
+ if hasdefer {
+ s.deferReturn()
+ }
+ Prog(obj.ARET)
+ case ssa.BlockRetJmp:
+ p := Prog(obj.AJMP)
+ p.To.Type = obj.TYPE_MEM
+ p.To.Name = obj.NAME_EXTERN
+ p.To.Sym = Linksym(b.Aux.(*Sym))
+
+ case ssa.BlockAMD64EQF:
+ genFPJump(s, b, next, &eqfJumps)
+
+ case ssa.BlockAMD64NEF:
+ genFPJump(s, b, next, &nefJumps)
+
+ case ssa.BlockAMD64EQ, ssa.BlockAMD64NE,
+ ssa.BlockAMD64LT, ssa.BlockAMD64GE,
+ ssa.BlockAMD64LE, ssa.BlockAMD64GT,
+ ssa.BlockAMD64ULT, ssa.BlockAMD64UGT,
+ ssa.BlockAMD64ULE, ssa.BlockAMD64UGE:
+ jmp := blockJump[b.Kind]
+ likely := b.Likely
+ var p *obj.Prog
+ switch next {
+ case b.Succs[0]:
+ p = Prog(jmp.invasm)
+ likely *= -1
+ p.To.Type = obj.TYPE_BRANCH
+ s.branches = append(s.branches, branch{p, b.Succs[1]})
+ case b.Succs[1]:
+ p = Prog(jmp.asm)
+ p.To.Type = obj.TYPE_BRANCH
+ s.branches = append(s.branches, branch{p, b.Succs[0]})
+ default:
+ p = Prog(jmp.asm)
+ p.To.Type = obj.TYPE_BRANCH
+ s.branches = append(s.branches, branch{p, b.Succs[0]})
+ q := Prog(obj.AJMP)
+ q.To.Type = obj.TYPE_BRANCH
+ s.branches = append(s.branches, branch{q, b.Succs[1]})
+ }
+
+ // liblink reorders the instruction stream as it sees fit.
+ // Pass along what we know so liblink can make use of it.
+ // TODO: Once we've fully switched to SSA,
+ // make liblink leave our output alone.
+ switch likely {
+ case ssa.BranchUnlikely:
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 0
+ case ssa.BranchLikely:
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 1
+ }
+
+ default:
+ b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
+ }
+}
+
+func (s *genState) deferReturn() {
+ // Deferred calls will appear to be returning to
+ // the CALL deferreturn(SB) that we are about to emit.
+ // However, the stack trace code will show the line
+ // of the instruction byte before the return PC.
+ // To avoid that being an unrelated instruction,
+ // insert an actual hardware NOP that will have the right line number.
+ // This is different from obj.ANOP, which is a virtual no-op
+ // that doesn't make it into the instruction stream.
+ s.deferTarget = Pc
+ Thearch.Ginsnop()
+ p := Prog(obj.ACALL)
+ p.To.Type = obj.TYPE_MEM
+ p.To.Name = obj.NAME_EXTERN
+ p.To.Sym = Linksym(Deferreturn.Sym)
+}
+
+// addAux adds the offset in the aux fields (AuxInt and Aux) of v to a.
+func addAux(a *obj.Addr, v *ssa.Value) {
+ if a.Type != obj.TYPE_MEM {
+ v.Fatalf("bad addAux addr %s", a)
+ }
+ // add integer offset
+ a.Offset += v.AuxInt
+
+ // If no additional symbol offset, we're done.
+ if v.Aux == nil {
+ return
+ }
+ // Add symbol's offset from its base register.
+ switch sym := v.Aux.(type) {
+ case *ssa.ExternSymbol:
+ a.Name = obj.NAME_EXTERN
+ a.Sym = Linksym(sym.Sym.(*Sym))
+ case *ssa.ArgSymbol:
+ n := sym.Node.(*Node)
+ a.Name = obj.NAME_PARAM
+ a.Node = n
+ a.Sym = Linksym(n.Orig.Sym)
+ a.Offset += n.Xoffset // TODO: why do I have to add this here? I don't for auto variables.
+ case *ssa.AutoSymbol:
+ n := sym.Node.(*Node)
+ a.Name = obj.NAME_AUTO
+ a.Node = n
+ a.Sym = Linksym(n.Sym)
+ default:
+ v.Fatalf("aux in %s not implemented %#v", v, v.Aux)
+ }
+}
+
+// extendIndex extends v to a full pointer width.
+func (s *state) extendIndex(v *ssa.Value) *ssa.Value {
+ size := v.Type.Size()
+ if size == s.config.PtrSize {
+ return v
+ }
+ if size > s.config.PtrSize {
+ // TODO: truncate 64-bit indexes on 32-bit pointer archs. We'd need to test
+ // the high word and branch to out-of-bounds failure if it is not 0.
+ s.Unimplementedf("64->32 index truncation not implemented")
+ return v
+ }
+
+ // Extend value to the required size
+ var op ssa.Op
+ if v.Type.IsSigned() {
+ switch 10*size + s.config.PtrSize {
+ case 14:
+ op = ssa.OpSignExt8to32
+ case 18:
+ op = ssa.OpSignExt8to64
+ case 24:
+ op = ssa.OpSignExt16to32
+ case 28:
+ op = ssa.OpSignExt16to64
+ case 48:
+ op = ssa.OpSignExt32to64
+ default:
+ s.Fatalf("bad signed index extension %s", v.Type)
+ }
+ } else {
+ switch 10*size + s.config.PtrSize {
+ case 14:
+ op = ssa.OpZeroExt8to32
+ case 18:
+ op = ssa.OpZeroExt8to64
+ case 24:
+ op = ssa.OpZeroExt16to32
+ case 28:
+ op = ssa.OpZeroExt16to64
+ case 48:
+ op = ssa.OpZeroExt32to64
+ default:
+ s.Fatalf("bad unsigned index extension %s", v.Type)
+ }
+ }
+ return s.newValue1(op, Types[TUINTPTR], v)
+}
+
+// ssaRegToReg maps ssa register numbers to obj register numbers.
+var ssaRegToReg = [...]int16{
+ x86.REG_AX,
+ x86.REG_CX,
+ x86.REG_DX,
+ x86.REG_BX,
+ x86.REG_SP,
+ x86.REG_BP,
+ x86.REG_SI,
+ x86.REG_DI,
+ x86.REG_R8,
+ x86.REG_R9,
+ x86.REG_R10,
+ x86.REG_R11,
+ x86.REG_R12,
+ x86.REG_R13,
+ x86.REG_R14,
+ x86.REG_R15,
+ x86.REG_X0,
+ x86.REG_X1,
+ x86.REG_X2,
+ x86.REG_X3,
+ x86.REG_X4,
+ x86.REG_X5,
+ x86.REG_X6,
+ x86.REG_X7,
+ x86.REG_X8,
+ x86.REG_X9,
+ x86.REG_X10,
+ x86.REG_X11,
+ x86.REG_X12,
+ x86.REG_X13,
+ x86.REG_X14,
+ x86.REG_X15,
+ 0, // SB isn't a real register. We fill an Addr.Reg field with 0 in this case.
+ // TODO: arch-dependent
+}
+
+// regMoveAMD64 returns the register->register move opcode for the given width.
+// TODO: generalize for all architectures?
+func regMoveAMD64(width int64) int {
+ switch width {
+ case 1:
+ return x86.AMOVB
+ case 2:
+ return x86.AMOVW
+ case 4:
+ return x86.AMOVL
+ case 8:
+ return x86.AMOVQ
+ default:
+ panic("bad int register width")
+ }
+}
+
+func regMoveByTypeAMD64(t ssa.Type) int {
+ width := t.Size()
+ if t.IsFloat() {
+ switch width {
+ case 4:
+ return x86.AMOVSS
+ case 8:
+ return x86.AMOVSD
+ default:
+ panic("bad float register width")
+ }
+ } else {
+ switch width {
+ case 1:
+ return x86.AMOVB
+ case 2:
+ return x86.AMOVW
+ case 4:
+ return x86.AMOVL
+ case 8:
+ return x86.AMOVQ
+ default:
+ panic("bad int register width")
+ }
+ }
+
+ panic("bad register type")
+}
+
+// regnum returns the register (in cmd/internal/obj numbering) to
+// which v has been allocated. Panics if v is not assigned to a
+// register.
+// TODO: Make this panic again once it stops happening routinely.
+func regnum(v *ssa.Value) int16 {
+ reg := v.Block.Func.RegAlloc[v.ID]
+ if reg == nil {
+ v.Unimplementedf("nil regnum for value: %s\n%s\n", v.LongString(), v.Block.Func)
+ return 0
+ }
+ return ssaRegToReg[reg.(*ssa.Register).Num]
+}
+
+// autoVar returns a *Node representing the auto variable assigned to v.
+func autoVar(v *ssa.Value) *Node {
+ return v.Block.Func.RegAlloc[v.ID].(*ssa.LocalSlot).N.(*Node)
+}
+
+// ssaExport exports a bunch of compiler services for the ssa backend.
+type ssaExport struct {
+ log bool
+ unimplemented bool
+ mustImplement bool
+}
+
+func (s *ssaExport) TypeBool() ssa.Type { return Types[TBOOL] }
+func (s *ssaExport) TypeInt8() ssa.Type { return Types[TINT8] }
+func (s *ssaExport) TypeInt16() ssa.Type { return Types[TINT16] }
+func (s *ssaExport) TypeInt32() ssa.Type { return Types[TINT32] }
+func (s *ssaExport) TypeInt64() ssa.Type { return Types[TINT64] }
+func (s *ssaExport) TypeUInt8() ssa.Type { return Types[TUINT8] }
+func (s *ssaExport) TypeUInt16() ssa.Type { return Types[TUINT16] }
+func (s *ssaExport) TypeUInt32() ssa.Type { return Types[TUINT32] }
+func (s *ssaExport) TypeUInt64() ssa.Type { return Types[TUINT64] }
+func (s *ssaExport) TypeFloat32() ssa.Type { return Types[TFLOAT32] }
+func (s *ssaExport) TypeFloat64() ssa.Type { return Types[TFLOAT64] }
+func (s *ssaExport) TypeInt() ssa.Type { return Types[TINT] }
+func (s *ssaExport) TypeUintptr() ssa.Type { return Types[TUINTPTR] }
+func (s *ssaExport) TypeString() ssa.Type { return Types[TSTRING] }
+func (s *ssaExport) TypeBytePtr() ssa.Type { return Ptrto(Types[TUINT8]) }
+
+// StringData returns a symbol (a *Sym wrapped in an interface) which
+// is the data component of a global string constant containing s.
+func (*ssaExport) StringData(s string) interface{} {
+ // TODO: is idealstring correct? It might not matter...
+ _, data := stringsym(s)
+ return &ssa.ExternSymbol{Typ: idealstring, Sym: data}
+}
+
+func (e *ssaExport) Auto(t ssa.Type) fmt.Stringer {
+ n := temp(t.(*Type)) // Note: adds new auto to Curfn.Func.Dcl list
+ e.mustImplement = true // This modifies the input to SSA, so we want to make sure we succeed from here!
+ return n
+}
+
+func (e ssaExport) CanSSA(t ssa.Type) bool {
+ return canSSAType(t.(*Type))
+}
+
+// Log logs a message from the compiler.
+func (e *ssaExport) Logf(msg string, args ...interface{}) {
+ // If e was marked as unimplemented, anything could happen. Ignore.
+ if e.log && !e.unimplemented {
+ fmt.Printf(msg, args...)
+ }
+}
+
+// Fatal reports a compiler error and exits.
+func (e *ssaExport) Fatalf(msg string, args ...interface{}) {
+ // If e was marked as unimplemented, anything could happen. Ignore.
+ if !e.unimplemented {
+ Fatalf(msg, args...)
+ }
+}
+
+// Unimplemented reports that the function cannot be compiled.
+// It will be removed once SSA work is complete.
+func (e *ssaExport) Unimplementedf(msg string, args ...interface{}) {
+ if e.mustImplement {
+ Fatalf(msg, args...)
+ }
+ const alwaysLog = false // enable to calculate top unimplemented features
+ if !e.unimplemented && (e.log || alwaysLog) {
+ // first implementation failure, print explanation
+ fmt.Printf("SSA unimplemented: "+msg+"\n", args...)
+ }
+ e.unimplemented = true
+}
--- /dev/null
- (Zero [size] destptr mem) && size <= 1024 && size%8 == 0 ->
- (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVQconst [0]) mem)
+// 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.
+
+// x86 register conventions:
+// - Integer types live in the low portion of registers. Upper portions are junk.
+// - Boolean types use the low-order byte of a register. Upper bytes are junk.
+// - We do not use AH,BH,CH,DH registers.
+// - Floating-point types will live in the low natural slot of an sse2 register.
+// Unused portions are junk.
+
+// Lowering arithmetic
+(Add64 x y) -> (ADDQ x y)
+(AddPtr x y) -> (ADDQ x y)
+(Add32 x y) -> (ADDL x y)
+(Add16 x y) -> (ADDW x y)
+(Add8 x y) -> (ADDB x y)
+(Add32F x y) -> (ADDSS x y)
+(Add64F x y) -> (ADDSD x y)
+
+(Sub64 x y) -> (SUBQ x y)
+(SubPtr x y) -> (SUBQ x y)
+(Sub32 x y) -> (SUBL x y)
+(Sub16 x y) -> (SUBW x y)
+(Sub8 x y) -> (SUBB x y)
+(Sub32F x y) -> (SUBSS x y)
+(Sub64F x y) -> (SUBSD x y)
+
+(Mul64 x y) -> (MULQ x y)
+(MulPtr x y) -> (MULQ x y)
+(Mul32 x y) -> (MULL x y)
+(Mul16 x y) -> (MULW x y)
+(Mul8 x y) -> (MULB x y)
+(Mul32F x y) -> (MULSS x y)
+(Mul64F x y) -> (MULSD x y)
+
+(Div32F x y) -> (DIVSS x y)
+(Div64F x y) -> (DIVSD x y)
+
+(Div64 x y) -> (DIVQ x y)
+(Div64u x y) -> (DIVQU x y)
+(Div32 x y) -> (DIVL x y)
+(Div32u x y) -> (DIVLU x y)
+(Div16 x y) -> (DIVW x y)
+(Div16u x y) -> (DIVWU x y)
+(Div8 x y) -> (DIVW (SignExt8to16 x) (SignExt8to16 y))
+(Div8u x y) -> (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+
+(Hmul32 x y) -> (HMULL x y)
+(Hmul32u x y) -> (HMULLU x y)
+(Hmul16 x y) -> (HMULW x y)
+(Hmul16u x y) -> (HMULWU x y)
+(Hmul8 x y) -> (HMULB x y)
+(Hmul8u x y) -> (HMULBU x y)
+
+(Mod64 x y) -> (MODQ x y)
+(Mod64u x y) -> (MODQU x y)
+(Mod32 x y) -> (MODL x y)
+(Mod32u x y) -> (MODLU x y)
+(Mod16 x y) -> (MODW x y)
+(Mod16u x y) -> (MODWU x y)
+(Mod8 x y) -> (MODW (SignExt8to16 x) (SignExt8to16 y))
+(Mod8u x y) -> (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+
+(And64 x y) -> (ANDQ x y)
+(And32 x y) -> (ANDL x y)
+(And16 x y) -> (ANDW x y)
+(And8 x y) -> (ANDB x y)
+
+(Or64 x y) -> (ORQ x y)
+(Or32 x y) -> (ORL x y)
+(Or16 x y) -> (ORW x y)
+(Or8 x y) -> (ORB x y)
+
+(Xor64 x y) -> (XORQ x y)
+(Xor32 x y) -> (XORL x y)
+(Xor16 x y) -> (XORW x y)
+(Xor8 x y) -> (XORB x y)
+
+(Neg64 x) -> (NEGQ x)
+(Neg32 x) -> (NEGL x)
+(Neg16 x) -> (NEGW x)
+(Neg8 x) -> (NEGB x)
+(Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
+(Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
+
+(Com64 x) -> (NOTQ x)
+(Com32 x) -> (NOTL x)
+(Com16 x) -> (NOTW x)
+(Com8 x) -> (NOTB x)
+
+(Sqrt x) -> (SQRTSD x)
+
+// Note: we always extend to 64 bits even though some ops don't need that many result bits.
+(SignExt8to16 x) -> (MOVBQSX x)
+(SignExt8to32 x) -> (MOVBQSX x)
+(SignExt8to64 x) -> (MOVBQSX x)
+(SignExt16to32 x) -> (MOVWQSX x)
+(SignExt16to64 x) -> (MOVWQSX x)
+(SignExt32to64 x) -> (MOVLQSX x)
+
+(ZeroExt8to16 x) -> (MOVBQZX x)
+(ZeroExt8to32 x) -> (MOVBQZX x)
+(ZeroExt8to64 x) -> (MOVBQZX x)
+(ZeroExt16to32 x) -> (MOVWQZX x)
+(ZeroExt16to64 x) -> (MOVWQZX x)
+(ZeroExt32to64 x) -> (MOVLQZX x)
+
+(Cvt32to32F x) -> (CVTSL2SS x)
+(Cvt32to64F x) -> (CVTSL2SD x)
+(Cvt64to32F x) -> (CVTSQ2SS x)
+(Cvt64to64F x) -> (CVTSQ2SD x)
+
+(Cvt32Fto32 x) -> (CVTTSS2SL x)
+(Cvt32Fto64 x) -> (CVTTSS2SQ x)
+(Cvt64Fto32 x) -> (CVTTSD2SL x)
+(Cvt64Fto64 x) -> (CVTTSD2SQ x)
+
+(Cvt32Fto64F x) -> (CVTSS2SD x)
+(Cvt64Fto32F x) -> (CVTSD2SS x)
+
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8 x) -> x
+(Trunc32to8 x) -> x
+(Trunc32to16 x) -> x
+(Trunc64to8 x) -> x
+(Trunc64to16 x) -> x
+(Trunc64to32 x) -> x
+
+// Lowering shifts
+// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
+// result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
+// Note: for small shifts we generate 32 bits of mask even when we don't need it all.
+(Lsh64x64 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPQconst [64] y)))
+(Lsh64x32 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPLconst [64] y)))
+(Lsh64x16 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPWconst [64] y)))
+(Lsh64x8 <t> x y) -> (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst [64] y)))
+
+(Lsh32x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst [32] y)))
+(Lsh32x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst [32] y)))
+(Lsh32x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst [32] y)))
+(Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst [32] y)))
+
+(Lsh16x64 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPQconst [16] y)))
+(Lsh16x32 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPLconst [16] y)))
+(Lsh16x16 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPWconst [16] y)))
+(Lsh16x8 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPBconst [16] y)))
+
+(Lsh8x64 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPQconst [8] y)))
+(Lsh8x32 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPLconst [8] y)))
+(Lsh8x16 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPWconst [8] y)))
+(Lsh8x8 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPBconst [8] y)))
+
+(Lrot64 <t> x [c]) -> (ROLQconst <t> [c&63] x)
+(Lrot32 <t> x [c]) -> (ROLLconst <t> [c&31] x)
+(Lrot16 <t> x [c]) -> (ROLWconst <t> [c&15] x)
+(Lrot8 <t> x [c]) -> (ROLBconst <t> [c&7] x)
+
+(Rsh64Ux64 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPQconst [64] y)))
+(Rsh64Ux32 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPLconst [64] y)))
+(Rsh64Ux16 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPWconst [64] y)))
+(Rsh64Ux8 <t> x y) -> (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst [64] y)))
+
+(Rsh32Ux64 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPQconst [32] y)))
+(Rsh32Ux32 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPLconst [32] y)))
+(Rsh32Ux16 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst [32] y)))
+(Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst [32] y)))
+
+(Rsh16Ux64 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst [16] y)))
+(Rsh16Ux32 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst [16] y)))
+(Rsh16Ux16 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst [16] y)))
+(Rsh16Ux8 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst [16] y)))
+
+(Rsh8Ux64 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst [8] y)))
+(Rsh8Ux32 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst [8] y)))
+(Rsh8Ux16 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst [8] y)))
+(Rsh8Ux8 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst [8] y)))
+
+// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
+// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
+// Note: for small shift widths we generate 32 bits of mask even when we don't need it all.
+(Rsh64x64 <t> x y) -> (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [64] y)))))
+(Rsh64x32 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [64] y)))))
+(Rsh64x16 <t> x y) -> (SARQ <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [64] y)))))
+(Rsh64x8 <t> x y) -> (SARQ <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [64] y)))))
+
+(Rsh32x64 <t> x y) -> (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [32] y)))))
+(Rsh32x32 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [32] y)))))
+(Rsh32x16 <t> x y) -> (SARL <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [32] y)))))
+(Rsh32x8 <t> x y) -> (SARL <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [32] y)))))
+
+(Rsh16x64 <t> x y) -> (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [16] y)))))
+(Rsh16x32 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [16] y)))))
+(Rsh16x16 <t> x y) -> (SARW <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [16] y)))))
+(Rsh16x8 <t> x y) -> (SARW <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [16] y)))))
+
+(Rsh8x64 <t> x y) -> (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [8] y)))))
+(Rsh8x32 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [8] y)))))
+(Rsh8x16 <t> x y) -> (SARB <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [8] y)))))
+(Rsh8x8 <t> x y) -> (SARB <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [8] y)))))
+
+(Less64 x y) -> (SETL (CMPQ x y))
+(Less32 x y) -> (SETL (CMPL x y))
+(Less16 x y) -> (SETL (CMPW x y))
+(Less8 x y) -> (SETL (CMPB x y))
+(Less64U x y) -> (SETB (CMPQ x y))
+(Less32U x y) -> (SETB (CMPL x y))
+(Less16U x y) -> (SETB (CMPW x y))
+(Less8U x y) -> (SETB (CMPB x y))
+// Use SETGF with reversed operands to dodge NaN case
+(Less64F x y) -> (SETGF (UCOMISD y x))
+(Less32F x y) -> (SETGF (UCOMISS y x))
+
+(Leq64 x y) -> (SETLE (CMPQ x y))
+(Leq32 x y) -> (SETLE (CMPL x y))
+(Leq16 x y) -> (SETLE (CMPW x y))
+(Leq8 x y) -> (SETLE (CMPB x y))
+(Leq64U x y) -> (SETBE (CMPQ x y))
+(Leq32U x y) -> (SETBE (CMPL x y))
+(Leq16U x y) -> (SETBE (CMPW x y))
+(Leq8U x y) -> (SETBE (CMPB x y))
+// Use SETGEF with reversed operands to dodge NaN case
+(Leq64F x y) -> (SETGEF (UCOMISD y x))
+(Leq32F x y) -> (SETGEF (UCOMISS y x))
+
+(Greater64 x y) -> (SETG (CMPQ x y))
+(Greater32 x y) -> (SETG (CMPL x y))
+(Greater16 x y) -> (SETG (CMPW x y))
+(Greater8 x y) -> (SETG (CMPB x y))
+(Greater64U x y) -> (SETA (CMPQ x y))
+(Greater32U x y) -> (SETA (CMPL x y))
+(Greater16U x y) -> (SETA (CMPW x y))
+(Greater8U x y) -> (SETA (CMPB x y))
+// Note Go assembler gets UCOMISx operand order wrong, but it is right here
+// Bug is accommodated at generation of assembly language.
+(Greater64F x y) -> (SETGF (UCOMISD x y))
+(Greater32F x y) -> (SETGF (UCOMISS x y))
+
+(Geq64 x y) -> (SETGE (CMPQ x y))
+(Geq32 x y) -> (SETGE (CMPL x y))
+(Geq16 x y) -> (SETGE (CMPW x y))
+(Geq8 x y) -> (SETGE (CMPB x y))
+(Geq64U x y) -> (SETAE (CMPQ x y))
+(Geq32U x y) -> (SETAE (CMPL x y))
+(Geq16U x y) -> (SETAE (CMPW x y))
+(Geq8U x y) -> (SETAE (CMPB x y))
+// Note Go assembler gets UCOMISx operand order wrong, but it is right here
+// Bug is accommodated at generation of assembly language.
+(Geq64F x y) -> (SETGEF (UCOMISD x y))
+(Geq32F x y) -> (SETGEF (UCOMISS x y))
+
+(Eq64 x y) -> (SETEQ (CMPQ x y))
+(Eq32 x y) -> (SETEQ (CMPL x y))
+(Eq16 x y) -> (SETEQ (CMPW x y))
+(Eq8 x y) -> (SETEQ (CMPB x y))
+(EqPtr x y) -> (SETEQ (CMPQ x y))
+(Eq64F x y) -> (SETEQF (UCOMISD x y))
+(Eq32F x y) -> (SETEQF (UCOMISS x y))
+
+(Neq64 x y) -> (SETNE (CMPQ x y))
+(Neq32 x y) -> (SETNE (CMPL x y))
+(Neq16 x y) -> (SETNE (CMPW x y))
+(Neq8 x y) -> (SETNE (CMPB x y))
+(NeqPtr x y) -> (SETNE (CMPQ x y))
+(Neq64F x y) -> (SETNEF (UCOMISD x y))
+(Neq32F x y) -> (SETNEF (UCOMISS x y))
+
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVQload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) -> (MOVLload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) -> (MOVWload ptr mem)
+(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) -> (MOVBload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) -> (MOVSSload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) -> (MOVSDload ptr mem)
+
+// These more-specific FP versions of Store pattern should come first.
+(Store [8] ptr val mem) && is64BitFloat(val.Type) -> (MOVSDstore ptr val mem)
+(Store [4] ptr val mem) && is32BitFloat(val.Type) -> (MOVSSstore ptr val mem)
+
+(Store [8] ptr val mem) -> (MOVQstore ptr val mem)
+(Store [4] ptr val mem) -> (MOVLstore ptr val mem)
+(Store [2] ptr val mem) -> (MOVWstore ptr val mem)
+(Store [1] ptr val mem) -> (MOVBstore ptr val mem)
+
+// checks
+(IsNonNil p) -> (SETNE (TESTQ p p))
+(IsInBounds idx len) -> (SETB (CMPQ idx len))
+(IsSliceInBounds idx len) -> (SETBE (CMPQ idx len))
+
+(PanicNilCheck ptr mem) -> (LoweredPanicNilCheck ptr mem)
+(GetG) -> (LoweredGetG)
+(GetClosurePtr) -> (LoweredGetClosurePtr)
+
+(Move [size] dst src mem) -> (REPMOVSB dst src (MOVQconst <config.Frontend().TypeUInt64()> [size]) mem)
+
+(Not x) -> (XORBconst [1] x)
+
+(OffPtr [off] ptr) -> (ADDQconst [off] ptr)
+
+(Const8 [val]) -> (MOVBconst [val])
+(Const16 [val]) -> (MOVWconst [val])
+(Const32 [val]) -> (MOVLconst [val])
+(Const64 [val]) -> (MOVQconst [val])
+(Const32F [val]) -> (MOVSSconst [val])
+(Const64F [val]) -> (MOVSDconst [val])
+(ConstPtr [val]) -> (MOVQconst [val])
+(ConstNil) -> (MOVQconst [0])
+(ConstBool [b]) -> (MOVBconst [b])
+
+(Addr {sym} base) -> (LEAQ {sym} base)
+
+(ITab (Load ptr mem)) -> (MOVQload ptr mem)
+
+// block rewrites
+(If (SETL cmp) yes no) -> (LT cmp yes no)
+(If (SETLE cmp) yes no) -> (LE cmp yes no)
+(If (SETG cmp) yes no) -> (GT cmp yes no)
+(If (SETGE cmp) yes no) -> (GE cmp yes no)
+(If (SETEQ cmp) yes no) -> (EQ cmp yes no)
+(If (SETNE cmp) yes no) -> (NE cmp yes no)
+(If (SETB cmp) yes no) -> (ULT cmp yes no)
+(If (SETBE cmp) yes no) -> (ULE cmp yes no)
+(If (SETA cmp) yes no) -> (UGT cmp yes no)
+(If (SETAE cmp) yes no) -> (UGE cmp yes no)
+
+// Special case for floating point - LF/LEF not generated
+(If (SETGF cmp) yes no) -> (UGT cmp yes no)
+(If (SETGEF cmp) yes no) -> (UGE cmp yes no)
+(If (SETEQF cmp) yes no) -> (EQF cmp yes no)
+(If (SETNEF cmp) yes no) -> (EQF cmp yes no)
+
+(If cond yes no) -> (NE (TESTB cond cond) yes no)
+
+(NE (TESTB (SETL cmp)) yes no) -> (LT cmp yes no)
+(NE (TESTB (SETLE cmp)) yes no) -> (LE cmp yes no)
+(NE (TESTB (SETG cmp)) yes no) -> (GT cmp yes no)
+(NE (TESTB (SETGE cmp)) yes no) -> (GE cmp yes no)
+(NE (TESTB (SETEQ cmp)) yes no) -> (EQ cmp yes no)
+(NE (TESTB (SETNE cmp)) yes no) -> (NE cmp yes no)
+(NE (TESTB (SETB cmp)) yes no) -> (ULT cmp yes no)
+(NE (TESTB (SETBE cmp)) yes no) -> (ULE cmp yes no)
+(NE (TESTB (SETA cmp)) yes no) -> (UGT cmp yes no)
+(NE (TESTB (SETAE cmp)) yes no) -> (UGE cmp yes no)
+
+// Special case for floating point - LF/LEF not generated
+(NE (TESTB (SETGF cmp)) yes no) -> (UGT cmp yes no)
+(NE (TESTB (SETGEF cmp)) yes no) -> (UGE cmp yes no)
+(NE (TESTB (SETEQF cmp)) yes no) -> (EQF cmp yes no)
+(NE (TESTB (SETNEF cmp)) yes no) -> (NEF cmp yes no)
+
+// Disabled because it interferes with the pattern match above and makes worse code.
+// (SETNEF x) -> (ORQ (SETNE <config.Frontend().TypeInt8()> x) (SETNAN <config.Frontend().TypeInt8()> x))
+// (SETEQF x) -> (ANDQ (SETEQ <config.Frontend().TypeInt8()> x) (SETORD <config.Frontend().TypeInt8()> x))
+
+(StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem)
+(ClosureCall [argwid] entry closure mem) -> (CALLclosure [argwid] entry closure mem)
+(DeferCall [argwid] mem) -> (CALLdefer [argwid] mem)
+(GoCall [argwid] mem) -> (CALLgo [argwid] mem)
+(InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
+
+// Rules below here apply some simple optimizations after lowering.
+// TODO: Should this be a separate pass?
+
+// fold constants into instructions
+(ADDQ x (MOVQconst [c])) && is32Bit(c) -> (ADDQconst [c] x)
+(ADDQ (MOVQconst [c]) x) && is32Bit(c) -> (ADDQconst [c] x)
+(ADDL x (MOVLconst [c])) -> (ADDLconst [c] x)
+(ADDL (MOVLconst [c]) x) -> (ADDLconst [c] x)
+(ADDW x (MOVWconst [c])) -> (ADDWconst [c] x)
+(ADDW (MOVWconst [c]) x) -> (ADDWconst [c] x)
+(ADDB x (MOVBconst [c])) -> (ADDBconst [c] x)
+(ADDB (MOVBconst [c]) x) -> (ADDBconst [c] x)
+
+(SUBQ x (MOVQconst [c])) && is32Bit(c) -> (SUBQconst x [c])
+(SUBQ (MOVQconst [c]) x) && is32Bit(c) -> (NEGQ (SUBQconst <v.Type> x [c]))
+(SUBL x (MOVLconst [c])) -> (SUBLconst x [c])
+(SUBL (MOVLconst [c]) x) -> (NEGL (SUBLconst <v.Type> x [c]))
+(SUBW x (MOVWconst [c])) -> (SUBWconst x [c])
+(SUBW (MOVWconst [c]) x) -> (NEGW (SUBWconst <v.Type> x [c]))
+(SUBB x (MOVBconst [c])) -> (SUBBconst x [c])
+(SUBB (MOVBconst [c]) x) -> (NEGB (SUBBconst <v.Type> x [c]))
+
+(MULQ x (MOVQconst [c])) && is32Bit(c) -> (MULQconst [c] x)
+(MULQ (MOVQconst [c]) x) && is32Bit(c) -> (MULQconst [c] x)
+(MULL x (MOVLconst [c])) -> (MULLconst [c] x)
+(MULL (MOVLconst [c]) x) -> (MULLconst [c] x)
+(MULW x (MOVWconst [c])) -> (MULWconst [c] x)
+(MULW (MOVWconst [c]) x) -> (MULWconst [c] x)
+(MULB x (MOVBconst [c])) -> (MULBconst [c] x)
+(MULB (MOVBconst [c]) x) -> (MULBconst [c] x)
+
+(ANDQ x (MOVQconst [c])) && is32Bit(c) -> (ANDQconst [c] x)
+(ANDQ (MOVQconst [c]) x) && is32Bit(c) -> (ANDQconst [c] x)
+(ANDL x (MOVLconst [c])) -> (ANDLconst [c] x)
+(ANDL (MOVLconst [c]) x) -> (ANDLconst [c] x)
+(ANDW x (MOVLconst [c])) -> (ANDWconst [c] x)
+(ANDW (MOVLconst [c]) x) -> (ANDWconst [c] x)
+(ANDW x (MOVWconst [c])) -> (ANDWconst [c] x)
+(ANDW (MOVWconst [c]) x) -> (ANDWconst [c] x)
+(ANDB x (MOVLconst [c])) -> (ANDBconst [c] x)
+(ANDB (MOVLconst [c]) x) -> (ANDBconst [c] x)
+(ANDB x (MOVBconst [c])) -> (ANDBconst [c] x)
+(ANDB (MOVBconst [c]) x) -> (ANDBconst [c] x)
+
+(ORQ x (MOVQconst [c])) && is32Bit(c) -> (ORQconst [c] x)
+(ORQ (MOVQconst [c]) x) && is32Bit(c) -> (ORQconst [c] x)
+(ORL x (MOVLconst [c])) -> (ORLconst [c] x)
+(ORL (MOVLconst [c]) x) -> (ORLconst [c] x)
+(ORW x (MOVWconst [c])) -> (ORWconst [c] x)
+(ORW (MOVWconst [c]) x) -> (ORWconst [c] x)
+(ORB x (MOVBconst [c])) -> (ORBconst [c] x)
+(ORB (MOVBconst [c]) x) -> (ORBconst [c] x)
+
+(XORQ x (MOVQconst [c])) && is32Bit(c) -> (XORQconst [c] x)
+(XORQ (MOVQconst [c]) x) && is32Bit(c) -> (XORQconst [c] x)
+(XORL x (MOVLconst [c])) -> (XORLconst [c] x)
+(XORL (MOVLconst [c]) x) -> (XORLconst [c] x)
+(XORW x (MOVWconst [c])) -> (XORWconst [c] x)
+(XORW (MOVWconst [c]) x) -> (XORWconst [c] x)
+(XORB x (MOVBconst [c])) -> (XORBconst [c] x)
+(XORB (MOVBconst [c]) x) -> (XORBconst [c] x)
+
+(SHLQ x (MOVQconst [c])) -> (SHLQconst [c&63] x)
+(SHLL x (MOVLconst [c])) -> (SHLLconst [c&31] x)
+(SHLW x (MOVWconst [c])) -> (SHLWconst [c&31] x)
+(SHLB x (MOVBconst [c])) -> (SHLBconst [c&31] x)
+
+(SHRQ x (MOVQconst [c])) -> (SHRQconst [c&63] x)
+(SHRL x (MOVLconst [c])) -> (SHRLconst [c&31] x)
+(SHRW x (MOVWconst [c])) -> (SHRWconst [c&31] x)
+(SHRB x (MOVBconst [c])) -> (SHRBconst [c&31] x)
+
+(SARQ x (MOVQconst [c])) -> (SARQconst [c&63] x)
+(SARL x (MOVLconst [c])) -> (SARLconst [c&31] x)
+(SARW x (MOVWconst [c])) -> (SARWconst [c&31] x)
+(SARB x (MOVBconst [c])) -> (SARBconst [c&31] x)
+
+// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
+// because the x86 instructions are defined to use all 5 bits of the shift even
+// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
+// (SHLW x (MOVWconst [24])), but just in case.
+
+(CMPQ x (MOVQconst [c])) && is32Bit(c) -> (CMPQconst x [c])
+(CMPQ (MOVQconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPQconst x [c]))
+(CMPL x (MOVLconst [c])) -> (CMPLconst x [c])
+(CMPL (MOVLconst [c]) x) -> (InvertFlags (CMPLconst x [c]))
+(CMPW x (MOVWconst [c])) -> (CMPWconst x [c])
+(CMPW (MOVWconst [c]) x) -> (InvertFlags (CMPWconst x [c]))
+(CMPB x (MOVBconst [c])) -> (CMPBconst x [c])
+(CMPB (MOVBconst [c]) x) -> (InvertFlags (CMPBconst x [c]))
+
+// strength reduction
+(MULQconst [-1] x) -> (NEGQ x)
+(MULQconst [0] _) -> (MOVQconst [0])
+(MULQconst [1] x) -> x
+(MULQconst [3] x) -> (LEAQ2 x x)
+(MULQconst [5] x) -> (LEAQ4 x x)
+(MULQconst [9] x) -> (LEAQ8 x x)
+(MULQconst [c] x) && isPowerOfTwo(c) -> (SHLQconst [log2(c)] x)
+
+// fold add/shift into leaq
+(ADDQ x (SHLQconst [3] y)) -> (LEAQ8 x y)
+(ADDQconst [c] (LEAQ8 [d] x y)) -> (LEAQ8 [addOff(c, d)] x y)
+
+// reverse ordering of compare instruction
+(SETL (InvertFlags x)) -> (SETG x)
+(SETG (InvertFlags x)) -> (SETL x)
+(SETB (InvertFlags x)) -> (SETA x)
+(SETA (InvertFlags x)) -> (SETB x)
+(SETLE (InvertFlags x)) -> (SETGE x)
+(SETGE (InvertFlags x)) -> (SETLE x)
+(SETBE (InvertFlags x)) -> (SETAE x)
+(SETAE (InvertFlags x)) -> (SETBE x)
+(SETEQ (InvertFlags x)) -> (SETEQ x)
+(SETNE (InvertFlags x)) -> (SETNE x)
+
+// sign extended loads
+// Note: The combined instruction must end up in the same block
+// as the original load. If not, we end up making a value with
+// memory type live in two different blocks, which can lead to
+// multiple memory values alive simultaneously.
+(MOVBQSX (MOVBload [off] {sym} ptr mem)) -> @v.Args[0].Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX (MOVBload [off] {sym} ptr mem)) -> @v.Args[0].Block (MOVBQZXload <v.Type> [off] {sym} ptr mem)
+// TODO: more
+
+// Don't extend before storing
+(MOVLstore [off] {sym} ptr (MOVLQSX x) mem) -> (MOVLstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWQSX x) mem) -> (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBQSX x) mem) -> (MOVBstore [off] {sym} ptr x mem)
+(MOVLstore [off] {sym} ptr (MOVLQZX x) mem) -> (MOVLstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWQZX x) mem) -> (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBQZX x) mem) -> (MOVBstore [off] {sym} ptr x mem)
+
+// fold constants into memory operations
+// Note that this is not always a good idea because if not all the uses of
+// the ADDQconst get eliminated, we still have to compute the ADDQconst and we now
+// have potentially two live values (ptr and (ADDQconst [off] ptr)) instead of one.
+// Nevertheless, let's do it!
+(MOVQload [off1] {sym} (ADDQconst [off2] ptr) mem) -> (MOVQload [addOff(off1, off2)] {sym} ptr mem)
+(MOVLload [off1] {sym} (ADDQconst [off2] ptr) mem) -> (MOVLload [addOff(off1, off2)] {sym} ptr mem)
+(MOVWload [off1] {sym} (ADDQconst [off2] ptr) mem) -> (MOVWload [addOff(off1, off2)] {sym} ptr mem)
+(MOVBload [off1] {sym} (ADDQconst [off2] ptr) mem) -> (MOVBload [addOff(off1, off2)] {sym} ptr mem)
+(MOVSSload [off1] {sym} (ADDQconst [off2] ptr) mem) -> (MOVSSload [addOff(off1, off2)] {sym} ptr mem)
+(MOVSDload [off1] {sym} (ADDQconst [off2] ptr) mem) -> (MOVSDload [addOff(off1, off2)] {sym} ptr mem)
+
+(MOVQstore [off1] {sym} (ADDQconst [off2] ptr) val mem) -> (MOVQstore [addOff(off1, off2)] {sym} ptr val mem)
+(MOVLstore [off1] {sym} (ADDQconst [off2] ptr) val mem) -> (MOVLstore [addOff(off1, off2)] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (ADDQconst [off2] ptr) val mem) -> (MOVWstore [addOff(off1, off2)] {sym} ptr val mem)
+(MOVBstore [off1] {sym} (ADDQconst [off2] ptr) val mem) -> (MOVBstore [addOff(off1, off2)] {sym} ptr val mem)
+(MOVSSstore [off1] {sym} (ADDQconst [off2] ptr) val mem) -> (MOVSSstore [addOff(off1, off2)] {sym} ptr val mem)
+(MOVSDstore [off1] {sym} (ADDQconst [off2] ptr) val mem) -> (MOVSDstore [addOff(off1, off2)] {sym} ptr val mem)
+
+// We need to fold LEAQ into the MOVx ops so that the live variable analysis knows
+// what variables are being read/written by the ops.
+(MOVQload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+ (MOVQload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+(MOVLload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+ (MOVLload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+(MOVWload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+ (MOVWload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+(MOVBload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+ (MOVBload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+(MOVSSload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+ (MOVSSload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+(MOVSDload [off1] {sym1} (LEAQ [off2] {sym2} base) mem) && canMergeSym(sym1, sym2) ->
+ (MOVSDload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+
+(MOVQstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVQstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+(MOVLstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVLstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+(MOVWstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVWstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+(MOVBstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVBstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+(MOVSSstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVSSstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+(MOVSDstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVSDstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+
+// indexed loads and stores
+(MOVQloadidx8 [off1] {sym} (ADDQconst [off2] ptr) idx mem) -> (MOVQloadidx8 [addOff(off1, off2)] {sym} ptr idx mem)
+(MOVQstoreidx8 [off1] {sym} (ADDQconst [off2] ptr) idx val mem) -> (MOVQstoreidx8 [addOff(off1, off2)] {sym} ptr idx val mem)
+(MOVSSloadidx4 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx mem) -> (MOVSSloadidx4 [addOff(off1, off2)] {sym} ptr idx mem)
+(MOVSSstoreidx4 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx val mem) -> (MOVSSstoreidx4 [addOff(off1, off2)] {sym} ptr idx val mem)
+(MOVSDloadidx8 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx mem) -> (MOVSDloadidx8 [addOff(off1, off2)] {sym} ptr idx mem)
+(MOVSDstoreidx8 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx val mem) -> (MOVSDstoreidx8 [addOff(off1, off2)] {sym} ptr idx val mem)
+
+(MOVQload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem) && canMergeSym(sym1, sym2) ->
+ (MOVQloadidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVQstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVQstoreidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx val mem)
+
+(MOVSSload [off1] {sym1} (LEAQ4 [off2] {sym2} ptr idx) mem) && canMergeSym(sym1, sym2) ->
+ (MOVSSloadidx4 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVSSstore [off1] {sym1} (LEAQ4 [off2] {sym2} ptr idx) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVSSstoreidx4 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx val mem)
+
+(MOVSDload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem) && canMergeSym(sym1, sym2) ->
+ (MOVSDloadidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx mem)
+(MOVSDstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem) && canMergeSym(sym1, sym2) ->
+ (MOVSDstoreidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx val mem)
+
+(ADDQconst [0] x) -> x
+
+// lower Zero instructions with word sizes
+(Zero [0] _ mem) -> mem
+(Zero [1] destptr mem) -> (MOVBstore destptr (MOVBconst [0]) mem)
+(Zero [2] destptr mem) -> (MOVWstore destptr (MOVWconst [0]) mem)
+(Zero [4] destptr mem) -> (MOVLstore destptr (MOVLconst [0]) mem)
+(Zero [8] destptr mem) -> (MOVQstore destptr (MOVQconst [0]) mem)
+
+(Zero [3] destptr mem) ->
+ (MOVBstore (ADDQconst [2] destptr) (MOVBconst [0])
+ (MOVWstore destptr (MOVWconst [0]) mem))
+(Zero [5] destptr mem) ->
+ (MOVBstore (ADDQconst [4] destptr) (MOVBconst [0])
+ (MOVLstore destptr (MOVLconst [0]) mem))
+(Zero [6] destptr mem) ->
+ (MOVWstore (ADDQconst [4] destptr) (MOVWconst [0])
+ (MOVLstore destptr (MOVLconst [0]) mem))
+(Zero [7] destptr mem) ->
+ (MOVLstore (ADDQconst [3] destptr) (MOVLconst [0])
+ (MOVLstore destptr (MOVLconst [0]) mem))
+
+// Strip off any fractional word zeroing.
+(Zero [size] destptr mem) && size%8 != 0 && size > 8 ->
+ (Zero [size-size%8] (ADDQconst destptr [size%8])
+ (MOVQstore destptr (MOVQconst [0]) mem))
+
+// Zero small numbers of words directly.
+(Zero [16] destptr mem) ->
+ (MOVQstore (ADDQconst [8] destptr) (MOVQconst [0])
+ (MOVQstore destptr (MOVQconst [0]) mem))
+(Zero [24] destptr mem) ->
+ (MOVQstore (ADDQconst [16] destptr) (MOVQconst [0])
+ (MOVQstore (ADDQconst [8] destptr) (MOVQconst [0])
+ (MOVQstore destptr (MOVQconst [0]) mem)))
+(Zero [32] destptr mem) ->
+ (MOVQstore (ADDQconst [24] destptr) (MOVQconst [0])
+ (MOVQstore (ADDQconst [16] destptr) (MOVQconst [0])
+ (MOVQstore (ADDQconst [8] destptr) (MOVQconst [0])
+ (MOVQstore destptr (MOVQconst [0]) mem))))
+
+// Medium zeroing uses a duff device.
++(Zero [size] destptr mem) && size <= 1024 && size%8 == 0 && size%16 != 0 ->
++ (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
++(Zero [size] destptr mem) && size <= 1024 && size%16 == 0 ->
++ (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem)
+
+// Large zeroing uses REP STOSQ.
+(Zero [size] destptr mem) && size > 1024 && size%8 == 0 ->
+ (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem)
+
+// Absorb InvertFlags into branches.
+(LT (InvertFlags cmp) yes no) -> (GT cmp yes no)
+(GT (InvertFlags cmp) yes no) -> (LT cmp yes no)
+(LE (InvertFlags cmp) yes no) -> (GE cmp yes no)
+(GE (InvertFlags cmp) yes no) -> (LE cmp yes no)
+(ULT (InvertFlags cmp) yes no) -> (UGT cmp yes no)
+(UGT (InvertFlags cmp) yes no) -> (ULT cmp yes no)
+(ULE (InvertFlags cmp) yes no) -> (UGE cmp yes no)
+(UGE (InvertFlags cmp) yes no) -> (ULE cmp yes no)
+(EQ (InvertFlags cmp) yes no) -> (EQ cmp yes no)
+(NE (InvertFlags cmp) yes no) -> (NE cmp yes no)
+
+// get rid of overflow code for constant shifts
+(SBBQcarrymask (CMPQconst [c] (MOVQconst [d]))) && inBounds64(d, c) -> (MOVQconst [-1])
+(SBBQcarrymask (CMPQconst [c] (MOVQconst [d]))) && !inBounds64(d, c) -> (MOVQconst [0])
+(SBBQcarrymask (CMPLconst [c] (MOVLconst [d]))) && inBounds32(d, c) -> (MOVQconst [-1])
+(SBBQcarrymask (CMPLconst [c] (MOVLconst [d]))) && !inBounds32(d, c) -> (MOVQconst [0])
+(SBBQcarrymask (CMPWconst [c] (MOVWconst [d]))) && inBounds16(d, c) -> (MOVQconst [-1])
+(SBBQcarrymask (CMPWconst [c] (MOVWconst [d]))) && !inBounds16(d, c) -> (MOVQconst [0])
+(SBBQcarrymask (CMPBconst [c] (MOVBconst [d]))) && inBounds8(d, c) -> (MOVQconst [-1])
+(SBBQcarrymask (CMPBconst [c] (MOVBconst [d]))) && !inBounds8(d, c) -> (MOVQconst [0])
+(SBBLcarrymask (CMPQconst [c] (MOVQconst [d]))) && inBounds64(d, c) -> (MOVLconst [-1])
+(SBBLcarrymask (CMPQconst [c] (MOVQconst [d]))) && !inBounds64(d, c) -> (MOVLconst [0])
+(SBBLcarrymask (CMPLconst [c] (MOVLconst [d]))) && inBounds32(d, c) -> (MOVLconst [-1])
+(SBBLcarrymask (CMPLconst [c] (MOVLconst [d]))) && !inBounds32(d, c) -> (MOVLconst [0])
+(SBBLcarrymask (CMPWconst [c] (MOVWconst [d]))) && inBounds16(d, c) -> (MOVLconst [-1])
+(SBBLcarrymask (CMPWconst [c] (MOVWconst [d]))) && !inBounds16(d, c) -> (MOVLconst [0])
+(SBBLcarrymask (CMPBconst [c] (MOVBconst [d]))) && inBounds8(d, c) -> (MOVLconst [-1])
+(SBBLcarrymask (CMPBconst [c] (MOVBconst [d]))) && !inBounds8(d, c) -> (MOVLconst [0])
+(ANDQconst [0] _) -> (MOVQconst [0])
+(ANDLconst [c] _) && int32(c)==0 -> (MOVLconst [0])
+(ANDWconst [c] _) && int16(c)==0 -> (MOVWconst [0])
+(ANDBconst [c] _) && int8(c)==0 -> (MOVBconst [0])
+(ANDQconst [-1] x) -> x
+(ANDLconst [c] x) && int32(c)==-1 -> x
+(ANDWconst [c] x) && int16(c)==-1 -> x
+(ANDBconst [c] x) && int8(c)==-1 -> x
+(ORQconst [0] x) -> x
+(ORLconst [c] x) && int32(c)==0 -> x
+(ORWconst [c] x) && int16(c)==0 -> x
+(ORBconst [c] x) && int8(c)==0 -> x
+(ORQconst [-1] _) -> (MOVQconst [-1])
+(ORLconst [c] _) && int32(c)==-1 -> (MOVLconst [-1])
+(ORWconst [c] _) && int16(c)==-1 -> (MOVWconst [-1])
+(ORBconst [c] _) && int8(c)==-1 -> (MOVBconst [-1])
+
+// generic constant folding
+// TODO: more of this
+(ADDQconst [c] (MOVQconst [d])) -> (MOVQconst [c+d])
+(ADDLconst [c] (MOVLconst [d])) -> (MOVLconst [c+d])
+(ADDWconst [c] (MOVWconst [d])) -> (MOVWconst [c+d])
+(ADDBconst [c] (MOVBconst [d])) -> (MOVBconst [c+d])
+(ADDQconst [c] (ADDQconst [d] x)) -> (ADDQconst [c+d] x)
+(ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [c+d] x)
+(ADDWconst [c] (ADDWconst [d] x)) -> (ADDWconst [c+d] x)
+(ADDBconst [c] (ADDBconst [d] x)) -> (ADDBconst [c+d] x)
+(SUBQconst [c] (MOVQconst [d])) -> (MOVQconst [d-c])
+(SUBLconst [c] (MOVLconst [d])) -> (MOVLconst [d-c])
+(SUBWconst [c] (MOVWconst [d])) -> (MOVWconst [d-c])
+(SUBBconst [c] (MOVBconst [d])) -> (MOVBconst [d-c])
+(SUBQconst [c] (SUBQconst [d] x)) -> (ADDQconst [-c-d] x)
+(SUBLconst [c] (SUBLconst [d] x)) -> (ADDLconst [-c-d] x)
+(SUBWconst [c] (SUBWconst [d] x)) -> (ADDWconst [-c-d] x)
+(SUBBconst [c] (SUBBconst [d] x)) -> (ADDBconst [-c-d] x)
+(SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
+(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
+(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
+(SARBconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
+(NEGQ (MOVQconst [c])) -> (MOVQconst [-c])
+(NEGL (MOVLconst [c])) -> (MOVLconst [-c])
+(NEGW (MOVWconst [c])) -> (MOVWconst [-c])
+(NEGB (MOVBconst [c])) -> (MOVBconst [-c])
+(MULQconst [c] (MOVQconst [d])) -> (MOVQconst [c*d])
+(MULLconst [c] (MOVLconst [d])) -> (MOVLconst [c*d])
+(MULWconst [c] (MOVWconst [d])) -> (MOVWconst [c*d])
+(MULBconst [c] (MOVBconst [d])) -> (MOVBconst [c*d])
+(ANDQconst [c] (MOVQconst [d])) -> (MOVQconst [c&d])
+(ANDLconst [c] (MOVLconst [d])) -> (MOVLconst [c&d])
+(ANDWconst [c] (MOVWconst [d])) -> (MOVWconst [c&d])
+(ANDBconst [c] (MOVBconst [d])) -> (MOVBconst [c&d])
+(ORQconst [c] (MOVQconst [d])) -> (MOVQconst [c|d])
+(ORLconst [c] (MOVLconst [d])) -> (MOVLconst [c|d])
+(ORWconst [c] (MOVWconst [d])) -> (MOVWconst [c|d])
+(ORBconst [c] (MOVBconst [d])) -> (MOVBconst [c|d])
+(XORQconst [c] (MOVQconst [d])) -> (MOVQconst [c^d])
+(XORLconst [c] (MOVLconst [d])) -> (MOVLconst [c^d])
+(XORWconst [c] (MOVWconst [d])) -> (MOVWconst [c^d])
+(XORBconst [c] (MOVBconst [d])) -> (MOVBconst [c^d])
+(NOTQ (MOVQconst [c])) -> (MOVQconst [^c])
+(NOTL (MOVLconst [c])) -> (MOVLconst [^c])
+(NOTW (MOVWconst [c])) -> (MOVWconst [^c])
+(NOTB (MOVBconst [c])) -> (MOVBconst [^c])
+
+// generic simplifications
+// TODO: more of this
+(ADDQ x (NEGQ y)) -> (SUBQ x y)
+(ADDL x (NEGL y)) -> (SUBL x y)
+(ADDW x (NEGW y)) -> (SUBW x y)
+(ADDB x (NEGB y)) -> (SUBB x y)
+(SUBQ x x) -> (MOVQconst [0])
+(SUBL x x) -> (MOVLconst [0])
+(SUBW x x) -> (MOVWconst [0])
+(SUBB x x) -> (MOVBconst [0])
+(ANDQ x x) -> x
+(ANDL x x) -> x
+(ANDW x x) -> x
+(ANDB x x) -> x
+(ORQ x x) -> x
+(ORL x x) -> x
+(ORW x x) -> x
+(ORB x x) -> x
+(XORQ x x) -> (MOVQconst [0])
+(XORL x x) -> (MOVLconst [0])
+(XORW x x) -> (MOVWconst [0])
+(XORB x x) -> (MOVBconst [0])
--- /dev/null
- inputs: []regMask{buildReg("DI"), buildReg("AX")},
+// 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 main
+
+import "strings"
+
+// copied from ../../amd64/reg.go
+var regNamesAMD64 = []string{
+ ".AX",
+ ".CX",
+ ".DX",
+ ".BX",
+ ".SP",
+ ".BP",
+ ".SI",
+ ".DI",
+ ".R8",
+ ".R9",
+ ".R10",
+ ".R11",
+ ".R12",
+ ".R13",
+ ".R14",
+ ".R15",
+ ".X0",
+ ".X1",
+ ".X2",
+ ".X3",
+ ".X4",
+ ".X5",
+ ".X6",
+ ".X7",
+ ".X8",
+ ".X9",
+ ".X10",
+ ".X11",
+ ".X12",
+ ".X13",
+ ".X14",
+ ".X15",
+
+ // pseudo-registers
+ ".SB",
+ ".FLAGS",
+}
+
+func init() {
+ // Make map from reg names to reg integers.
+ if len(regNamesAMD64) > 64 {
+ panic("too many registers")
+ }
+ num := map[string]int{}
+ for i, name := range regNamesAMD64 {
+ if name[0] != '.' {
+ panic("register name " + name + " does not start with '.'")
+ }
+ num[name[1:]] = i
+ }
+ buildReg := func(s string) regMask {
+ m := regMask(0)
+ for _, r := range strings.Split(s, " ") {
+ if n, ok := num[r]; ok {
+ m |= regMask(1) << uint(n)
+ continue
+ }
+ panic("register " + r + " not found")
+ }
+ return m
+ }
+
+ // Common individual register masks
+ var (
+ ax = buildReg("AX")
+ cx = buildReg("CX")
+ dx = buildReg("DX")
+ x15 = buildReg("X15")
+ gp = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15")
+ fp = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15")
+ gpsp = gp | buildReg("SP")
+ gpspsb = gpsp | buildReg("SB")
+ flags = buildReg("FLAGS")
+ callerSave = gp | fp | flags
+ )
+ // Common slices of register masks
+ var (
+ gponly = []regMask{gp}
+ fponly = []regMask{fp}
+ flagsonly = []regMask{flags}
+ )
+
+ // Common regInfo
+ var (
+ gp01 = regInfo{inputs: []regMask{}, outputs: gponly}
+ gp01flags = regInfo{inputs: []regMask{}, outputs: gponly, clobbers: flags}
+ gp11 = regInfo{inputs: []regMask{gpsp}, outputs: gponly, clobbers: flags}
+ gp11nf = regInfo{inputs: []regMask{gpsp}, outputs: gponly} // nf: no flags clobbered
+ gp11sb = regInfo{inputs: []regMask{gpspsb}, outputs: gponly}
+ gp21 = regInfo{inputs: []regMask{gpsp, gpsp}, outputs: gponly, clobbers: flags}
+ gp21sb = regInfo{inputs: []regMask{gpspsb, gpsp}, outputs: gponly}
+ gp21shift = regInfo{inputs: []regMask{gpsp, cx}, outputs: []regMask{gp &^ cx}, clobbers: flags}
+ gp11div = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{ax},
+ clobbers: dx | flags}
+ gp11hmul = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx},
+ clobbers: ax | flags}
+ gp11mod = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{dx},
+ clobbers: ax | flags}
+ gp10 = regInfo{inputs: []regMask{gp}}
+
+ gp2flags = regInfo{inputs: []regMask{gpsp, gpsp}, outputs: flagsonly}
+ gp1flags = regInfo{inputs: []regMask{gpsp}, outputs: flagsonly}
+ flagsgp = regInfo{inputs: flagsonly, outputs: gponly}
+ readflags = regInfo{inputs: flagsonly, outputs: gponly}
+ flagsgpax = regInfo{inputs: flagsonly, clobbers: ax | flags, outputs: []regMask{gp &^ ax}}
+
+ gpload = regInfo{inputs: []regMask{gpspsb, 0}, outputs: gponly}
+ gploadidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: gponly}
+
+ gpstore = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
+ gpstoreidx = regInfo{inputs: []regMask{gpspsb, gpsp, gpsp, 0}}
+
+ fp01 = regInfo{inputs: []regMask{}, outputs: fponly}
+ fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
+ fp21x15 = regInfo{inputs: []regMask{fp &^ x15, fp &^ x15},
+ clobbers: x15, outputs: []regMask{fp &^ x15}}
+ fpgp = regInfo{inputs: fponly, outputs: gponly}
+ gpfp = regInfo{inputs: gponly, outputs: fponly}
+ fp11 = regInfo{inputs: fponly, outputs: fponly}
+ fp2flags = regInfo{inputs: []regMask{fp, fp}, outputs: flagsonly}
+ // fp1flags = regInfo{inputs: fponly, outputs: flagsonly}
+
+ fpload = regInfo{inputs: []regMask{gpspsb, 0}, outputs: fponly}
+ fploadidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: fponly}
+
+ fpstore = regInfo{inputs: []regMask{gpspsb, fp, 0}}
+ fpstoreidx = regInfo{inputs: []regMask{gpspsb, gpsp, fp, 0}}
+ )
+ // TODO: most ops clobber flags
+
+ // Suffixes encode the bit width of various instructions.
+ // Q = 64 bit, L = 32 bit, W = 16 bit, B = 8 bit
+
+ // TODO: 2-address instructions. Mark ops as needing matching input/output regs.
+ var AMD64ops = []opData{
+ // fp ops
+ {name: "ADDSS", reg: fp21, asm: "ADDSS"}, // fp32 add
+ {name: "ADDSD", reg: fp21, asm: "ADDSD"}, // fp64 add
+ {name: "SUBSS", reg: fp21x15, asm: "SUBSS"}, // fp32 sub
+ {name: "SUBSD", reg: fp21x15, asm: "SUBSD"}, // fp64 sub
+ {name: "MULSS", reg: fp21, asm: "MULSS"}, // fp32 mul
+ {name: "MULSD", reg: fp21, asm: "MULSD"}, // fp64 mul
+ {name: "DIVSS", reg: fp21x15, asm: "DIVSS"}, // fp32 div
+ {name: "DIVSD", reg: fp21x15, asm: "DIVSD"}, // fp64 div
+
+ {name: "MOVSSload", reg: fpload, asm: "MOVSS"}, // fp32 load
+ {name: "MOVSDload", reg: fpload, asm: "MOVSD"}, // fp64 load
+ {name: "MOVSSconst", reg: fp01, asm: "MOVSS"}, // fp32 constant
+ {name: "MOVSDconst", reg: fp01, asm: "MOVSD"}, // fp64 constant
+ {name: "MOVSSloadidx4", reg: fploadidx, asm: "MOVSS"}, // fp32 load
+ {name: "MOVSDloadidx8", reg: fploadidx, asm: "MOVSD"}, // fp64 load
+
+ {name: "MOVSSstore", reg: fpstore, asm: "MOVSS"}, // fp32 store
+ {name: "MOVSDstore", reg: fpstore, asm: "MOVSD"}, // fp64 store
+ {name: "MOVSSstoreidx4", reg: fpstoreidx, asm: "MOVSS"}, // fp32 indexed by 4i store
+ {name: "MOVSDstoreidx8", reg: fpstoreidx, asm: "MOVSD"}, // fp64 indexed by 8i store
+
+ // binary ops
+ {name: "ADDQ", reg: gp21, asm: "ADDQ"}, // arg0 + arg1
+ {name: "ADDL", reg: gp21, asm: "ADDL"}, // arg0 + arg1
+ {name: "ADDW", reg: gp21, asm: "ADDW"}, // arg0 + arg1
+ {name: "ADDB", reg: gp21, asm: "ADDB"}, // arg0 + arg1
+ {name: "ADDQconst", reg: gp11, asm: "ADDQ", typ: "UInt64"}, // arg0 + auxint
+ {name: "ADDLconst", reg: gp11, asm: "ADDL"}, // arg0 + auxint
+ {name: "ADDWconst", reg: gp11, asm: "ADDW"}, // arg0 + auxint
+ {name: "ADDBconst", reg: gp11, asm: "ADDB"}, // arg0 + auxint
+
+ {name: "SUBQ", reg: gp21, asm: "SUBQ"}, // arg0 - arg1
+ {name: "SUBL", reg: gp21, asm: "SUBL"}, // arg0 - arg1
+ {name: "SUBW", reg: gp21, asm: "SUBW"}, // arg0 - arg1
+ {name: "SUBB", reg: gp21, asm: "SUBB"}, // arg0 - arg1
+ {name: "SUBQconst", reg: gp11, asm: "SUBQ"}, // arg0 - auxint
+ {name: "SUBLconst", reg: gp11, asm: "SUBL"}, // arg0 - auxint
+ {name: "SUBWconst", reg: gp11, asm: "SUBW"}, // arg0 - auxint
+ {name: "SUBBconst", reg: gp11, asm: "SUBB"}, // arg0 - auxint
+
+ {name: "MULQ", reg: gp21, asm: "IMULQ"}, // arg0 * arg1
+ {name: "MULL", reg: gp21, asm: "IMULL"}, // arg0 * arg1
+ {name: "MULW", reg: gp21, asm: "IMULW"}, // arg0 * arg1
+ {name: "MULB", reg: gp21, asm: "IMULW"}, // arg0 * arg1
+ {name: "MULQconst", reg: gp11, asm: "IMULQ"}, // arg0 * auxint
+ {name: "MULLconst", reg: gp11, asm: "IMULL"}, // arg0 * auxint
+ {name: "MULWconst", reg: gp11, asm: "IMULW"}, // arg0 * auxint
+ {name: "MULBconst", reg: gp11, asm: "IMULW"}, // arg0 * auxint
+
+ {name: "HMULL", reg: gp11hmul, asm: "IMULL"}, // (arg0 * arg1) >> width
+ {name: "HMULW", reg: gp11hmul, asm: "IMULW"}, // (arg0 * arg1) >> width
+ {name: "HMULB", reg: gp11hmul, asm: "IMULB"}, // (arg0 * arg1) >> width
+ {name: "HMULLU", reg: gp11hmul, asm: "MULL"}, // (arg0 * arg1) >> width
+ {name: "HMULWU", reg: gp11hmul, asm: "MULW"}, // (arg0 * arg1) >> width
+ {name: "HMULBU", reg: gp11hmul, asm: "MULB"}, // (arg0 * arg1) >> width
+
+ {name: "DIVQ", reg: gp11div, asm: "IDIVQ"}, // arg0 / arg1
+ {name: "DIVL", reg: gp11div, asm: "IDIVL"}, // arg0 / arg1
+ {name: "DIVW", reg: gp11div, asm: "IDIVW"}, // arg0 / arg1
+ {name: "DIVQU", reg: gp11div, asm: "DIVQ"}, // arg0 / arg1
+ {name: "DIVLU", reg: gp11div, asm: "DIVL"}, // arg0 / arg1
+ {name: "DIVWU", reg: gp11div, asm: "DIVW"}, // arg0 / arg1
+
+ {name: "MODQ", reg: gp11mod, asm: "IDIVQ"}, // arg0 % arg1
+ {name: "MODL", reg: gp11mod, asm: "IDIVL"}, // arg0 % arg1
+ {name: "MODW", reg: gp11mod, asm: "IDIVW"}, // arg0 % arg1
+ {name: "MODQU", reg: gp11mod, asm: "DIVQ"}, // arg0 % arg1
+ {name: "MODLU", reg: gp11mod, asm: "DIVL"}, // arg0 % arg1
+ {name: "MODWU", reg: gp11mod, asm: "DIVW"}, // arg0 % arg1
+
+ {name: "ANDQ", reg: gp21, asm: "ANDQ"}, // arg0 & arg1
+ {name: "ANDL", reg: gp21, asm: "ANDL"}, // arg0 & arg1
+ {name: "ANDW", reg: gp21, asm: "ANDW"}, // arg0 & arg1
+ {name: "ANDB", reg: gp21, asm: "ANDB"}, // arg0 & arg1
+ {name: "ANDQconst", reg: gp11, asm: "ANDQ"}, // arg0 & auxint
+ {name: "ANDLconst", reg: gp11, asm: "ANDL"}, // arg0 & auxint
+ {name: "ANDWconst", reg: gp11, asm: "ANDW"}, // arg0 & auxint
+ {name: "ANDBconst", reg: gp11, asm: "ANDB"}, // arg0 & auxint
+
+ {name: "ORQ", reg: gp21, asm: "ORQ"}, // arg0 | arg1
+ {name: "ORL", reg: gp21, asm: "ORL"}, // arg0 | arg1
+ {name: "ORW", reg: gp21, asm: "ORW"}, // arg0 | arg1
+ {name: "ORB", reg: gp21, asm: "ORB"}, // arg0 | arg1
+ {name: "ORQconst", reg: gp11, asm: "ORQ"}, // arg0 | auxint
+ {name: "ORLconst", reg: gp11, asm: "ORL"}, // arg0 | auxint
+ {name: "ORWconst", reg: gp11, asm: "ORW"}, // arg0 | auxint
+ {name: "ORBconst", reg: gp11, asm: "ORB"}, // arg0 | auxint
+
+ {name: "XORQ", reg: gp21, asm: "XORQ"}, // arg0 ^ arg1
+ {name: "XORL", reg: gp21, asm: "XORL"}, // arg0 ^ arg1
+ {name: "XORW", reg: gp21, asm: "XORW"}, // arg0 ^ arg1
+ {name: "XORB", reg: gp21, asm: "XORB"}, // arg0 ^ arg1
+ {name: "XORQconst", reg: gp11, asm: "XORQ"}, // arg0 ^ auxint
+ {name: "XORLconst", reg: gp11, asm: "XORL"}, // arg0 ^ auxint
+ {name: "XORWconst", reg: gp11, asm: "XORW"}, // arg0 ^ auxint
+ {name: "XORBconst", reg: gp11, asm: "XORB"}, // arg0 ^ auxint
+
+ {name: "CMPQ", reg: gp2flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to arg1
+ {name: "CMPL", reg: gp2flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to arg1
+ {name: "CMPW", reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
+ {name: "CMPB", reg: gp2flags, asm: "CMPB", typ: "Flags"}, // arg0 compare to arg1
+ {name: "CMPQconst", reg: gp1flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to auxint
+ {name: "CMPLconst", reg: gp1flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to auxint
+ {name: "CMPWconst", reg: gp1flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to auxint
+ {name: "CMPBconst", reg: gp1flags, asm: "CMPB", typ: "Flags"}, // arg0 compare to auxint
+
+ {name: "UCOMISS", reg: fp2flags, asm: "UCOMISS", typ: "Flags"}, // arg0 compare to arg1, f32
+ {name: "UCOMISD", reg: fp2flags, asm: "UCOMISD", typ: "Flags"}, // arg0 compare to arg1, f64
+
+ {name: "TESTQ", reg: gp2flags, asm: "TESTQ", typ: "Flags"}, // (arg0 & arg1) compare to 0
+ {name: "TESTL", reg: gp2flags, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
+ {name: "TESTW", reg: gp2flags, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
+ {name: "TESTB", reg: gp2flags, asm: "TESTB", typ: "Flags"}, // (arg0 & arg1) compare to 0
+ {name: "TESTQconst", reg: gp1flags, asm: "TESTQ", typ: "Flags"}, // (arg0 & auxint) compare to 0
+ {name: "TESTLconst", reg: gp1flags, asm: "TESTL", typ: "Flags"}, // (arg0 & auxint) compare to 0
+ {name: "TESTWconst", reg: gp1flags, asm: "TESTW", typ: "Flags"}, // (arg0 & auxint) compare to 0
+ {name: "TESTBconst", reg: gp1flags, asm: "TESTB", typ: "Flags"}, // (arg0 & auxint) compare to 0
+
+ {name: "SHLQ", reg: gp21shift, asm: "SHLQ"}, // arg0 << arg1, shift amount is mod 64
+ {name: "SHLL", reg: gp21shift, asm: "SHLL"}, // arg0 << arg1, shift amount is mod 32
+ {name: "SHLW", reg: gp21shift, asm: "SHLW"}, // arg0 << arg1, shift amount is mod 32
+ {name: "SHLB", reg: gp21shift, asm: "SHLB"}, // arg0 << arg1, shift amount is mod 32
+ {name: "SHLQconst", reg: gp11, asm: "SHLQ"}, // arg0 << auxint, shift amount 0-63
+ {name: "SHLLconst", reg: gp11, asm: "SHLL"}, // arg0 << auxint, shift amount 0-31
+ {name: "SHLWconst", reg: gp11, asm: "SHLW"}, // arg0 << auxint, shift amount 0-31
+ {name: "SHLBconst", reg: gp11, asm: "SHLB"}, // arg0 << auxint, shift amount 0-31
+ // Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
+
+ {name: "SHRQ", reg: gp21shift, asm: "SHRQ"}, // unsigned arg0 >> arg1, shift amount is mod 64
+ {name: "SHRL", reg: gp21shift, asm: "SHRL"}, // unsigned arg0 >> arg1, shift amount is mod 32
+ {name: "SHRW", reg: gp21shift, asm: "SHRW"}, // unsigned arg0 >> arg1, shift amount is mod 32
+ {name: "SHRB", reg: gp21shift, asm: "SHRB"}, // unsigned arg0 >> arg1, shift amount is mod 32
+ {name: "SHRQconst", reg: gp11, asm: "SHRQ"}, // unsigned arg0 >> auxint, shift amount 0-63
+ {name: "SHRLconst", reg: gp11, asm: "SHRL"}, // unsigned arg0 >> auxint, shift amount 0-31
+ {name: "SHRWconst", reg: gp11, asm: "SHRW"}, // unsigned arg0 >> auxint, shift amount 0-31
+ {name: "SHRBconst", reg: gp11, asm: "SHRB"}, // unsigned arg0 >> auxint, shift amount 0-31
+
+ {name: "SARQ", reg: gp21shift, asm: "SARQ"}, // signed arg0 >> arg1, shift amount is mod 64
+ {name: "SARL", reg: gp21shift, asm: "SARL"}, // signed arg0 >> arg1, shift amount is mod 32
+ {name: "SARW", reg: gp21shift, asm: "SARW"}, // signed arg0 >> arg1, shift amount is mod 32
+ {name: "SARB", reg: gp21shift, asm: "SARB"}, // signed arg0 >> arg1, shift amount is mod 32
+ {name: "SARQconst", reg: gp11, asm: "SARQ"}, // signed arg0 >> auxint, shift amount 0-63
+ {name: "SARLconst", reg: gp11, asm: "SARL"}, // signed arg0 >> auxint, shift amount 0-31
+ {name: "SARWconst", reg: gp11, asm: "SARW"}, // signed arg0 >> auxint, shift amount 0-31
+ {name: "SARBconst", reg: gp11, asm: "SARB"}, // signed arg0 >> auxint, shift amount 0-31
+
+ {name: "ROLQconst", reg: gp11, asm: "ROLQ"}, // arg0 rotate left auxint, rotate amount 0-63
+ {name: "ROLLconst", reg: gp11, asm: "ROLL"}, // arg0 rotate left auxint, rotate amount 0-31
+ {name: "ROLWconst", reg: gp11, asm: "ROLW"}, // arg0 rotate left auxint, rotate amount 0-15
+ {name: "ROLBconst", reg: gp11, asm: "ROLB"}, // arg0 rotate left auxint, rotate amount 0-7
+
+ // unary ops
+ {name: "NEGQ", reg: gp11, asm: "NEGQ"}, // -arg0
+ {name: "NEGL", reg: gp11, asm: "NEGL"}, // -arg0
+ {name: "NEGW", reg: gp11, asm: "NEGW"}, // -arg0
+ {name: "NEGB", reg: gp11, asm: "NEGB"}, // -arg0
+
+ {name: "NOTQ", reg: gp11, asm: "NOTQ"}, // ^arg0
+ {name: "NOTL", reg: gp11, asm: "NOTL"}, // ^arg0
+ {name: "NOTW", reg: gp11, asm: "NOTW"}, // ^arg0
+ {name: "NOTB", reg: gp11, asm: "NOTB"}, // ^arg0
+
+ {name: "SQRTSD", reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
+
+ {name: "SBBQcarrymask", reg: flagsgp, asm: "SBBQ"}, // (int64)(-1) if carry is set, 0 if carry is clear.
+ {name: "SBBLcarrymask", reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
+ // Note: SBBW and SBBB are subsumed by SBBL
+
+ {name: "SETEQ", reg: readflags, asm: "SETEQ"}, // extract == condition from arg0
+ {name: "SETNE", reg: readflags, asm: "SETNE"}, // extract != condition from arg0
+ {name: "SETL", reg: readflags, asm: "SETLT"}, // extract signed < condition from arg0
+ {name: "SETLE", reg: readflags, asm: "SETLE"}, // extract signed <= condition from arg0
+ {name: "SETG", reg: readflags, asm: "SETGT"}, // extract signed > condition from arg0
+ {name: "SETGE", reg: readflags, asm: "SETGE"}, // extract signed >= condition from arg0
+ {name: "SETB", reg: readflags, asm: "SETCS"}, // extract unsigned < condition from arg0
+ {name: "SETBE", reg: readflags, asm: "SETLS"}, // extract unsigned <= condition from arg0
+ {name: "SETA", reg: readflags, asm: "SETHI"}, // extract unsigned > condition from arg0
+ {name: "SETAE", reg: readflags, asm: "SETCC"}, // extract unsigned >= condition from arg0
+ // Need different opcodes for floating point conditions because
+ // any comparison involving a NaN is always FALSE and thus
+ // the patterns for inverting conditions cannot be used.
+ {name: "SETEQF", reg: flagsgpax, asm: "SETEQ"}, // extract == condition from arg0
+ {name: "SETNEF", reg: flagsgpax, asm: "SETNE"}, // extract != condition from arg0
+ {name: "SETORD", reg: flagsgp, asm: "SETPC"}, // extract "ordered" (No Nan present) condition from arg0
+ {name: "SETNAN", reg: flagsgp, asm: "SETPS"}, // extract "unordered" (Nan present) condition from arg0
+
+ {name: "SETGF", reg: flagsgp, asm: "SETHI"}, // extract floating > condition from arg0
+ {name: "SETGEF", reg: flagsgp, asm: "SETCC"}, // extract floating >= condition from arg0
+
+ {name: "MOVBQSX", reg: gp11nf, asm: "MOVBQSX"}, // sign extend arg0 from int8 to int64
+ {name: "MOVBQZX", reg: gp11nf, asm: "MOVBQZX"}, // zero extend arg0 from int8 to int64
+ {name: "MOVWQSX", reg: gp11nf, asm: "MOVWQSX"}, // sign extend arg0 from int16 to int64
+ {name: "MOVWQZX", reg: gp11nf, asm: "MOVWQZX"}, // zero extend arg0 from int16 to int64
+ {name: "MOVLQSX", reg: gp11nf, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64
+ {name: "MOVLQZX", reg: gp11nf, asm: "MOVLQZX"}, // zero extend arg0 from int32 to int64
+
+ // clobbers flags as liblink will rewrite these to XOR reg, reg if the constant is zero
+ // TODO: revisit when issue 12405 is fixed
+ {name: "MOVBconst", reg: gp01flags, asm: "MOVB", typ: "UInt8"}, // 8 low bits of auxint
+ {name: "MOVWconst", reg: gp01flags, asm: "MOVW", typ: "UInt16"}, // 16 low bits of auxint
+ {name: "MOVLconst", reg: gp01flags, asm: "MOVL", typ: "UInt32"}, // 32 low bits of auxint
+ {name: "MOVQconst", reg: gp01flags, asm: "MOVQ", typ: "UInt64"}, // auxint
+
+ {name: "CVTTSD2SL", reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
+ {name: "CVTTSD2SQ", reg: fpgp, asm: "CVTTSD2SQ"}, // convert float64 to int64
+ {name: "CVTTSS2SL", reg: fpgp, asm: "CVTTSS2SL"}, // convert float32 to int32
+ {name: "CVTTSS2SQ", reg: fpgp, asm: "CVTTSS2SQ"}, // convert float32 to int64
+ {name: "CVTSL2SS", reg: gpfp, asm: "CVTSL2SS"}, // convert int32 to float32
+ {name: "CVTSL2SD", reg: gpfp, asm: "CVTSL2SD"}, // convert int32 to float64
+ {name: "CVTSQ2SS", reg: gpfp, asm: "CVTSQ2SS"}, // convert int64 to float32
+ {name: "CVTSQ2SD", reg: gpfp, asm: "CVTSQ2SD"}, // convert int64 to float64
+ {name: "CVTSD2SS", reg: fp11, asm: "CVTSD2SS"}, // convert float64 to float32
+ {name: "CVTSS2SD", reg: fp11, asm: "CVTSS2SD"}, // convert float32 to float64
+
+ {name: "PXOR", reg: fp21, asm: "PXOR"}, // exclusive or, applied to X regs for float negation.
+
+ {name: "LEAQ", reg: gp11sb}, // arg0 + auxint + offset encoded in aux
+ {name: "LEAQ1", reg: gp21sb}, // arg0 + arg1 + auxint
+ {name: "LEAQ2", reg: gp21sb}, // arg0 + 2*arg1 + auxint
+ {name: "LEAQ4", reg: gp21sb}, // arg0 + 4*arg1 + auxint
+ {name: "LEAQ8", reg: gp21sb}, // arg0 + 8*arg1 + auxint
+
+ // auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
+ {name: "MOVBload", reg: gpload, asm: "MOVB"}, // load byte from arg0+auxint+aux. arg1=mem
+ {name: "MOVBQSXload", reg: gpload, asm: "MOVBQSX"}, // ditto, extend to int64
+ {name: "MOVBQZXload", reg: gpload, asm: "MOVBQZX"}, // ditto, extend to uint64
+ {name: "MOVWload", reg: gpload, asm: "MOVW"}, // load 2 bytes from arg0+auxint+aux. arg1=mem
+ {name: "MOVLload", reg: gpload, asm: "MOVL"}, // load 4 bytes from arg0+auxint+aux. arg1=mem
+ {name: "MOVQload", reg: gpload, asm: "MOVQ"}, // load 8 bytes from arg0+auxint+aux. arg1=mem
+ {name: "MOVQloadidx8", reg: gploadidx, asm: "MOVQ"}, // load 8 bytes from arg0+8*arg1+auxint+aux. arg2=mem
+ {name: "MOVBstore", reg: gpstore, asm: "MOVB", typ: "Mem"}, // store byte in arg1 to arg0+auxint+aux. arg2=mem
+ {name: "MOVWstore", reg: gpstore, asm: "MOVW", typ: "Mem"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
+ {name: "MOVLstore", reg: gpstore, asm: "MOVL", typ: "Mem"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
+ {name: "MOVQstore", reg: gpstore, asm: "MOVQ", typ: "Mem"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
+ {name: "MOVQstoreidx8", reg: gpstoreidx, asm: "MOVQ"}, // store 8 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
+
+ // arg0 = (duff-adjusted) pointer to start of memory to zero
+ // arg1 = value to store (will always be zero)
+ // arg2 = mem
+ // auxint = offset into duffzero code to start executing
+ // returns mem
+ {
+ name: "DUFFZERO",
+ reg: regInfo{
++ inputs: []regMask{buildReg("DI"), buildReg("X0")},
+ clobbers: buildReg("DI FLAGS"),
+ },
+ },
++ {name: "MOVOconst", reg: regInfo{nil, 0, []regMask{fp}}, typ: "Float64"},
+
+ // arg0 = address of memory to zero
+ // arg1 = # of 8-byte words to zero
+ // arg2 = value to store (will always be zero)
+ // arg3 = mem
+ // returns mem
+ {
+ name: "REPSTOSQ",
+ reg: regInfo{
+ inputs: []regMask{buildReg("DI"), buildReg("CX"), buildReg("AX")},
+ clobbers: buildReg("DI CX FLAGS"),
+ },
+ },
+
+ {name: "CALLstatic", reg: regInfo{clobbers: callerSave}}, // call static function aux.(*gc.Sym). arg0=mem, auxint=argsize, returns mem
+ {name: "CALLclosure", reg: regInfo{[]regMask{gpsp, buildReg("DX"), 0}, callerSave, nil}}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+ {name: "CALLdefer", reg: regInfo{clobbers: callerSave}}, // call deferproc. arg0=mem, auxint=argsize, returns mem
+ {name: "CALLgo", reg: regInfo{clobbers: callerSave}}, // call newproc. arg0=mem, auxint=argsize, returns mem
+ {name: "CALLinter", reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+ {name: "REPMOVSB", reg: regInfo{[]regMask{buildReg("DI"), buildReg("SI"), buildReg("CX")}, buildReg("DI SI CX"), nil}}, // move arg2 bytes from arg1 to arg0. arg3=mem, returns memory
+
+ // (InvertFlags (CMPQ a b)) == (CMPQ b a)
+ // So if we want (SETL (CMPQ a b)) but we can't do that because a is a constant,
+ // then we do (SETL (InvertFlags (CMPQ b a))) instead.
+ // Rewrites will convert this to (SETG (CMPQ b a)).
+ // InvertFlags is a pseudo-op which can't appear in assembly output.
+ {name: "InvertFlags"}, // reverse direction of arg0
+
+ // Pseudo-ops
+ {name: "LoweredPanicNilCheck", reg: gp10},
+ {name: "LoweredGetG", reg: gp01},
+ // Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+ // and sorts it to the very beginning of the block to prevent other
+ // use of DX (the closure pointer)
+ {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
+ }
+
+ var AMD64blocks = []blockData{
+ {name: "EQ"},
+ {name: "NE"},
+ {name: "LT"},
+ {name: "LE"},
+ {name: "GT"},
+ {name: "GE"},
+ {name: "ULT"},
+ {name: "ULE"},
+ {name: "UGT"},
+ {name: "UGE"},
+ {name: "EQF"},
+ {name: "NEF"},
+ {name: "ORD"}, // FP, ordered comparison (parity zero)
+ {name: "NAN"}, // FP, unordered comparison (parity one)
+ }
+
+ archs = append(archs, arch{"AMD64", AMD64ops, AMD64blocks, regNamesAMD64})
+}
--- /dev/null
- {0, 128}, // .DI
- {1, 1}, // .AX
+// autogenerated: do not edit!
+// generated from gen/*Ops.go
+package ssa
+
+import "cmd/internal/obj/x86"
+
+const (
+ BlockInvalid BlockKind = iota
+
+ BlockAMD64EQ
+ BlockAMD64NE
+ BlockAMD64LT
+ BlockAMD64LE
+ BlockAMD64GT
+ BlockAMD64GE
+ BlockAMD64ULT
+ BlockAMD64ULE
+ BlockAMD64UGT
+ BlockAMD64UGE
+ BlockAMD64EQF
+ BlockAMD64NEF
+ BlockAMD64ORD
+ BlockAMD64NAN
+
+ BlockPlain
+ BlockIf
+ BlockCall
+ BlockRet
+ BlockRetJmp
+ BlockExit
+ BlockFirst
+ BlockDead
+)
+
+var blockString = [...]string{
+ BlockInvalid: "BlockInvalid",
+
+ BlockAMD64EQ: "EQ",
+ BlockAMD64NE: "NE",
+ BlockAMD64LT: "LT",
+ BlockAMD64LE: "LE",
+ BlockAMD64GT: "GT",
+ BlockAMD64GE: "GE",
+ BlockAMD64ULT: "ULT",
+ BlockAMD64ULE: "ULE",
+ BlockAMD64UGT: "UGT",
+ BlockAMD64UGE: "UGE",
+ BlockAMD64EQF: "EQF",
+ BlockAMD64NEF: "NEF",
+ BlockAMD64ORD: "ORD",
+ BlockAMD64NAN: "NAN",
+
+ BlockPlain: "Plain",
+ BlockIf: "If",
+ BlockCall: "Call",
+ BlockRet: "Ret",
+ BlockRetJmp: "RetJmp",
+ BlockExit: "Exit",
+ BlockFirst: "First",
+ BlockDead: "Dead",
+}
+
+func (k BlockKind) String() string { return blockString[k] }
+
+const (
+ OpInvalid Op = iota
+
+ OpAMD64ADDSS
+ OpAMD64ADDSD
+ OpAMD64SUBSS
+ OpAMD64SUBSD
+ OpAMD64MULSS
+ OpAMD64MULSD
+ OpAMD64DIVSS
+ OpAMD64DIVSD
+ OpAMD64MOVSSload
+ OpAMD64MOVSDload
+ OpAMD64MOVSSconst
+ OpAMD64MOVSDconst
+ OpAMD64MOVSSloadidx4
+ OpAMD64MOVSDloadidx8
+ OpAMD64MOVSSstore
+ OpAMD64MOVSDstore
+ OpAMD64MOVSSstoreidx4
+ OpAMD64MOVSDstoreidx8
+ OpAMD64ADDQ
+ OpAMD64ADDL
+ OpAMD64ADDW
+ OpAMD64ADDB
+ OpAMD64ADDQconst
+ OpAMD64ADDLconst
+ OpAMD64ADDWconst
+ OpAMD64ADDBconst
+ OpAMD64SUBQ
+ OpAMD64SUBL
+ OpAMD64SUBW
+ OpAMD64SUBB
+ OpAMD64SUBQconst
+ OpAMD64SUBLconst
+ OpAMD64SUBWconst
+ OpAMD64SUBBconst
+ OpAMD64MULQ
+ OpAMD64MULL
+ OpAMD64MULW
+ OpAMD64MULB
+ OpAMD64MULQconst
+ OpAMD64MULLconst
+ OpAMD64MULWconst
+ OpAMD64MULBconst
+ OpAMD64HMULL
+ OpAMD64HMULW
+ OpAMD64HMULB
+ OpAMD64HMULLU
+ OpAMD64HMULWU
+ OpAMD64HMULBU
+ OpAMD64DIVQ
+ OpAMD64DIVL
+ OpAMD64DIVW
+ OpAMD64DIVQU
+ OpAMD64DIVLU
+ OpAMD64DIVWU
+ OpAMD64MODQ
+ OpAMD64MODL
+ OpAMD64MODW
+ OpAMD64MODQU
+ OpAMD64MODLU
+ OpAMD64MODWU
+ OpAMD64ANDQ
+ OpAMD64ANDL
+ OpAMD64ANDW
+ OpAMD64ANDB
+ OpAMD64ANDQconst
+ OpAMD64ANDLconst
+ OpAMD64ANDWconst
+ OpAMD64ANDBconst
+ OpAMD64ORQ
+ OpAMD64ORL
+ OpAMD64ORW
+ OpAMD64ORB
+ OpAMD64ORQconst
+ OpAMD64ORLconst
+ OpAMD64ORWconst
+ OpAMD64ORBconst
+ OpAMD64XORQ
+ OpAMD64XORL
+ OpAMD64XORW
+ OpAMD64XORB
+ OpAMD64XORQconst
+ OpAMD64XORLconst
+ OpAMD64XORWconst
+ OpAMD64XORBconst
+ OpAMD64CMPQ
+ OpAMD64CMPL
+ OpAMD64CMPW
+ OpAMD64CMPB
+ OpAMD64CMPQconst
+ OpAMD64CMPLconst
+ OpAMD64CMPWconst
+ OpAMD64CMPBconst
+ OpAMD64UCOMISS
+ OpAMD64UCOMISD
+ OpAMD64TESTQ
+ OpAMD64TESTL
+ OpAMD64TESTW
+ OpAMD64TESTB
+ OpAMD64TESTQconst
+ OpAMD64TESTLconst
+ OpAMD64TESTWconst
+ OpAMD64TESTBconst
+ OpAMD64SHLQ
+ OpAMD64SHLL
+ OpAMD64SHLW
+ OpAMD64SHLB
+ OpAMD64SHLQconst
+ OpAMD64SHLLconst
+ OpAMD64SHLWconst
+ OpAMD64SHLBconst
+ OpAMD64SHRQ
+ OpAMD64SHRL
+ OpAMD64SHRW
+ OpAMD64SHRB
+ OpAMD64SHRQconst
+ OpAMD64SHRLconst
+ OpAMD64SHRWconst
+ OpAMD64SHRBconst
+ OpAMD64SARQ
+ OpAMD64SARL
+ OpAMD64SARW
+ OpAMD64SARB
+ OpAMD64SARQconst
+ OpAMD64SARLconst
+ OpAMD64SARWconst
+ OpAMD64SARBconst
+ OpAMD64ROLQconst
+ OpAMD64ROLLconst
+ OpAMD64ROLWconst
+ OpAMD64ROLBconst
+ OpAMD64NEGQ
+ OpAMD64NEGL
+ OpAMD64NEGW
+ OpAMD64NEGB
+ OpAMD64NOTQ
+ OpAMD64NOTL
+ OpAMD64NOTW
+ OpAMD64NOTB
+ OpAMD64SQRTSD
+ OpAMD64SBBQcarrymask
+ OpAMD64SBBLcarrymask
+ OpAMD64SETEQ
+ OpAMD64SETNE
+ OpAMD64SETL
+ OpAMD64SETLE
+ OpAMD64SETG
+ OpAMD64SETGE
+ OpAMD64SETB
+ OpAMD64SETBE
+ OpAMD64SETA
+ OpAMD64SETAE
+ OpAMD64SETEQF
+ OpAMD64SETNEF
+ OpAMD64SETORD
+ OpAMD64SETNAN
+ OpAMD64SETGF
+ OpAMD64SETGEF
+ OpAMD64MOVBQSX
+ OpAMD64MOVBQZX
+ OpAMD64MOVWQSX
+ OpAMD64MOVWQZX
+ OpAMD64MOVLQSX
+ OpAMD64MOVLQZX
+ OpAMD64MOVBconst
+ OpAMD64MOVWconst
+ OpAMD64MOVLconst
+ OpAMD64MOVQconst
+ OpAMD64CVTTSD2SL
+ OpAMD64CVTTSD2SQ
+ OpAMD64CVTTSS2SL
+ OpAMD64CVTTSS2SQ
+ OpAMD64CVTSL2SS
+ OpAMD64CVTSL2SD
+ OpAMD64CVTSQ2SS
+ OpAMD64CVTSQ2SD
+ OpAMD64CVTSD2SS
+ OpAMD64CVTSS2SD
+ OpAMD64PXOR
+ OpAMD64LEAQ
+ OpAMD64LEAQ1
+ OpAMD64LEAQ2
+ OpAMD64LEAQ4
+ OpAMD64LEAQ8
+ OpAMD64MOVBload
+ OpAMD64MOVBQSXload
+ OpAMD64MOVBQZXload
+ OpAMD64MOVWload
+ OpAMD64MOVLload
+ OpAMD64MOVQload
+ OpAMD64MOVQloadidx8
+ OpAMD64MOVBstore
+ OpAMD64MOVWstore
+ OpAMD64MOVLstore
+ OpAMD64MOVQstore
+ OpAMD64MOVQstoreidx8
+ OpAMD64DUFFZERO
++ OpAMD64MOVOconst
+ OpAMD64REPSTOSQ
+ OpAMD64CALLstatic
+ OpAMD64CALLclosure
+ OpAMD64CALLdefer
+ OpAMD64CALLgo
+ OpAMD64CALLinter
+ OpAMD64REPMOVSB
+ OpAMD64InvertFlags
+ OpAMD64LoweredPanicNilCheck
+ OpAMD64LoweredGetG
+ OpAMD64LoweredGetClosurePtr
+
+ OpAdd8
+ OpAdd16
+ OpAdd32
+ OpAdd64
+ OpAddPtr
+ OpAdd32F
+ OpAdd64F
+ OpSub8
+ OpSub16
+ OpSub32
+ OpSub64
+ OpSubPtr
+ OpSub32F
+ OpSub64F
+ OpMul8
+ OpMul16
+ OpMul32
+ OpMul64
+ OpMulPtr
+ OpMul32F
+ OpMul64F
+ OpDiv32F
+ OpDiv64F
+ OpHmul8
+ OpHmul8u
+ OpHmul16
+ OpHmul16u
+ OpHmul32
+ OpHmul32u
+ OpDiv8
+ OpDiv8u
+ OpDiv16
+ OpDiv16u
+ OpDiv32
+ OpDiv32u
+ OpDiv64
+ OpDiv64u
+ OpMod8
+ OpMod8u
+ OpMod16
+ OpMod16u
+ OpMod32
+ OpMod32u
+ OpMod64
+ OpMod64u
+ OpAnd8
+ OpAnd16
+ OpAnd32
+ OpAnd64
+ OpOr8
+ OpOr16
+ OpOr32
+ OpOr64
+ OpXor8
+ OpXor16
+ OpXor32
+ OpXor64
+ OpLsh8x8
+ OpLsh8x16
+ OpLsh8x32
+ OpLsh8x64
+ OpLsh16x8
+ OpLsh16x16
+ OpLsh16x32
+ OpLsh16x64
+ OpLsh32x8
+ OpLsh32x16
+ OpLsh32x32
+ OpLsh32x64
+ OpLsh64x8
+ OpLsh64x16
+ OpLsh64x32
+ OpLsh64x64
+ OpRsh8x8
+ OpRsh8x16
+ OpRsh8x32
+ OpRsh8x64
+ OpRsh16x8
+ OpRsh16x16
+ OpRsh16x32
+ OpRsh16x64
+ OpRsh32x8
+ OpRsh32x16
+ OpRsh32x32
+ OpRsh32x64
+ OpRsh64x8
+ OpRsh64x16
+ OpRsh64x32
+ OpRsh64x64
+ OpRsh8Ux8
+ OpRsh8Ux16
+ OpRsh8Ux32
+ OpRsh8Ux64
+ OpRsh16Ux8
+ OpRsh16Ux16
+ OpRsh16Ux32
+ OpRsh16Ux64
+ OpRsh32Ux8
+ OpRsh32Ux16
+ OpRsh32Ux32
+ OpRsh32Ux64
+ OpRsh64Ux8
+ OpRsh64Ux16
+ OpRsh64Ux32
+ OpRsh64Ux64
+ OpLrot8
+ OpLrot16
+ OpLrot32
+ OpLrot64
+ OpEq8
+ OpEq16
+ OpEq32
+ OpEq64
+ OpEqPtr
+ OpEqInter
+ OpEqSlice
+ OpEq32F
+ OpEq64F
+ OpNeq8
+ OpNeq16
+ OpNeq32
+ OpNeq64
+ OpNeqPtr
+ OpNeqInter
+ OpNeqSlice
+ OpNeq32F
+ OpNeq64F
+ OpLess8
+ OpLess8U
+ OpLess16
+ OpLess16U
+ OpLess32
+ OpLess32U
+ OpLess64
+ OpLess64U
+ OpLess32F
+ OpLess64F
+ OpLeq8
+ OpLeq8U
+ OpLeq16
+ OpLeq16U
+ OpLeq32
+ OpLeq32U
+ OpLeq64
+ OpLeq64U
+ OpLeq32F
+ OpLeq64F
+ OpGreater8
+ OpGreater8U
+ OpGreater16
+ OpGreater16U
+ OpGreater32
+ OpGreater32U
+ OpGreater64
+ OpGreater64U
+ OpGreater32F
+ OpGreater64F
+ OpGeq8
+ OpGeq8U
+ OpGeq16
+ OpGeq16U
+ OpGeq32
+ OpGeq32U
+ OpGeq64
+ OpGeq64U
+ OpGeq32F
+ OpGeq64F
+ OpNot
+ OpNeg8
+ OpNeg16
+ OpNeg32
+ OpNeg64
+ OpNeg32F
+ OpNeg64F
+ OpCom8
+ OpCom16
+ OpCom32
+ OpCom64
+ OpSqrt
+ OpPhi
+ OpCopy
+ OpConstBool
+ OpConstString
+ OpConstNil
+ OpConst8
+ OpConst16
+ OpConst32
+ OpConst64
+ OpConst32F
+ OpConst64F
+ OpConstPtr
+ OpConstInterface
+ OpConstSlice
+ OpArg
+ OpAddr
+ OpSP
+ OpSB
+ OpFunc
+ OpLoad
+ OpStore
+ OpMove
+ OpZero
+ OpClosureCall
+ OpStaticCall
+ OpDeferCall
+ OpGoCall
+ OpInterCall
+ OpSignExt8to16
+ OpSignExt8to32
+ OpSignExt8to64
+ OpSignExt16to32
+ OpSignExt16to64
+ OpSignExt32to64
+ OpZeroExt8to16
+ OpZeroExt8to32
+ OpZeroExt8to64
+ OpZeroExt16to32
+ OpZeroExt16to64
+ OpZeroExt32to64
+ OpTrunc16to8
+ OpTrunc32to8
+ OpTrunc32to16
+ OpTrunc64to8
+ OpTrunc64to16
+ OpTrunc64to32
+ OpCvt32to32F
+ OpCvt32to64F
+ OpCvt64to32F
+ OpCvt64to64F
+ OpCvt32Fto32
+ OpCvt32Fto64
+ OpCvt64Fto32
+ OpCvt64Fto64
+ OpCvt32Fto64F
+ OpCvt64Fto32F
+ OpIsNonNil
+ OpIsInBounds
+ OpIsSliceInBounds
+ OpPanicNilCheck
+ OpGetG
+ OpGetClosurePtr
+ OpArrayIndex
+ OpPtrIndex
+ OpOffPtr
+ OpStructSelect
+ OpSliceMake
+ OpSlicePtr
+ OpSliceLen
+ OpSliceCap
+ OpComplexMake
+ OpComplexReal
+ OpComplexImag
+ OpStringMake
+ OpStringPtr
+ OpStringLen
+ OpIMake
+ OpITab
+ OpIData
+ OpStoreReg
+ OpLoadReg
+ OpFwdRef
+ OpVarDef
+ OpVarKill
+)
+
+var opcodeTable = [...]opInfo{
+ {name: "OpInvalid"},
+
+ {
+ name: "ADDSS",
+ asm: x86.AADDSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "ADDSD",
+ asm: x86.AADDSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "SUBSS",
+ asm: x86.ASUBSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ {1, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ clobbers: 2147483648, // .X15
+ outputs: []regMask{
+ 2147418112, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ },
+ },
+ {
+ name: "SUBSD",
+ asm: x86.ASUBSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ {1, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ clobbers: 2147483648, // .X15
+ outputs: []regMask{
+ 2147418112, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ },
+ },
+ {
+ name: "MULSS",
+ asm: x86.AMULSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MULSD",
+ asm: x86.AMULSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "DIVSS",
+ asm: x86.ADIVSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ {1, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ clobbers: 2147483648, // .X15
+ outputs: []regMask{
+ 2147418112, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ },
+ },
+ {
+ name: "DIVSD",
+ asm: x86.ADIVSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ {1, 2147418112}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ clobbers: 2147483648, // .X15
+ outputs: []regMask{
+ 2147418112, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14
+ },
+ },
+ },
+ {
+ name: "MOVSSload",
+ asm: x86.AMOVSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MOVSDload",
+ asm: x86.AMOVSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MOVSSconst",
+ asm: x86.AMOVSS,
+ reg: regInfo{
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MOVSDconst",
+ asm: x86.AMOVSD,
+ reg: regInfo{
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MOVSSloadidx4",
+ asm: x86.AMOVSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MOVSDloadidx8",
+ asm: x86.AMOVSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "MOVSSstore",
+ asm: x86.AMOVSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVSDstore",
+ asm: x86.AMOVSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVSSstoreidx4",
+ asm: x86.AMOVSS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {2, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVSDstoreidx8",
+ asm: x86.AMOVSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {2, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "ADDQ",
+ asm: x86.AADDQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDL",
+ asm: x86.AADDL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDW",
+ asm: x86.AADDW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDB",
+ asm: x86.AADDB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDQconst",
+ asm: x86.AADDQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDLconst",
+ asm: x86.AADDL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDWconst",
+ asm: x86.AADDW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ADDBconst",
+ asm: x86.AADDB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBQ",
+ asm: x86.ASUBQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBL",
+ asm: x86.ASUBL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBW",
+ asm: x86.ASUBW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBB",
+ asm: x86.ASUBB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBQconst",
+ asm: x86.ASUBQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBLconst",
+ asm: x86.ASUBL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBWconst",
+ asm: x86.ASUBW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SUBBconst",
+ asm: x86.ASUBB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULQ",
+ asm: x86.AIMULQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULL",
+ asm: x86.AIMULL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULW",
+ asm: x86.AIMULW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULB",
+ asm: x86.AIMULW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULQconst",
+ asm: x86.AIMULQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULLconst",
+ asm: x86.AIMULL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULWconst",
+ asm: x86.AIMULW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MULBconst",
+ asm: x86.AIMULW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "HMULL",
+ asm: x86.AIMULL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "HMULW",
+ asm: x86.AIMULW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "HMULB",
+ asm: x86.AIMULB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "HMULLU",
+ asm: x86.AMULL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "HMULWU",
+ asm: x86.AMULW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "HMULBU",
+ asm: x86.AMULB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "DIVQ",
+ asm: x86.AIDIVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934596, // .DX .FLAGS
+ outputs: []regMask{
+ 1, // .AX
+ },
+ },
+ },
+ {
+ name: "DIVL",
+ asm: x86.AIDIVL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934596, // .DX .FLAGS
+ outputs: []regMask{
+ 1, // .AX
+ },
+ },
+ },
+ {
+ name: "DIVW",
+ asm: x86.AIDIVW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934596, // .DX .FLAGS
+ outputs: []regMask{
+ 1, // .AX
+ },
+ },
+ },
+ {
+ name: "DIVQU",
+ asm: x86.ADIVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934596, // .DX .FLAGS
+ outputs: []regMask{
+ 1, // .AX
+ },
+ },
+ },
+ {
+ name: "DIVLU",
+ asm: x86.ADIVL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934596, // .DX .FLAGS
+ outputs: []regMask{
+ 1, // .AX
+ },
+ },
+ },
+ {
+ name: "DIVWU",
+ asm: x86.ADIVW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934596, // .DX .FLAGS
+ outputs: []regMask{
+ 1, // .AX
+ },
+ },
+ },
+ {
+ name: "MODQ",
+ asm: x86.AIDIVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "MODL",
+ asm: x86.AIDIVL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "MODW",
+ asm: x86.AIDIVW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "MODQU",
+ asm: x86.ADIVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "MODLU",
+ asm: x86.ADIVL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "MODWU",
+ asm: x86.ADIVW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 1}, // .AX
+ {1, 65531}, // .AX .CX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+ {
+ name: "ANDQ",
+ asm: x86.AANDQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDL",
+ asm: x86.AANDL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDW",
+ asm: x86.AANDW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDB",
+ asm: x86.AANDB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDQconst",
+ asm: x86.AANDQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDLconst",
+ asm: x86.AANDL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDWconst",
+ asm: x86.AANDW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ANDBconst",
+ asm: x86.AANDB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORQ",
+ asm: x86.AORQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORL",
+ asm: x86.AORL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORW",
+ asm: x86.AORW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORB",
+ asm: x86.AORB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORQconst",
+ asm: x86.AORQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORLconst",
+ asm: x86.AORL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORWconst",
+ asm: x86.AORW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ORBconst",
+ asm: x86.AORB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORQ",
+ asm: x86.AXORQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORL",
+ asm: x86.AXORL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORW",
+ asm: x86.AXORW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORB",
+ asm: x86.AXORB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORQconst",
+ asm: x86.AXORQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORLconst",
+ asm: x86.AXORL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORWconst",
+ asm: x86.AXORW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "XORBconst",
+ asm: x86.AXORB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "CMPQ",
+ asm: x86.ACMPQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPL",
+ asm: x86.ACMPL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPW",
+ asm: x86.ACMPW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPB",
+ asm: x86.ACMPB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPQconst",
+ asm: x86.ACMPQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPLconst",
+ asm: x86.ACMPL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPWconst",
+ asm: x86.ACMPW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "CMPBconst",
+ asm: x86.ACMPB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "UCOMISS",
+ asm: x86.AUCOMISS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "UCOMISD",
+ asm: x86.AUCOMISD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTQ",
+ asm: x86.ATESTQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTL",
+ asm: x86.ATESTL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTW",
+ asm: x86.ATESTW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTB",
+ asm: x86.ATESTB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTQconst",
+ asm: x86.ATESTQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTLconst",
+ asm: x86.ATESTL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTWconst",
+ asm: x86.ATESTW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "TESTBconst",
+ asm: x86.ATESTB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 8589934592, // .FLAGS
+ },
+ },
+ },
+ {
+ name: "SHLQ",
+ asm: x86.ASHLQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLL",
+ asm: x86.ASHLL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLW",
+ asm: x86.ASHLW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLB",
+ asm: x86.ASHLB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLQconst",
+ asm: x86.ASHLQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLLconst",
+ asm: x86.ASHLL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLWconst",
+ asm: x86.ASHLW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHLBconst",
+ asm: x86.ASHLB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRQ",
+ asm: x86.ASHRQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRL",
+ asm: x86.ASHRL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRW",
+ asm: x86.ASHRW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRB",
+ asm: x86.ASHRB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRQconst",
+ asm: x86.ASHRQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRLconst",
+ asm: x86.ASHRL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRWconst",
+ asm: x86.ASHRW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SHRBconst",
+ asm: x86.ASHRB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARQ",
+ asm: x86.ASARQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARL",
+ asm: x86.ASARL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARW",
+ asm: x86.ASARW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARB",
+ asm: x86.ASARB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 2}, // .CX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65517, // .AX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARQconst",
+ asm: x86.ASARQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARLconst",
+ asm: x86.ASARL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARWconst",
+ asm: x86.ASARW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SARBconst",
+ asm: x86.ASARB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ROLQconst",
+ asm: x86.AROLQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ROLLconst",
+ asm: x86.AROLL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ROLWconst",
+ asm: x86.AROLW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "ROLBconst",
+ asm: x86.AROLB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NEGQ",
+ asm: x86.ANEGQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NEGL",
+ asm: x86.ANEGL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NEGW",
+ asm: x86.ANEGW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NEGB",
+ asm: x86.ANEGB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NOTQ",
+ asm: x86.ANOTQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NOTL",
+ asm: x86.ANOTL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NOTW",
+ asm: x86.ANOTW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "NOTB",
+ asm: x86.ANOTB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SQRTSD",
+ asm: x86.ASQRTSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "SBBQcarrymask",
+ asm: x86.ASBBQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SBBLcarrymask",
+ asm: x86.ASBBL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETEQ",
+ asm: x86.ASETEQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETNE",
+ asm: x86.ASETNE,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETL",
+ asm: x86.ASETLT,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETLE",
+ asm: x86.ASETLE,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETG",
+ asm: x86.ASETGT,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETGE",
+ asm: x86.ASETGE,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETB",
+ asm: x86.ASETCS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETBE",
+ asm: x86.ASETLS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETA",
+ asm: x86.ASETHI,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETAE",
+ asm: x86.ASETCC,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETEQF",
+ asm: x86.ASETEQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 65518, // .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETNEF",
+ asm: x86.ASETNE,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ clobbers: 8589934593, // .AX .FLAGS
+ outputs: []regMask{
+ 65518, // .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETORD",
+ asm: x86.ASETPC,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETNAN",
+ asm: x86.ASETPS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETGF",
+ asm: x86.ASETHI,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "SETGEF",
+ asm: x86.ASETCC,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 8589934592}, // .FLAGS
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBQSX",
+ asm: x86.AMOVBQSX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBQZX",
+ asm: x86.AMOVBQZX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVWQSX",
+ asm: x86.AMOVWQSX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVWQZX",
+ asm: x86.AMOVWQZX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVLQSX",
+ asm: x86.AMOVLQSX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVLQZX",
+ asm: x86.AMOVLQZX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBconst",
+ asm: x86.AMOVB,
+ reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVWconst",
+ asm: x86.AMOVW,
+ reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVLconst",
+ asm: x86.AMOVL,
+ reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVQconst",
+ asm: x86.AMOVQ,
+ reg: regInfo{
+ clobbers: 8589934592, // .FLAGS
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "CVTTSD2SL",
+ asm: x86.ACVTTSD2SL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "CVTTSD2SQ",
+ asm: x86.ACVTTSD2SQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "CVTTSS2SL",
+ asm: x86.ACVTTSS2SL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "CVTTSS2SQ",
+ asm: x86.ACVTTSS2SQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "CVTSL2SS",
+ asm: x86.ACVTSL2SS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65519}, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "CVTSL2SD",
+ asm: x86.ACVTSL2SD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65519}, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "CVTSQ2SS",
+ asm: x86.ACVTSQ2SS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65519}, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "CVTSQ2SD",
+ asm: x86.ACVTSQ2SD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65519}, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "CVTSD2SS",
+ asm: x86.ACVTSD2SS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "CVTSS2SD",
+ asm: x86.ACVTSS2SD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "PXOR",
+ asm: x86.APXOR,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ {1, 4294901760}, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ outputs: []regMask{
+ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
+ },
+ },
+ },
+ {
+ name: "LEAQ",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "LEAQ1",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "LEAQ2",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "LEAQ4",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "LEAQ8",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBload",
+ asm: x86.AMOVB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBQSXload",
+ asm: x86.AMOVBQSX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBQZXload",
+ asm: x86.AMOVBQZX,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVWload",
+ asm: x86.AMOVW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVLload",
+ asm: x86.AMOVL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVQload",
+ asm: x86.AMOVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVQloadidx8",
+ asm: x86.AMOVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "MOVBstore",
+ asm: x86.AMOVB,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVWstore",
+ asm: x86.AMOVW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVLstore",
+ asm: x86.AMOVL,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVQstore",
+ asm: x86.AMOVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "MOVQstoreidx8",
+ asm: x86.AMOVQ,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {2, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ {0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
+ },
+ },
+ },
+ {
+ name: "DUFFZERO",
+ reg: regInfo{
+ inputs: []inputInfo{
++ {0, 128}, // .DI
++ {1, 65536}, // .X0
+ },
+ clobbers: 8589934720, // .DI .FLAGS
+ },
+ },
++ {
++ name: "MOVOconst",
++ reg: regInfo{
++ outputs: []regMask{
++ 4294901760, // .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15
++ },
++ },
++ },
+ {
+ name: "REPSTOSQ",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 128}, // .DI
+ {1, 2}, // .CX
+ {2, 1}, // .AX
+ },
+ clobbers: 8589934722, // .CX .DI .FLAGS
+ },
+ },
+ {
+ name: "CALLstatic",
+ reg: regInfo{
+ clobbers: 12884901871, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15 .FLAGS
+ },
+ },
+ {
+ name: "CALLclosure",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 4}, // .DX
+ {0, 65535}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 12884901871, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15 .FLAGS
+ },
+ },
+ {
+ name: "CALLdefer",
+ reg: regInfo{
+ clobbers: 12884901871, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15 .FLAGS
+ },
+ },
+ {
+ name: "CALLgo",
+ reg: regInfo{
+ clobbers: 12884901871, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15 .FLAGS
+ },
+ },
+ {
+ name: "CALLinter",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65519}, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ clobbers: 12884901871, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .X0 .X1 .X2 .X3 .X4 .X5 .X6 .X7 .X8 .X9 .X10 .X11 .X12 .X13 .X14 .X15 .FLAGS
+ },
+ },
+ {
+ name: "REPMOVSB",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 128}, // .DI
+ {1, 64}, // .SI
+ {2, 2}, // .CX
+ },
+ clobbers: 194, // .CX .SI .DI
+ },
+ },
+ {
+ name: "InvertFlags",
+ reg: regInfo{},
+ },
+ {
+ name: "LoweredPanicNilCheck",
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 65519}, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "LoweredGetG",
+ reg: regInfo{
+ outputs: []regMask{
+ 65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
+ },
+ },
+ },
+ {
+ name: "LoweredGetClosurePtr",
+ reg: regInfo{
+ outputs: []regMask{
+ 4, // .DX
+ },
+ },
+ },
+
+ {
+ name: "Add8",
+ generic: true,
+ },
+ {
+ name: "Add16",
+ generic: true,
+ },
+ {
+ name: "Add32",
+ generic: true,
+ },
+ {
+ name: "Add64",
+ generic: true,
+ },
+ {
+ name: "AddPtr",
+ generic: true,
+ },
+ {
+ name: "Add32F",
+ generic: true,
+ },
+ {
+ name: "Add64F",
+ generic: true,
+ },
+ {
+ name: "Sub8",
+ generic: true,
+ },
+ {
+ name: "Sub16",
+ generic: true,
+ },
+ {
+ name: "Sub32",
+ generic: true,
+ },
+ {
+ name: "Sub64",
+ generic: true,
+ },
+ {
+ name: "SubPtr",
+ generic: true,
+ },
+ {
+ name: "Sub32F",
+ generic: true,
+ },
+ {
+ name: "Sub64F",
+ generic: true,
+ },
+ {
+ name: "Mul8",
+ generic: true,
+ },
+ {
+ name: "Mul16",
+ generic: true,
+ },
+ {
+ name: "Mul32",
+ generic: true,
+ },
+ {
+ name: "Mul64",
+ generic: true,
+ },
+ {
+ name: "MulPtr",
+ generic: true,
+ },
+ {
+ name: "Mul32F",
+ generic: true,
+ },
+ {
+ name: "Mul64F",
+ generic: true,
+ },
+ {
+ name: "Div32F",
+ generic: true,
+ },
+ {
+ name: "Div64F",
+ generic: true,
+ },
+ {
+ name: "Hmul8",
+ generic: true,
+ },
+ {
+ name: "Hmul8u",
+ generic: true,
+ },
+ {
+ name: "Hmul16",
+ generic: true,
+ },
+ {
+ name: "Hmul16u",
+ generic: true,
+ },
+ {
+ name: "Hmul32",
+ generic: true,
+ },
+ {
+ name: "Hmul32u",
+ generic: true,
+ },
+ {
+ name: "Div8",
+ generic: true,
+ },
+ {
+ name: "Div8u",
+ generic: true,
+ },
+ {
+ name: "Div16",
+ generic: true,
+ },
+ {
+ name: "Div16u",
+ generic: true,
+ },
+ {
+ name: "Div32",
+ generic: true,
+ },
+ {
+ name: "Div32u",
+ generic: true,
+ },
+ {
+ name: "Div64",
+ generic: true,
+ },
+ {
+ name: "Div64u",
+ generic: true,
+ },
+ {
+ name: "Mod8",
+ generic: true,
+ },
+ {
+ name: "Mod8u",
+ generic: true,
+ },
+ {
+ name: "Mod16",
+ generic: true,
+ },
+ {
+ name: "Mod16u",
+ generic: true,
+ },
+ {
+ name: "Mod32",
+ generic: true,
+ },
+ {
+ name: "Mod32u",
+ generic: true,
+ },
+ {
+ name: "Mod64",
+ generic: true,
+ },
+ {
+ name: "Mod64u",
+ generic: true,
+ },
+ {
+ name: "And8",
+ generic: true,
+ },
+ {
+ name: "And16",
+ generic: true,
+ },
+ {
+ name: "And32",
+ generic: true,
+ },
+ {
+ name: "And64",
+ generic: true,
+ },
+ {
+ name: "Or8",
+ generic: true,
+ },
+ {
+ name: "Or16",
+ generic: true,
+ },
+ {
+ name: "Or32",
+ generic: true,
+ },
+ {
+ name: "Or64",
+ generic: true,
+ },
+ {
+ name: "Xor8",
+ generic: true,
+ },
+ {
+ name: "Xor16",
+ generic: true,
+ },
+ {
+ name: "Xor32",
+ generic: true,
+ },
+ {
+ name: "Xor64",
+ generic: true,
+ },
+ {
+ name: "Lsh8x8",
+ generic: true,
+ },
+ {
+ name: "Lsh8x16",
+ generic: true,
+ },
+ {
+ name: "Lsh8x32",
+ generic: true,
+ },
+ {
+ name: "Lsh8x64",
+ generic: true,
+ },
+ {
+ name: "Lsh16x8",
+ generic: true,
+ },
+ {
+ name: "Lsh16x16",
+ generic: true,
+ },
+ {
+ name: "Lsh16x32",
+ generic: true,
+ },
+ {
+ name: "Lsh16x64",
+ generic: true,
+ },
+ {
+ name: "Lsh32x8",
+ generic: true,
+ },
+ {
+ name: "Lsh32x16",
+ generic: true,
+ },
+ {
+ name: "Lsh32x32",
+ generic: true,
+ },
+ {
+ name: "Lsh32x64",
+ generic: true,
+ },
+ {
+ name: "Lsh64x8",
+ generic: true,
+ },
+ {
+ name: "Lsh64x16",
+ generic: true,
+ },
+ {
+ name: "Lsh64x32",
+ generic: true,
+ },
+ {
+ name: "Lsh64x64",
+ generic: true,
+ },
+ {
+ name: "Rsh8x8",
+ generic: true,
+ },
+ {
+ name: "Rsh8x16",
+ generic: true,
+ },
+ {
+ name: "Rsh8x32",
+ generic: true,
+ },
+ {
+ name: "Rsh8x64",
+ generic: true,
+ },
+ {
+ name: "Rsh16x8",
+ generic: true,
+ },
+ {
+ name: "Rsh16x16",
+ generic: true,
+ },
+ {
+ name: "Rsh16x32",
+ generic: true,
+ },
+ {
+ name: "Rsh16x64",
+ generic: true,
+ },
+ {
+ name: "Rsh32x8",
+ generic: true,
+ },
+ {
+ name: "Rsh32x16",
+ generic: true,
+ },
+ {
+ name: "Rsh32x32",
+ generic: true,
+ },
+ {
+ name: "Rsh32x64",
+ generic: true,
+ },
+ {
+ name: "Rsh64x8",
+ generic: true,
+ },
+ {
+ name: "Rsh64x16",
+ generic: true,
+ },
+ {
+ name: "Rsh64x32",
+ generic: true,
+ },
+ {
+ name: "Rsh64x64",
+ generic: true,
+ },
+ {
+ name: "Rsh8Ux8",
+ generic: true,
+ },
+ {
+ name: "Rsh8Ux16",
+ generic: true,
+ },
+ {
+ name: "Rsh8Ux32",
+ generic: true,
+ },
+ {
+ name: "Rsh8Ux64",
+ generic: true,
+ },
+ {
+ name: "Rsh16Ux8",
+ generic: true,
+ },
+ {
+ name: "Rsh16Ux16",
+ generic: true,
+ },
+ {
+ name: "Rsh16Ux32",
+ generic: true,
+ },
+ {
+ name: "Rsh16Ux64",
+ generic: true,
+ },
+ {
+ name: "Rsh32Ux8",
+ generic: true,
+ },
+ {
+ name: "Rsh32Ux16",
+ generic: true,
+ },
+ {
+ name: "Rsh32Ux32",
+ generic: true,
+ },
+ {
+ name: "Rsh32Ux64",
+ generic: true,
+ },
+ {
+ name: "Rsh64Ux8",
+ generic: true,
+ },
+ {
+ name: "Rsh64Ux16",
+ generic: true,
+ },
+ {
+ name: "Rsh64Ux32",
+ generic: true,
+ },
+ {
+ name: "Rsh64Ux64",
+ generic: true,
+ },
+ {
+ name: "Lrot8",
+ generic: true,
+ },
+ {
+ name: "Lrot16",
+ generic: true,
+ },
+ {
+ name: "Lrot32",
+ generic: true,
+ },
+ {
+ name: "Lrot64",
+ generic: true,
+ },
+ {
+ name: "Eq8",
+ generic: true,
+ },
+ {
+ name: "Eq16",
+ generic: true,
+ },
+ {
+ name: "Eq32",
+ generic: true,
+ },
+ {
+ name: "Eq64",
+ generic: true,
+ },
+ {
+ name: "EqPtr",
+ generic: true,
+ },
+ {
+ name: "EqInter",
+ generic: true,
+ },
+ {
+ name: "EqSlice",
+ generic: true,
+ },
+ {
+ name: "Eq32F",
+ generic: true,
+ },
+ {
+ name: "Eq64F",
+ generic: true,
+ },
+ {
+ name: "Neq8",
+ generic: true,
+ },
+ {
+ name: "Neq16",
+ generic: true,
+ },
+ {
+ name: "Neq32",
+ generic: true,
+ },
+ {
+ name: "Neq64",
+ generic: true,
+ },
+ {
+ name: "NeqPtr",
+ generic: true,
+ },
+ {
+ name: "NeqInter",
+ generic: true,
+ },
+ {
+ name: "NeqSlice",
+ generic: true,
+ },
+ {
+ name: "Neq32F",
+ generic: true,
+ },
+ {
+ name: "Neq64F",
+ generic: true,
+ },
+ {
+ name: "Less8",
+ generic: true,
+ },
+ {
+ name: "Less8U",
+ generic: true,
+ },
+ {
+ name: "Less16",
+ generic: true,
+ },
+ {
+ name: "Less16U",
+ generic: true,
+ },
+ {
+ name: "Less32",
+ generic: true,
+ },
+ {
+ name: "Less32U",
+ generic: true,
+ },
+ {
+ name: "Less64",
+ generic: true,
+ },
+ {
+ name: "Less64U",
+ generic: true,
+ },
+ {
+ name: "Less32F",
+ generic: true,
+ },
+ {
+ name: "Less64F",
+ generic: true,
+ },
+ {
+ name: "Leq8",
+ generic: true,
+ },
+ {
+ name: "Leq8U",
+ generic: true,
+ },
+ {
+ name: "Leq16",
+ generic: true,
+ },
+ {
+ name: "Leq16U",
+ generic: true,
+ },
+ {
+ name: "Leq32",
+ generic: true,
+ },
+ {
+ name: "Leq32U",
+ generic: true,
+ },
+ {
+ name: "Leq64",
+ generic: true,
+ },
+ {
+ name: "Leq64U",
+ generic: true,
+ },
+ {
+ name: "Leq32F",
+ generic: true,
+ },
+ {
+ name: "Leq64F",
+ generic: true,
+ },
+ {
+ name: "Greater8",
+ generic: true,
+ },
+ {
+ name: "Greater8U",
+ generic: true,
+ },
+ {
+ name: "Greater16",
+ generic: true,
+ },
+ {
+ name: "Greater16U",
+ generic: true,
+ },
+ {
+ name: "Greater32",
+ generic: true,
+ },
+ {
+ name: "Greater32U",
+ generic: true,
+ },
+ {
+ name: "Greater64",
+ generic: true,
+ },
+ {
+ name: "Greater64U",
+ generic: true,
+ },
+ {
+ name: "Greater32F",
+ generic: true,
+ },
+ {
+ name: "Greater64F",
+ generic: true,
+ },
+ {
+ name: "Geq8",
+ generic: true,
+ },
+ {
+ name: "Geq8U",
+ generic: true,
+ },
+ {
+ name: "Geq16",
+ generic: true,
+ },
+ {
+ name: "Geq16U",
+ generic: true,
+ },
+ {
+ name: "Geq32",
+ generic: true,
+ },
+ {
+ name: "Geq32U",
+ generic: true,
+ },
+ {
+ name: "Geq64",
+ generic: true,
+ },
+ {
+ name: "Geq64U",
+ generic: true,
+ },
+ {
+ name: "Geq32F",
+ generic: true,
+ },
+ {
+ name: "Geq64F",
+ generic: true,
+ },
+ {
+ name: "Not",
+ generic: true,
+ },
+ {
+ name: "Neg8",
+ generic: true,
+ },
+ {
+ name: "Neg16",
+ generic: true,
+ },
+ {
+ name: "Neg32",
+ generic: true,
+ },
+ {
+ name: "Neg64",
+ generic: true,
+ },
+ {
+ name: "Neg32F",
+ generic: true,
+ },
+ {
+ name: "Neg64F",
+ generic: true,
+ },
+ {
+ name: "Com8",
+ generic: true,
+ },
+ {
+ name: "Com16",
+ generic: true,
+ },
+ {
+ name: "Com32",
+ generic: true,
+ },
+ {
+ name: "Com64",
+ generic: true,
+ },
+ {
+ name: "Sqrt",
+ generic: true,
+ },
+ {
+ name: "Phi",
+ generic: true,
+ },
+ {
+ name: "Copy",
+ generic: true,
+ },
+ {
+ name: "ConstBool",
+ generic: true,
+ },
+ {
+ name: "ConstString",
+ generic: true,
+ },
+ {
+ name: "ConstNil",
+ generic: true,
+ },
+ {
+ name: "Const8",
+ generic: true,
+ },
+ {
+ name: "Const16",
+ generic: true,
+ },
+ {
+ name: "Const32",
+ generic: true,
+ },
+ {
+ name: "Const64",
+ generic: true,
+ },
+ {
+ name: "Const32F",
+ generic: true,
+ },
+ {
+ name: "Const64F",
+ generic: true,
+ },
+ {
+ name: "ConstPtr",
+ generic: true,
+ },
+ {
+ name: "ConstInterface",
+ generic: true,
+ },
+ {
+ name: "ConstSlice",
+ generic: true,
+ },
+ {
+ name: "Arg",
+ generic: true,
+ },
+ {
+ name: "Addr",
+ generic: true,
+ },
+ {
+ name: "SP",
+ generic: true,
+ },
+ {
+ name: "SB",
+ generic: true,
+ },
+ {
+ name: "Func",
+ generic: true,
+ },
+ {
+ name: "Load",
+ generic: true,
+ },
+ {
+ name: "Store",
+ generic: true,
+ },
+ {
+ name: "Move",
+ generic: true,
+ },
+ {
+ name: "Zero",
+ generic: true,
+ },
+ {
+ name: "ClosureCall",
+ generic: true,
+ },
+ {
+ name: "StaticCall",
+ generic: true,
+ },
+ {
+ name: "DeferCall",
+ generic: true,
+ },
+ {
+ name: "GoCall",
+ generic: true,
+ },
+ {
+ name: "InterCall",
+ generic: true,
+ },
+ {
+ name: "SignExt8to16",
+ generic: true,
+ },
+ {
+ name: "SignExt8to32",
+ generic: true,
+ },
+ {
+ name: "SignExt8to64",
+ generic: true,
+ },
+ {
+ name: "SignExt16to32",
+ generic: true,
+ },
+ {
+ name: "SignExt16to64",
+ generic: true,
+ },
+ {
+ name: "SignExt32to64",
+ generic: true,
+ },
+ {
+ name: "ZeroExt8to16",
+ generic: true,
+ },
+ {
+ name: "ZeroExt8to32",
+ generic: true,
+ },
+ {
+ name: "ZeroExt8to64",
+ generic: true,
+ },
+ {
+ name: "ZeroExt16to32",
+ generic: true,
+ },
+ {
+ name: "ZeroExt16to64",
+ generic: true,
+ },
+ {
+ name: "ZeroExt32to64",
+ generic: true,
+ },
+ {
+ name: "Trunc16to8",
+ generic: true,
+ },
+ {
+ name: "Trunc32to8",
+ generic: true,
+ },
+ {
+ name: "Trunc32to16",
+ generic: true,
+ },
+ {
+ name: "Trunc64to8",
+ generic: true,
+ },
+ {
+ name: "Trunc64to16",
+ generic: true,
+ },
+ {
+ name: "Trunc64to32",
+ generic: true,
+ },
+ {
+ name: "Cvt32to32F",
+ generic: true,
+ },
+ {
+ name: "Cvt32to64F",
+ generic: true,
+ },
+ {
+ name: "Cvt64to32F",
+ generic: true,
+ },
+ {
+ name: "Cvt64to64F",
+ generic: true,
+ },
+ {
+ name: "Cvt32Fto32",
+ generic: true,
+ },
+ {
+ name: "Cvt32Fto64",
+ generic: true,
+ },
+ {
+ name: "Cvt64Fto32",
+ generic: true,
+ },
+ {
+ name: "Cvt64Fto64",
+ generic: true,
+ },
+ {
+ name: "Cvt32Fto64F",
+ generic: true,
+ },
+ {
+ name: "Cvt64Fto32F",
+ generic: true,
+ },
+ {
+ name: "IsNonNil",
+ generic: true,
+ },
+ {
+ name: "IsInBounds",
+ generic: true,
+ },
+ {
+ name: "IsSliceInBounds",
+ generic: true,
+ },
+ {
+ name: "PanicNilCheck",
+ generic: true,
+ },
+ {
+ name: "GetG",
+ generic: true,
+ },
+ {
+ name: "GetClosurePtr",
+ generic: true,
+ },
+ {
+ name: "ArrayIndex",
+ generic: true,
+ },
+ {
+ name: "PtrIndex",
+ generic: true,
+ },
+ {
+ name: "OffPtr",
+ generic: true,
+ },
+ {
+ name: "StructSelect",
+ generic: true,
+ },
+ {
+ name: "SliceMake",
+ generic: true,
+ },
+ {
+ name: "SlicePtr",
+ generic: true,
+ },
+ {
+ name: "SliceLen",
+ generic: true,
+ },
+ {
+ name: "SliceCap",
+ generic: true,
+ },
+ {
+ name: "ComplexMake",
+ generic: true,
+ },
+ {
+ name: "ComplexReal",
+ generic: true,
+ },
+ {
+ name: "ComplexImag",
+ generic: true,
+ },
+ {
+ name: "StringMake",
+ generic: true,
+ },
+ {
+ name: "StringPtr",
+ generic: true,
+ },
+ {
+ name: "StringLen",
+ generic: true,
+ },
+ {
+ name: "IMake",
+ generic: true,
+ },
+ {
+ name: "ITab",
+ generic: true,
+ },
+ {
+ name: "IData",
+ generic: true,
+ },
+ {
+ name: "StoreReg",
+ generic: true,
+ },
+ {
+ name: "LoadReg",
+ generic: true,
+ },
+ {
+ name: "FwdRef",
+ generic: true,
+ },
+ {
+ name: "VarDef",
+ generic: true,
+ },
+ {
+ name: "VarKill",
+ generic: true,
+ },
+}
+
+func (o Op) Asm() int { return opcodeTable[o].asm }
+func (o Op) String() string { return opcodeTable[o].name }
--- /dev/null
- // DUFFZERO consists of repeated blocks of 4 MOVs + ADD,
- // with 4 STOSQs at the very end.
- // The trailing STOSQs prevent the need for a DI preadjustment
- // for small numbers of words to clear.
+// 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 (
+ "fmt"
+ "math"
+)
+
+func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool) {
+ // repeat rewrites until we find no more rewrites
+ var curb *Block
+ var curv *Value
+ defer func() {
+ if curb != nil {
+ curb.Fatalf("panic during rewrite of block %s\n", curb.LongString())
+ }
+ if curv != nil {
+ curv.Fatalf("panic during rewrite of value %s\n", curv.LongString())
+ // TODO(khr): print source location also
+ }
+ }()
+ config := f.Config
+ for {
+ change := false
+ for _, b := range f.Blocks {
+ if b.Kind == BlockDead {
+ continue
+ }
+ if b.Control != nil && b.Control.Op == OpCopy {
+ for b.Control.Op == OpCopy {
+ b.Control = b.Control.Args[0]
+ }
+ }
+ curb = b
+ if rb(b) {
+ change = true
+ }
+ curb = nil
+ for _, v := range b.Values {
+ // elide any copies generated during rewriting
+ for i, a := range v.Args {
+ if a.Op != OpCopy {
+ continue
+ }
+ // Rewriting can generate OpCopy loops.
+ // They are harmless (see removePredecessor),
+ // but take care to stop if we find a cycle.
+ slow := a // advances every other iteration
+ var advance bool
+ for a.Op == OpCopy {
+ a = a.Args[0]
+ if slow == a {
+ break
+ }
+ if advance {
+ slow = a
+ }
+ advance = !advance
+ }
+ v.Args[i] = a
+ }
+
+ // apply rewrite function
+ curv = v
+ if rv(v, config) {
+ change = true
+ }
+ curv = nil
+ }
+ }
+ if !change {
+ return
+ }
+ }
+}
+
+// Common functions called from rewriting rules
+
+func is64BitFloat(t Type) bool {
+ return t.Size() == 8 && t.IsFloat()
+}
+
+func is32BitFloat(t Type) bool {
+ return t.Size() == 4 && t.IsFloat()
+}
+
+func is64BitInt(t Type) bool {
+ return t.Size() == 8 && t.IsInteger()
+}
+
+func is32BitInt(t Type) bool {
+ return t.Size() == 4 && t.IsInteger()
+}
+
+func is16BitInt(t Type) bool {
+ return t.Size() == 2 && t.IsInteger()
+}
+
+func is8BitInt(t Type) bool {
+ return t.Size() == 1 && t.IsInteger()
+}
+
+func isPtr(t Type) bool {
+ return t.IsPtr()
+}
+
+func isSigned(t Type) bool {
+ return t.IsSigned()
+}
+
+func typeSize(t Type) int64 {
+ return t.Size()
+}
+
+// addOff adds two int64 offsets. Fails if wraparound happens.
+func addOff(x, y int64) int64 {
+ z := x + y
+ // x and y have same sign and z has a different sign => overflow
+ if x^y >= 0 && x^z < 0 {
+ panic(fmt.Sprintf("offset overflow %d %d", x, y))
+ }
+ return z
+}
+
+// mergeSym merges two symbolic offsets. There is no real merging of
+// offsets, we just pick the non-nil one.
+func mergeSym(x, y interface{}) interface{} {
+ if x == nil {
+ return y
+ }
+ if y == nil {
+ return x
+ }
+ panic(fmt.Sprintf("mergeSym with two non-nil syms %s %s", x, y))
+ return nil
+}
+func canMergeSym(x, y interface{}) bool {
+ return x == nil || y == nil
+}
+
+func inBounds8(idx, len int64) bool { return int8(idx) >= 0 && int8(idx) < int8(len) }
+func inBounds16(idx, len int64) bool { return int16(idx) >= 0 && int16(idx) < int16(len) }
+func inBounds32(idx, len int64) bool { return int32(idx) >= 0 && int32(idx) < int32(len) }
+func inBounds64(idx, len int64) bool { return idx >= 0 && idx < len }
+
+// log2 returns logarithm in base of n.
+// expects n to be a power of 2.
+func log2(n int64) (l int64) {
+ for n > 1 {
+ l++
+ n >>= 1
+ }
+ return l
+}
+
+// isPowerOfTwo reports whether n is a power of 2.
+func isPowerOfTwo(n int64) bool {
+ return n > 0 && n&(n-1) == 0
+}
+
+// is32Bit reports whether n can be represented as a signed 32 bit integer.
+func is32Bit(n int64) bool {
+ return n == int64(int32(n))
+}
+
+// b2i translates a boolean value to 0 or 1 for assigning to auxInt.
+func b2i(b bool) int64 {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+// f2i is used in the rules for storing a float in AuxInt.
+func f2i(f float64) int64 {
+ return int64(math.Float64bits(f))
+}
+
- dzBlocks = 31 // number of MOV/ADD blocks
++// DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD,
+// See runtime/mkduff.go.
+const (
- dzDIStep = 8 // number of bytes cleared by each MOV instruction
++ dzBlocks = 16 // number of MOV/ADD blocks
+ dzBlockLen = 4 // number of clears per block
+ dzBlockSize = 19 // size of instructions in a single block
+ dzMovSize = 4 // size of single MOV instruction w/ offset
+ dzAddSize = 4 // size of single ADD instruction
- dzSize = dzBlocks*dzBlockSize + dzTailLen*dzTailSize // total size of DUFFZERO routine
++ dzClearStep = 16 // number of bytes cleared by each MOV instruction
+
+ dzTailLen = 4 // number of final STOSQ instructions
+ dzTailSize = 2 // size of single STOSQ instruction
+
- if size < 32 || size > 1024 || size%8 != 0 {
++ dzClearLen = dzClearStep * dzBlockLen // bytes cleared by one block
++ dzSize = dzBlocks * dzBlockSize
+)
+
+func duffStart(size int64) int64 {
+ x, _ := duff(size)
+ return x
+}
+func duffAdj(size int64) int64 {
+ _, x := duff(size)
+ return x
+}
+
+// duff returns the offset (from duffzero, in bytes) and pointer adjust (in bytes)
+// required to use the duffzero mechanism for a block of the given size.
+func duff(size int64) (int64, int64) {
- off := int64(dzSize)
- off -= dzTailLen * dzTailSize
- size -= dzTailLen * dzDIStep
- q := size / dzDIStep
- blocks, singles := q/dzBlockLen, q%dzBlockLen
- off -= dzBlockSize * blocks
++ if size < 32 || size > 1024 || size%dzClearStep != 0 {
+ panic("bad duffzero size")
+ }
+ // TODO: arch-dependent
- if singles > 0 {
- off -= dzAddSize + dzMovSize*singles
- adj -= dzDIStep * (dzBlockLen - singles)
++ steps := size / dzClearStep
++ blocks := steps / dzBlockLen
++ steps %= dzBlockLen
++ off := dzBlockSize * (dzBlocks - blocks)
+ var adj int64
++ if steps != 0 {
++ off -= dzAddSize
++ off -= dzMovSize * steps
++ adj -= dzClearStep * (dzBlockLen - steps)
+ }
+ return off, adj
+}
--- /dev/null
- // cond: size <= 1024 && size%8 == 0
- // result: (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVQconst [0]) mem)
+// autogenerated from gen/AMD64.rules: do not edit!
+// generated with: cd gen; go run *.go
+package ssa
+
+import "math"
+
+var _ = math.MinInt8 // in case not otherwise used
+func rewriteValueAMD64(v *Value, config *Config) bool {
+ b := v.Block
+ switch v.Op {
+ case OpAMD64ADDB:
+ // match: (ADDB x (MOVBconst [c]))
+ // cond:
+ // result: (ADDBconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto endab690db69bfd8192eea57a2f9f76bf84
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ADDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endab690db69bfd8192eea57a2f9f76bf84
+ endab690db69bfd8192eea57a2f9f76bf84:
+ ;
+ // match: (ADDB (MOVBconst [c]) x)
+ // cond:
+ // result: (ADDBconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end28aa1a4abe7e1abcdd64135e9967d39d
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ADDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end28aa1a4abe7e1abcdd64135e9967d39d
+ end28aa1a4abe7e1abcdd64135e9967d39d:
+ ;
+ // match: (ADDB x (NEGB y))
+ // cond:
+ // result: (SUBB x y)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64NEGB {
+ goto end9464509b8874ffb00b43b843da01f0bc
+ }
+ y := v.Args[1].Args[0]
+ v.Op = OpAMD64SUBB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end9464509b8874ffb00b43b843da01f0bc
+ end9464509b8874ffb00b43b843da01f0bc:
+ ;
+ case OpAMD64ADDBconst:
+ // match: (ADDBconst [c] (MOVBconst [d]))
+ // cond:
+ // result: (MOVBconst [c+d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto enda9b1e9e31ccdf0af5f4fe57bf4b1343f
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ return true
+ }
+ goto enda9b1e9e31ccdf0af5f4fe57bf4b1343f
+ enda9b1e9e31ccdf0af5f4fe57bf4b1343f:
+ ;
+ // match: (ADDBconst [c] (ADDBconst [d] x))
+ // cond:
+ // result: (ADDBconst [c+d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64ADDBconst {
+ goto end9b1e6890adbf9d9e447d591b4148cbd0
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ v.AddArg(x)
+ return true
+ }
+ goto end9b1e6890adbf9d9e447d591b4148cbd0
+ end9b1e6890adbf9d9e447d591b4148cbd0:
+ ;
+ case OpAMD64ADDL:
+ // match: (ADDL x (MOVLconst [c]))
+ // cond:
+ // result: (ADDLconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end8d6d3b99a7be8da6b7a254b7e709cc95
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ADDLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end8d6d3b99a7be8da6b7a254b7e709cc95
+ end8d6d3b99a7be8da6b7a254b7e709cc95:
+ ;
+ // match: (ADDL (MOVLconst [c]) x)
+ // cond:
+ // result: (ADDLconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end739561e08a561e26ce3634dc0d5ec733
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ADDLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end739561e08a561e26ce3634dc0d5ec733
+ end739561e08a561e26ce3634dc0d5ec733:
+ ;
+ // match: (ADDL x (NEGL y))
+ // cond:
+ // result: (SUBL x y)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64NEGL {
+ goto end9596df31f2685a49df67c6fb912a521d
+ }
+ y := v.Args[1].Args[0]
+ v.Op = OpAMD64SUBL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end9596df31f2685a49df67c6fb912a521d
+ end9596df31f2685a49df67c6fb912a521d:
+ ;
+ case OpAMD64ADDLconst:
+ // match: (ADDLconst [c] (MOVLconst [d]))
+ // cond:
+ // result: (MOVLconst [c+d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto ende04850e987890abf1d66199042a19c23
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ return true
+ }
+ goto ende04850e987890abf1d66199042a19c23
+ ende04850e987890abf1d66199042a19c23:
+ ;
+ // match: (ADDLconst [c] (ADDLconst [d] x))
+ // cond:
+ // result: (ADDLconst [c+d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64ADDLconst {
+ goto endf1dd8673b2fef4950aec87aa7523a236
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ v.AddArg(x)
+ return true
+ }
+ goto endf1dd8673b2fef4950aec87aa7523a236
+ endf1dd8673b2fef4950aec87aa7523a236:
+ ;
+ case OpAMD64ADDQ:
+ // match: (ADDQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (ADDQconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end1de8aeb1d043e0dadcffd169a99ce5c0
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto end1de8aeb1d043e0dadcffd169a99ce5c0
+ }
+ v.Op = OpAMD64ADDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end1de8aeb1d043e0dadcffd169a99ce5c0
+ end1de8aeb1d043e0dadcffd169a99ce5c0:
+ ;
+ // match: (ADDQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (ADDQconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto endca635e3bdecd9e3aeb892f841021dfaa
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto endca635e3bdecd9e3aeb892f841021dfaa
+ }
+ v.Op = OpAMD64ADDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endca635e3bdecd9e3aeb892f841021dfaa
+ endca635e3bdecd9e3aeb892f841021dfaa:
+ ;
+ // match: (ADDQ x (SHLQconst [3] y))
+ // cond:
+ // result: (LEAQ8 x y)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64SHLQconst {
+ goto endc02313d35a0525d1d680cd58992e820d
+ }
+ if v.Args[1].AuxInt != 3 {
+ goto endc02313d35a0525d1d680cd58992e820d
+ }
+ y := v.Args[1].Args[0]
+ v.Op = OpAMD64LEAQ8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endc02313d35a0525d1d680cd58992e820d
+ endc02313d35a0525d1d680cd58992e820d:
+ ;
+ // match: (ADDQ x (NEGQ y))
+ // cond:
+ // result: (SUBQ x y)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64NEGQ {
+ goto endec8f899c6e175a0147a90750f9bfe0a2
+ }
+ y := v.Args[1].Args[0]
+ v.Op = OpAMD64SUBQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endec8f899c6e175a0147a90750f9bfe0a2
+ endec8f899c6e175a0147a90750f9bfe0a2:
+ ;
+ case OpAMD64ADDQconst:
+ // match: (ADDQconst [c] (LEAQ8 [d] x y))
+ // cond:
+ // result: (LEAQ8 [addOff(c, d)] x y)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64LEAQ8 {
+ goto ende2cc681c9abf9913288803fb1b39e639
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ y := v.Args[0].Args[1]
+ v.Op = OpAMD64LEAQ8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(c, d)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto ende2cc681c9abf9913288803fb1b39e639
+ ende2cc681c9abf9913288803fb1b39e639:
+ ;
+ // match: (ADDQconst [0] x)
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 0 {
+ goto end03d9f5a3e153048b0afa781401e2a849
+ }
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end03d9f5a3e153048b0afa781401e2a849
+ end03d9f5a3e153048b0afa781401e2a849:
+ ;
+ // match: (ADDQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [c+d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end09dc54395b4e96e8332cf8e4e7481c52
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ return true
+ }
+ goto end09dc54395b4e96e8332cf8e4e7481c52
+ end09dc54395b4e96e8332cf8e4e7481c52:
+ ;
+ // match: (ADDQconst [c] (ADDQconst [d] x))
+ // cond:
+ // result: (ADDQconst [c+d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto endd4cb539641f0dc40bfd0cb7fbb9b0405
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ v.AddArg(x)
+ return true
+ }
+ goto endd4cb539641f0dc40bfd0cb7fbb9b0405
+ endd4cb539641f0dc40bfd0cb7fbb9b0405:
+ ;
+ case OpAMD64ADDW:
+ // match: (ADDW x (MOVWconst [c]))
+ // cond:
+ // result: (ADDWconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto end1aabd2317de77c7dfc4876fd7e4c5011
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ADDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end1aabd2317de77c7dfc4876fd7e4c5011
+ end1aabd2317de77c7dfc4876fd7e4c5011:
+ ;
+ // match: (ADDW (MOVWconst [c]) x)
+ // cond:
+ // result: (ADDWconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto ende3aede99966f388afc624f9e86676fd2
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ADDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto ende3aede99966f388afc624f9e86676fd2
+ ende3aede99966f388afc624f9e86676fd2:
+ ;
+ // match: (ADDW x (NEGW y))
+ // cond:
+ // result: (SUBW x y)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64NEGW {
+ goto end55cf2af0d75f3ec413528eeb799e94d5
+ }
+ y := v.Args[1].Args[0]
+ v.Op = OpAMD64SUBW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end55cf2af0d75f3ec413528eeb799e94d5
+ end55cf2af0d75f3ec413528eeb799e94d5:
+ ;
+ case OpAMD64ADDWconst:
+ // match: (ADDWconst [c] (MOVWconst [d]))
+ // cond:
+ // result: (MOVWconst [c+d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end32541920f2f5a920dfae41d8ebbef00f
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ return true
+ }
+ goto end32541920f2f5a920dfae41d8ebbef00f
+ end32541920f2f5a920dfae41d8ebbef00f:
+ ;
+ // match: (ADDWconst [c] (ADDWconst [d] x))
+ // cond:
+ // result: (ADDWconst [c+d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64ADDWconst {
+ goto end73944f6ddda7e4c050f11d17484ff9a5
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c + d
+ v.AddArg(x)
+ return true
+ }
+ goto end73944f6ddda7e4c050f11d17484ff9a5
+ end73944f6ddda7e4c050f11d17484ff9a5:
+ ;
+ case OpAMD64ANDB:
+ // match: (ANDB x (MOVLconst [c]))
+ // cond:
+ // result: (ANDBconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end01100cd255396e29bfdb130f4fbc9bbc
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ANDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end01100cd255396e29bfdb130f4fbc9bbc
+ end01100cd255396e29bfdb130f4fbc9bbc:
+ ;
+ // match: (ANDB (MOVLconst [c]) x)
+ // cond:
+ // result: (ANDBconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end70830ce2834dc5f8d786fa6789460926
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ANDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end70830ce2834dc5f8d786fa6789460926
+ end70830ce2834dc5f8d786fa6789460926:
+ ;
+ // match: (ANDB x (MOVBconst [c]))
+ // cond:
+ // result: (ANDBconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto endd275ec2e73768cb3d201478fc934e06c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ANDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endd275ec2e73768cb3d201478fc934e06c
+ endd275ec2e73768cb3d201478fc934e06c:
+ ;
+ // match: (ANDB (MOVBconst [c]) x)
+ // cond:
+ // result: (ANDBconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end4068edac2ae0f354cf581db210288b98
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ANDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end4068edac2ae0f354cf581db210288b98
+ end4068edac2ae0f354cf581db210288b98:
+ ;
+ // match: (ANDB x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto endb8ff272a1456513da708603abe37541c
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endb8ff272a1456513da708603abe37541c
+ endb8ff272a1456513da708603abe37541c:
+ ;
+ case OpAMD64ANDBconst:
+ // match: (ANDBconst [c] _)
+ // cond: int8(c)==0
+ // result: (MOVBconst [0])
+ {
+ c := v.AuxInt
+ if !(int8(c) == 0) {
+ goto end2106d410c949da14d7c00041f40eca76
+ }
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end2106d410c949da14d7c00041f40eca76
+ end2106d410c949da14d7c00041f40eca76:
+ ;
+ // match: (ANDBconst [c] x)
+ // cond: int8(c)==-1
+ // result: x
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(int8(c) == -1) {
+ goto enda0b78503c204c8225de1433949a71fe4
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto enda0b78503c204c8225de1433949a71fe4
+ enda0b78503c204c8225de1433949a71fe4:
+ ;
+ // match: (ANDBconst [c] (MOVBconst [d]))
+ // cond:
+ // result: (MOVBconst [c&d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end946312b1f216933da86febe293eb956f
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & d
+ return true
+ }
+ goto end946312b1f216933da86febe293eb956f
+ end946312b1f216933da86febe293eb956f:
+ ;
+ case OpAMD64ANDL:
+ // match: (ANDL x (MOVLconst [c]))
+ // cond:
+ // result: (ANDLconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end0a4c49d9a26759c0fd21369dafcd7abb
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ANDLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end0a4c49d9a26759c0fd21369dafcd7abb
+ end0a4c49d9a26759c0fd21369dafcd7abb:
+ ;
+ // match: (ANDL (MOVLconst [c]) x)
+ // cond:
+ // result: (ANDLconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end0529ba323d9b6f15c41add401ef67959
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ANDLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end0529ba323d9b6f15c41add401ef67959
+ end0529ba323d9b6f15c41add401ef67959:
+ ;
+ // match: (ANDL x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto enddfb08a0d0c262854db3905cb323388c7
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto enddfb08a0d0c262854db3905cb323388c7
+ enddfb08a0d0c262854db3905cb323388c7:
+ ;
+ case OpAMD64ANDLconst:
+ // match: (ANDLconst [c] _)
+ // cond: int32(c)==0
+ // result: (MOVLconst [0])
+ {
+ c := v.AuxInt
+ if !(int32(c) == 0) {
+ goto end5efb241208aef28c950b7bcf8d85d5de
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end5efb241208aef28c950b7bcf8d85d5de
+ end5efb241208aef28c950b7bcf8d85d5de:
+ ;
+ // match: (ANDLconst [c] x)
+ // cond: int32(c)==-1
+ // result: x
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(int32(c) == -1) {
+ goto end0e852ae30bb8289d6ffee0c9267e3e0c
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end0e852ae30bb8289d6ffee0c9267e3e0c
+ end0e852ae30bb8289d6ffee0c9267e3e0c:
+ ;
+ // match: (ANDLconst [c] (MOVLconst [d]))
+ // cond:
+ // result: (MOVLconst [c&d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end7bfd24059369753eadd235f07e2dd7b8
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & d
+ return true
+ }
+ goto end7bfd24059369753eadd235f07e2dd7b8
+ end7bfd24059369753eadd235f07e2dd7b8:
+ ;
+ case OpAMD64ANDQ:
+ // match: (ANDQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (ANDQconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end048fadc69e81103480015b84b9cafff7
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto end048fadc69e81103480015b84b9cafff7
+ }
+ v.Op = OpAMD64ANDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end048fadc69e81103480015b84b9cafff7
+ end048fadc69e81103480015b84b9cafff7:
+ ;
+ // match: (ANDQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (ANDQconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end3035a3bf650b708705fd27dd857ab0a4
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto end3035a3bf650b708705fd27dd857ab0a4
+ }
+ v.Op = OpAMD64ANDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end3035a3bf650b708705fd27dd857ab0a4
+ end3035a3bf650b708705fd27dd857ab0a4:
+ ;
+ // match: (ANDQ x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end06b5ec19efdd4e79f03a5e4a2c3c3427
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end06b5ec19efdd4e79f03a5e4a2c3c3427
+ end06b5ec19efdd4e79f03a5e4a2c3c3427:
+ ;
+ case OpAMD64ANDQconst:
+ // match: (ANDQconst [0] _)
+ // cond:
+ // result: (MOVQconst [0])
+ {
+ if v.AuxInt != 0 {
+ goto end57018c1d0f54fd721521095b4832bab2
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end57018c1d0f54fd721521095b4832bab2
+ end57018c1d0f54fd721521095b4832bab2:
+ ;
+ // match: (ANDQconst [-1] x)
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != -1 {
+ goto endb542c4b42ab94a7bedb32dec8f610d67
+ }
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endb542c4b42ab94a7bedb32dec8f610d67
+ endb542c4b42ab94a7bedb32dec8f610d67:
+ ;
+ // match: (ANDQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [c&d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end67ca66494705b0345a5f22c710225292
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & d
+ return true
+ }
+ goto end67ca66494705b0345a5f22c710225292
+ end67ca66494705b0345a5f22c710225292:
+ ;
+ case OpAMD64ANDW:
+ // match: (ANDW x (MOVLconst [c]))
+ // cond:
+ // result: (ANDWconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto endce6f557823ee2fdd7a8f47b6f925fc7c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ANDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endce6f557823ee2fdd7a8f47b6f925fc7c
+ endce6f557823ee2fdd7a8f47b6f925fc7c:
+ ;
+ // match: (ANDW (MOVLconst [c]) x)
+ // cond:
+ // result: (ANDWconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto endc46af0d9265c08b09f1f1fba24feda80
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ANDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endc46af0d9265c08b09f1f1fba24feda80
+ endc46af0d9265c08b09f1f1fba24feda80:
+ ;
+ // match: (ANDW x (MOVWconst [c]))
+ // cond:
+ // result: (ANDWconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto enda77a39f65a5eb3436a5842eab69a3103
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ANDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto enda77a39f65a5eb3436a5842eab69a3103
+ enda77a39f65a5eb3436a5842eab69a3103:
+ ;
+ // match: (ANDW (MOVWconst [c]) x)
+ // cond:
+ // result: (ANDWconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto endea2a25eb525a5dbf6d5132d84ea4e7a5
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ANDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endea2a25eb525a5dbf6d5132d84ea4e7a5
+ endea2a25eb525a5dbf6d5132d84ea4e7a5:
+ ;
+ // match: (ANDW x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end3a26cf52dd1b77f07cc9e005760dbb11
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end3a26cf52dd1b77f07cc9e005760dbb11
+ end3a26cf52dd1b77f07cc9e005760dbb11:
+ ;
+ case OpAMD64ANDWconst:
+ // match: (ANDWconst [c] _)
+ // cond: int16(c)==0
+ // result: (MOVWconst [0])
+ {
+ c := v.AuxInt
+ if !(int16(c) == 0) {
+ goto end336ece33b4f0fb44dfe1f24981df7b74
+ }
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end336ece33b4f0fb44dfe1f24981df7b74
+ end336ece33b4f0fb44dfe1f24981df7b74:
+ ;
+ // match: (ANDWconst [c] x)
+ // cond: int16(c)==-1
+ // result: x
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(int16(c) == -1) {
+ goto endfb111c3afa8c5c4040fa6000fadee810
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endfb111c3afa8c5c4040fa6000fadee810
+ endfb111c3afa8c5c4040fa6000fadee810:
+ ;
+ // match: (ANDWconst [c] (MOVWconst [d]))
+ // cond:
+ // result: (MOVWconst [c&d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end250eb27fcac10bf6c0d96ce66a21726e
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & d
+ return true
+ }
+ goto end250eb27fcac10bf6c0d96ce66a21726e
+ end250eb27fcac10bf6c0d96ce66a21726e:
+ ;
+ case OpAdd16:
+ // match: (Add16 x y)
+ // cond:
+ // result: (ADDW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto ende604481c6de9fe4574cb2954ba2ddc67
+ ende604481c6de9fe4574cb2954ba2ddc67:
+ ;
+ case OpAdd32:
+ // match: (Add32 x y)
+ // cond:
+ // result: (ADDL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endc445ea2a65385445676cd684ae9a42b5
+ endc445ea2a65385445676cd684ae9a42b5:
+ ;
+ case OpAdd32F:
+ // match: (Add32F x y)
+ // cond:
+ // result: (ADDSS x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDSS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end5d82e1c10823774894c036b7c5b8fed4
+ end5d82e1c10823774894c036b7c5b8fed4:
+ ;
+ case OpAdd64:
+ // match: (Add64 x y)
+ // cond:
+ // result: (ADDQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endd88f18b3f39e3ccc201477a616f0abc0
+ endd88f18b3f39e3ccc201477a616f0abc0:
+ ;
+ case OpAdd64F:
+ // match: (Add64F x y)
+ // cond:
+ // result: (ADDSD x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDSD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end62f2de6c70abd214e6987ee37976653a
+ end62f2de6c70abd214e6987ee37976653a:
+ ;
+ case OpAdd8:
+ // match: (Add8 x y)
+ // cond:
+ // result: (ADDB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end6117c84a6b75c1b816b3fb095bc5f656
+ end6117c84a6b75c1b816b3fb095bc5f656:
+ ;
+ case OpAddPtr:
+ // match: (AddPtr x y)
+ // cond:
+ // result: (ADDQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ADDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto enda1d5640788c7157996f9d4af602dec1c
+ enda1d5640788c7157996f9d4af602dec1c:
+ ;
+ case OpAddr:
+ // match: (Addr {sym} base)
+ // cond:
+ // result: (LEAQ {sym} base)
+ {
+ sym := v.Aux
+ base := v.Args[0]
+ v.Op = OpAMD64LEAQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Aux = sym
+ v.AddArg(base)
+ return true
+ }
+ goto end53cad0c3c9daa5575680e77c14e05e72
+ end53cad0c3c9daa5575680e77c14e05e72:
+ ;
+ case OpAnd16:
+ // match: (And16 x y)
+ // cond:
+ // result: (ANDW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end1c01f04a173d86ce1a6d1ef59e753014
+ end1c01f04a173d86ce1a6d1ef59e753014:
+ ;
+ case OpAnd32:
+ // match: (And32 x y)
+ // cond:
+ // result: (ANDL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end6b9eb9375b3a859028a6ba6bf6b8ec88
+ end6b9eb9375b3a859028a6ba6bf6b8ec88:
+ ;
+ case OpAnd64:
+ // match: (And64 x y)
+ // cond:
+ // result: (ANDQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto enda0bde5853819d05fa2b7d3b723629552
+ enda0bde5853819d05fa2b7d3b723629552:
+ ;
+ case OpAnd8:
+ // match: (And8 x y)
+ // cond:
+ // result: (ANDB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end0f53bee6291f1229b43aa1b5f977b4f2
+ end0f53bee6291f1229b43aa1b5f977b4f2:
+ ;
+ case OpAMD64CMPB:
+ // match: (CMPB x (MOVBconst [c]))
+ // cond:
+ // result: (CMPBconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto end52190c0b8759133aa6c540944965c4c0
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64CMPBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end52190c0b8759133aa6c540944965c4c0
+ end52190c0b8759133aa6c540944965c4c0:
+ ;
+ // match: (CMPB (MOVBconst [c]) x)
+ // cond:
+ // result: (InvertFlags (CMPBconst x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end25ab646f9eb8749ea58c8fbbb4bf6bcd
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64InvertFlags
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end25ab646f9eb8749ea58c8fbbb4bf6bcd
+ end25ab646f9eb8749ea58c8fbbb4bf6bcd:
+ ;
+ case OpAMD64CMPL:
+ // match: (CMPL x (MOVLconst [c]))
+ // cond:
+ // result: (CMPLconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end49ff4559c4bdecb2aef0c905e2d9a6cf
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64CMPLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end49ff4559c4bdecb2aef0c905e2d9a6cf
+ end49ff4559c4bdecb2aef0c905e2d9a6cf:
+ ;
+ // match: (CMPL (MOVLconst [c]) x)
+ // cond:
+ // result: (InvertFlags (CMPLconst x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end7d89230086678ab4ed5cc96a3ae358d6
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64InvertFlags
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end7d89230086678ab4ed5cc96a3ae358d6
+ end7d89230086678ab4ed5cc96a3ae358d6:
+ ;
+ case OpAMD64CMPQ:
+ // match: (CMPQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (CMPQconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end3bbb2c6caa57853a7561738ce3c0c630
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto end3bbb2c6caa57853a7561738ce3c0c630
+ }
+ v.Op = OpAMD64CMPQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end3bbb2c6caa57853a7561738ce3c0c630
+ end3bbb2c6caa57853a7561738ce3c0c630:
+ ;
+ // match: (CMPQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (InvertFlags (CMPQconst x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end153e951c4d9890ee40bf6f189ff6280e
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto end153e951c4d9890ee40bf6f189ff6280e
+ }
+ v.Op = OpAMD64InvertFlags
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end153e951c4d9890ee40bf6f189ff6280e
+ end153e951c4d9890ee40bf6f189ff6280e:
+ ;
+ case OpAMD64CMPW:
+ // match: (CMPW x (MOVWconst [c]))
+ // cond:
+ // result: (CMPWconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto end310a9ba58ac35c97587e08c63fe8a46c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64CMPWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end310a9ba58ac35c97587e08c63fe8a46c
+ end310a9ba58ac35c97587e08c63fe8a46c:
+ ;
+ // match: (CMPW (MOVWconst [c]) x)
+ // cond:
+ // result: (InvertFlags (CMPWconst x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end3c52d0ae6e3d186bf131b41276c21889
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64InvertFlags
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end3c52d0ae6e3d186bf131b41276c21889
+ end3c52d0ae6e3d186bf131b41276c21889:
+ ;
+ case OpClosureCall:
+ // match: (ClosureCall [argwid] entry closure mem)
+ // cond:
+ // result: (CALLclosure [argwid] entry closure mem)
+ {
+ argwid := v.AuxInt
+ entry := v.Args[0]
+ closure := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64CALLclosure
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = argwid
+ v.AddArg(entry)
+ v.AddArg(closure)
+ v.AddArg(mem)
+ return true
+ }
+ goto endfd75d26316012d86cb71d0dd1214259b
+ endfd75d26316012d86cb71d0dd1214259b:
+ ;
+ case OpCom16:
+ // match: (Com16 x)
+ // cond:
+ // result: (NOTW x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NOTW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end1b14ba8d7d7aa585ec0a211827f280ae
+ end1b14ba8d7d7aa585ec0a211827f280ae:
+ ;
+ case OpCom32:
+ // match: (Com32 x)
+ // cond:
+ // result: (NOTL x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NOTL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end6eb124ba3bdb3fd6031414370852feb6
+ end6eb124ba3bdb3fd6031414370852feb6:
+ ;
+ case OpCom64:
+ // match: (Com64 x)
+ // cond:
+ // result: (NOTQ x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NOTQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endf5f3b355a87779c347e305719dddda05
+ endf5f3b355a87779c347e305719dddda05:
+ ;
+ case OpCom8:
+ // match: (Com8 x)
+ // cond:
+ // result: (NOTB x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NOTB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end1c7c5c055d663ccf1f05fbc4883030c6
+ end1c7c5c055d663ccf1f05fbc4883030c6:
+ ;
+ case OpConst16:
+ // match: (Const16 [val])
+ // cond:
+ // result: (MOVWconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto end2c6c92f297873b8ac12bd035d56d001e
+ end2c6c92f297873b8ac12bd035d56d001e:
+ ;
+ case OpConst32:
+ // match: (Const32 [val])
+ // cond:
+ // result: (MOVLconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto enddae5807662af67143a3ac3ad9c63bae5
+ enddae5807662af67143a3ac3ad9c63bae5:
+ ;
+ case OpConst32F:
+ // match: (Const32F [val])
+ // cond:
+ // result: (MOVSSconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVSSconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto endfabcef2d57a8f36eaa6041de6f112b89
+ endfabcef2d57a8f36eaa6041de6f112b89:
+ ;
+ case OpConst64:
+ // match: (Const64 [val])
+ // cond:
+ // result: (MOVQconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto endc630434ae7f143ab69d5f482a9b52b5f
+ endc630434ae7f143ab69d5f482a9b52b5f:
+ ;
+ case OpConst64F:
+ // match: (Const64F [val])
+ // cond:
+ // result: (MOVSDconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVSDconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto endae6cf7189e464bbde17b98635a20f0ff
+ endae6cf7189e464bbde17b98635a20f0ff:
+ ;
+ case OpConst8:
+ // match: (Const8 [val])
+ // cond:
+ // result: (MOVBconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto end200524c722ed14ca935ba47f8f30327d
+ end200524c722ed14ca935ba47f8f30327d:
+ ;
+ case OpConstBool:
+ // match: (ConstBool [b])
+ // cond:
+ // result: (MOVBconst [b])
+ {
+ b := v.AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = b
+ return true
+ }
+ goto end6d919011283330dcbcb3826f0adc6793
+ end6d919011283330dcbcb3826f0adc6793:
+ ;
+ case OpConstNil:
+ // match: (ConstNil)
+ // cond:
+ // result: (MOVQconst [0])
+ {
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto endea557d921056c25b945a49649e4b9b91
+ endea557d921056c25b945a49649e4b9b91:
+ ;
+ case OpConstPtr:
+ // match: (ConstPtr [val])
+ // cond:
+ // result: (MOVQconst [val])
+ {
+ val := v.AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = val
+ return true
+ }
+ goto endc395c0a53eeccf597e225a07b53047d1
+ endc395c0a53eeccf597e225a07b53047d1:
+ ;
+ case OpCvt32Fto32:
+ // match: (Cvt32Fto32 x)
+ // cond:
+ // result: (CVTTSS2SL x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTTSS2SL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto enda410209d31804e1bce7bdc235fc62342
+ enda410209d31804e1bce7bdc235fc62342:
+ ;
+ case OpCvt32Fto64:
+ // match: (Cvt32Fto64 x)
+ // cond:
+ // result: (CVTTSS2SQ x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTTSS2SQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto enddb02fa4f3230a14d557d6c90cdadd523
+ enddb02fa4f3230a14d557d6c90cdadd523:
+ ;
+ case OpCvt32Fto64F:
+ // match: (Cvt32Fto64F x)
+ // cond:
+ // result: (CVTSS2SD x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTSS2SD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end0bf5d6f8d182ee2b3ab7d7c2f8ff7790
+ end0bf5d6f8d182ee2b3ab7d7c2f8ff7790:
+ ;
+ case OpCvt32to32F:
+ // match: (Cvt32to32F x)
+ // cond:
+ // result: (CVTSL2SS x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTSL2SS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto ende0bdea2b21aecdb8399d6fd80ddc97d6
+ ende0bdea2b21aecdb8399d6fd80ddc97d6:
+ ;
+ case OpCvt32to64F:
+ // match: (Cvt32to64F x)
+ // cond:
+ // result: (CVTSL2SD x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTSL2SD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto ende06cbe745112bcf0e6612788ef71c958
+ ende06cbe745112bcf0e6612788ef71c958:
+ ;
+ case OpCvt64Fto32:
+ // match: (Cvt64Fto32 x)
+ // cond:
+ // result: (CVTTSD2SL x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTTSD2SL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endc213dd690dfe568607dec717b2c385b7
+ endc213dd690dfe568607dec717b2c385b7:
+ ;
+ case OpCvt64Fto32F:
+ // match: (Cvt64Fto32F x)
+ // cond:
+ // result: (CVTSD2SS x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTSD2SS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endfd70158a96824ced99712d606c607d94
+ endfd70158a96824ced99712d606c607d94:
+ ;
+ case OpCvt64Fto64:
+ // match: (Cvt64Fto64 x)
+ // cond:
+ // result: (CVTTSD2SQ x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTTSD2SQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end0bf3e4468047fd20714266ff05797454
+ end0bf3e4468047fd20714266ff05797454:
+ ;
+ case OpCvt64to32F:
+ // match: (Cvt64to32F x)
+ // cond:
+ // result: (CVTSQ2SS x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTSQ2SS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endfecc08b8a8cbd2bf3be21a077c4d0d40
+ endfecc08b8a8cbd2bf3be21a077c4d0d40:
+ ;
+ case OpCvt64to64F:
+ // match: (Cvt64to64F x)
+ // cond:
+ // result: (CVTSQ2SD x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64CVTSQ2SD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endf74ce5df659f385f75c61187b515a5d0
+ endf74ce5df659f385f75c61187b515a5d0:
+ ;
+ case OpDeferCall:
+ // match: (DeferCall [argwid] mem)
+ // cond:
+ // result: (CALLdefer [argwid] mem)
+ {
+ argwid := v.AuxInt
+ mem := v.Args[0]
+ v.Op = OpAMD64CALLdefer
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = argwid
+ v.AddArg(mem)
+ return true
+ }
+ goto end1c408581037450df959dd1fb7554a022
+ end1c408581037450df959dd1fb7554a022:
+ ;
+ case OpDiv16:
+ // match: (Div16 x y)
+ // cond:
+ // result: (DIVW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endb60a86e606726640c84d3e1e5a5ce890
+ endb60a86e606726640c84d3e1e5a5ce890:
+ ;
+ case OpDiv16u:
+ // match: (Div16u x y)
+ // cond:
+ // result: (DIVWU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVWU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end6af9e212a865593e506bfdf7db67c9ec
+ end6af9e212a865593e506bfdf7db67c9ec:
+ ;
+ case OpDiv32:
+ // match: (Div32 x y)
+ // cond:
+ // result: (DIVL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endf20ac71407e57c2904684d3cc33cf697
+ endf20ac71407e57c2904684d3cc33cf697:
+ ;
+ case OpDiv32F:
+ // match: (Div32F x y)
+ // cond:
+ // result: (DIVSS x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVSS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto enddca0462c7b176c4138854d7d5627ab5b
+ enddca0462c7b176c4138854d7d5627ab5b:
+ ;
+ case OpDiv32u:
+ // match: (Div32u x y)
+ // cond:
+ // result: (DIVLU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVLU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto enda22604d23eeb1298008c97b817f60bbd
+ enda22604d23eeb1298008c97b817f60bbd:
+ ;
+ case OpDiv64:
+ // match: (Div64 x y)
+ // cond:
+ // result: (DIVQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end86490d9b337333dfc09a413e1e0120a9
+ end86490d9b337333dfc09a413e1e0120a9:
+ ;
+ case OpDiv64F:
+ // match: (Div64F x y)
+ // cond:
+ // result: (DIVSD x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVSD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end12299d76db5144a60f564d34ba97eb43
+ end12299d76db5144a60f564d34ba97eb43:
+ ;
+ case OpDiv64u:
+ // match: (Div64u x y)
+ // cond:
+ // result: (DIVQU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVQU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endf871d8b397e5fad6a5b500cc0c759a8d
+ endf871d8b397e5fad6a5b500cc0c759a8d:
+ ;
+ case OpDiv8:
+ // match: (Div8 x y)
+ // cond:
+ // result: (DIVW (SignExt8to16 x) (SignExt8to16 y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpSignExt8to16, TypeInvalid)
+ v0.AddArg(x)
+ v0.Type = config.fe.TypeInt16()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpSignExt8to16, TypeInvalid)
+ v1.AddArg(y)
+ v1.Type = config.fe.TypeInt16()
+ v.AddArg(v1)
+ return true
+ }
+ goto endeee2bc780a73ec2ccb1a66c527816ee0
+ endeee2bc780a73ec2ccb1a66c527816ee0:
+ ;
+ case OpDiv8u:
+ // match: (Div8u x y)
+ // cond:
+ // result: (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64DIVWU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpZeroExt8to16, TypeInvalid)
+ v0.AddArg(x)
+ v0.Type = config.fe.TypeUInt16()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpZeroExt8to16, TypeInvalid)
+ v1.AddArg(y)
+ v1.Type = config.fe.TypeUInt16()
+ v.AddArg(v1)
+ return true
+ }
+ goto end39da6664d6434d844303f6924cc875dd
+ end39da6664d6434d844303f6924cc875dd:
+ ;
+ case OpEq16:
+ // match: (Eq16 x y)
+ // cond:
+ // result: (SETEQ (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endd7f668b1d23603b0949953ee8dec8107
+ endd7f668b1d23603b0949953ee8dec8107:
+ ;
+ case OpEq32:
+ // match: (Eq32 x y)
+ // cond:
+ // result: (SETEQ (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endf28041ae0c73fb341cc0d2f4903fb2fb
+ endf28041ae0c73fb341cc0d2f4903fb2fb:
+ ;
+ case OpEq32F:
+ // match: (Eq32F x y)
+ // cond:
+ // result: (SETEQF (UCOMISS x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISS, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endb2c12933769e5faa8fc238048e113dee
+ endb2c12933769e5faa8fc238048e113dee:
+ ;
+ case OpEq64:
+ // match: (Eq64 x y)
+ // cond:
+ // result: (SETEQ (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto ende07a380487b710b51bcd5aa6d3144b8c
+ ende07a380487b710b51bcd5aa6d3144b8c:
+ ;
+ case OpEq64F:
+ // match: (Eq64F x y)
+ // cond:
+ // result: (SETEQF (UCOMISD x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISD, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end68e20c0c1b3ee62fbd17af07ac100704
+ end68e20c0c1b3ee62fbd17af07ac100704:
+ ;
+ case OpEq8:
+ // match: (Eq8 x y)
+ // cond:
+ // result: (SETEQ (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end359e5a51d2ab928a455f0ae5adb42ab0
+ end359e5a51d2ab928a455f0ae5adb42ab0:
+ ;
+ case OpEqPtr:
+ // match: (EqPtr x y)
+ // cond:
+ // result: (SETEQ (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETEQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endf19bd3c0eb99d15718bef4066d62560c
+ endf19bd3c0eb99d15718bef4066d62560c:
+ ;
+ case OpGeq16:
+ // match: (Geq16 x y)
+ // cond:
+ // result: (SETGE (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end0a3f723d5c0b877c473b0043d814867b
+ end0a3f723d5c0b877c473b0043d814867b:
+ ;
+ case OpGeq16U:
+ // match: (Geq16U x y)
+ // cond:
+ // result: (SETAE (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETAE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end79d754a28ee34eff95140635b26f0248
+ end79d754a28ee34eff95140635b26f0248:
+ ;
+ case OpGeq32:
+ // match: (Geq32 x y)
+ // cond:
+ // result: (SETGE (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endfb1f6286a1b153b2a3f5b8548a782c8c
+ endfb1f6286a1b153b2a3f5b8548a782c8c:
+ ;
+ case OpGeq32F:
+ // match: (Geq32F x y)
+ // cond:
+ // result: (SETGEF (UCOMISS x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGEF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISS, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end7a8d6107a945410e64db06669a61da97
+ end7a8d6107a945410e64db06669a61da97:
+ ;
+ case OpGeq32U:
+ // match: (Geq32U x y)
+ // cond:
+ // result: (SETAE (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETAE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endc5d3478a626df01ede063564f4cb80d0
+ endc5d3478a626df01ede063564f4cb80d0:
+ ;
+ case OpGeq64:
+ // match: (Geq64 x y)
+ // cond:
+ // result: (SETGE (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end74bddb7905ab865de5b041e7e4789911
+ end74bddb7905ab865de5b041e7e4789911:
+ ;
+ case OpGeq64F:
+ // match: (Geq64F x y)
+ // cond:
+ // result: (SETGEF (UCOMISD x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGEF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISD, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end9fac9bd98ef58b7fbbe1a31f84bdcccf
+ end9fac9bd98ef58b7fbbe1a31f84bdcccf:
+ ;
+ case OpGeq64U:
+ // match: (Geq64U x y)
+ // cond:
+ // result: (SETAE (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETAE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end95101721fc8f5be9969e50e364143e7f
+ end95101721fc8f5be9969e50e364143e7f:
+ ;
+ case OpGeq8:
+ // match: (Geq8 x y)
+ // cond:
+ // result: (SETGE (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end983070a3db317bdb64b5a0fb104d267c
+ end983070a3db317bdb64b5a0fb104d267c:
+ ;
+ case OpGeq8U:
+ // match: (Geq8U x y)
+ // cond:
+ // result: (SETAE (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETAE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto enda617119faaccc0f0c2d23548116cf331
+ enda617119faaccc0f0c2d23548116cf331:
+ ;
+ case OpGetClosurePtr:
+ // match: (GetClosurePtr)
+ // cond:
+ // result: (LoweredGetClosurePtr)
+ {
+ v.Op = OpAMD64LoweredGetClosurePtr
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ return true
+ }
+ goto end6fd0b53f0acb4d35e7d7fa78d2ca1392
+ end6fd0b53f0acb4d35e7d7fa78d2ca1392:
+ ;
+ case OpGetG:
+ // match: (GetG)
+ // cond:
+ // result: (LoweredGetG)
+ {
+ v.Op = OpAMD64LoweredGetG
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ return true
+ }
+ goto endb17140e71dd641aa4d89e14479160260
+ endb17140e71dd641aa4d89e14479160260:
+ ;
+ case OpGoCall:
+ // match: (GoCall [argwid] mem)
+ // cond:
+ // result: (CALLgo [argwid] mem)
+ {
+ argwid := v.AuxInt
+ mem := v.Args[0]
+ v.Op = OpAMD64CALLgo
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = argwid
+ v.AddArg(mem)
+ return true
+ }
+ goto end1cef0f92c46e6aaa2c7abdf5f2794baf
+ end1cef0f92c46e6aaa2c7abdf5f2794baf:
+ ;
+ case OpGreater16:
+ // match: (Greater16 x y)
+ // cond:
+ // result: (SETG (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETG
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end4e4a1307c61240af9a86d8fe4f834ee8
+ end4e4a1307c61240af9a86d8fe4f834ee8:
+ ;
+ case OpGreater16U:
+ // match: (Greater16U x y)
+ // cond:
+ // result: (SETA (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETA
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end7c66c75f4b8ec1db593f3e60cfba9592
+ end7c66c75f4b8ec1db593f3e60cfba9592:
+ ;
+ case OpGreater32:
+ // match: (Greater32 x y)
+ // cond:
+ // result: (SETG (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETG
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end6fb0eae4a0e0e81b4afb085d398d873b
+ end6fb0eae4a0e0e81b4afb085d398d873b:
+ ;
+ case OpGreater32F:
+ // match: (Greater32F x y)
+ // cond:
+ // result: (SETGF (UCOMISS x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISS, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end94df0bd5cedad8ce8021df1b24da40c6
+ end94df0bd5cedad8ce8021df1b24da40c6:
+ ;
+ case OpGreater32U:
+ // match: (Greater32U x y)
+ // cond:
+ // result: (SETA (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETA
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end18da022a28eae8bd0771e0c948aadaf8
+ end18da022a28eae8bd0771e0c948aadaf8:
+ ;
+ case OpGreater64:
+ // match: (Greater64 x y)
+ // cond:
+ // result: (SETG (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETG
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endc025c908708f939780fba0da0c1148b4
+ endc025c908708f939780fba0da0c1148b4:
+ ;
+ case OpGreater64F:
+ // match: (Greater64F x y)
+ // cond:
+ // result: (SETGF (UCOMISD x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISD, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end033ca5181b18376e7215c02812ef5a6b
+ end033ca5181b18376e7215c02812ef5a6b:
+ ;
+ case OpGreater64U:
+ // match: (Greater64U x y)
+ // cond:
+ // result: (SETA (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETA
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endb3e25347041760a04d3fc8321c3f3d00
+ endb3e25347041760a04d3fc8321c3f3d00:
+ ;
+ case OpGreater8:
+ // match: (Greater8 x y)
+ // cond:
+ // result: (SETG (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETG
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto enda3eeb5da2e69cb54a1515601d4b360d4
+ enda3eeb5da2e69cb54a1515601d4b360d4:
+ ;
+ case OpGreater8U:
+ // match: (Greater8U x y)
+ // cond:
+ // result: (SETA (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETA
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endd2027f3b6471262f42b90c8cc0413667
+ endd2027f3b6471262f42b90c8cc0413667:
+ ;
+ case OpHmul16:
+ // match: (Hmul16 x y)
+ // cond:
+ // result: (HMULW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64HMULW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end1b9ff394bb3b06fc109637656b6875f5
+ end1b9ff394bb3b06fc109637656b6875f5:
+ ;
+ case OpHmul16u:
+ // match: (Hmul16u x y)
+ // cond:
+ // result: (HMULWU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64HMULWU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endee9089e794a43f2ce1619a6ef61670f4
+ endee9089e794a43f2ce1619a6ef61670f4:
+ ;
+ case OpHmul32:
+ // match: (Hmul32 x y)
+ // cond:
+ // result: (HMULL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64HMULL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end7c83c91ef2634f0b1da4f49350b437b1
+ end7c83c91ef2634f0b1da4f49350b437b1:
+ ;
+ case OpHmul32u:
+ // match: (Hmul32u x y)
+ // cond:
+ // result: (HMULLU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64HMULLU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end3c4f36611dc8815aa2a63d4ec0eaa06d
+ end3c4f36611dc8815aa2a63d4ec0eaa06d:
+ ;
+ case OpHmul8:
+ // match: (Hmul8 x y)
+ // cond:
+ // result: (HMULB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64HMULB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end51b2cc9f1ed15314e68fc81024f281a7
+ end51b2cc9f1ed15314e68fc81024f281a7:
+ ;
+ case OpHmul8u:
+ // match: (Hmul8u x y)
+ // cond:
+ // result: (HMULBU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64HMULBU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto ende68d7b3a3c774cedc3522af9d635c39d
+ ende68d7b3a3c774cedc3522af9d635c39d:
+ ;
+ case OpITab:
+ // match: (ITab (Load ptr mem))
+ // cond:
+ // result: (MOVQload ptr mem)
+ {
+ if v.Args[0].Op != OpLoad {
+ goto enda49fcae3630a097c78aa58189c90a97a
+ }
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[0].Args[1]
+ v.Op = OpAMD64MOVQload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto enda49fcae3630a097c78aa58189c90a97a
+ enda49fcae3630a097c78aa58189c90a97a:
+ ;
+ case OpInterCall:
+ // match: (InterCall [argwid] entry mem)
+ // cond:
+ // result: (CALLinter [argwid] entry mem)
+ {
+ argwid := v.AuxInt
+ entry := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64CALLinter
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = argwid
+ v.AddArg(entry)
+ v.AddArg(mem)
+ return true
+ }
+ goto endc04351e492ed362efc6aa75121bca305
+ endc04351e492ed362efc6aa75121bca305:
+ ;
+ case OpIsInBounds:
+ // match: (IsInBounds idx len)
+ // cond:
+ // result: (SETB (CMPQ idx len))
+ {
+ idx := v.Args[0]
+ len := v.Args[1]
+ v.Op = OpAMD64SETB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(idx)
+ v0.AddArg(len)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endfff988d5f1912886d73be3bb563c37d9
+ endfff988d5f1912886d73be3bb563c37d9:
+ ;
+ case OpIsNonNil:
+ // match: (IsNonNil p)
+ // cond:
+ // result: (SETNE (TESTQ p p))
+ {
+ p := v.Args[0]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64TESTQ, TypeInvalid)
+ v0.AddArg(p)
+ v0.AddArg(p)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end0af5ec868ede9ea73fb0602d54b863e9
+ end0af5ec868ede9ea73fb0602d54b863e9:
+ ;
+ case OpIsSliceInBounds:
+ // match: (IsSliceInBounds idx len)
+ // cond:
+ // result: (SETBE (CMPQ idx len))
+ {
+ idx := v.Args[0]
+ len := v.Args[1]
+ v.Op = OpAMD64SETBE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(idx)
+ v0.AddArg(len)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end02799ad95fe7fb5ce3c2c8ab313b737c
+ end02799ad95fe7fb5ce3c2c8ab313b737c:
+ ;
+ case OpLeq16:
+ // match: (Leq16 x y)
+ // cond:
+ // result: (SETLE (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETLE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end586c647ca6bb8ec725eea917c743d1ea
+ end586c647ca6bb8ec725eea917c743d1ea:
+ ;
+ case OpLeq16U:
+ // match: (Leq16U x y)
+ // cond:
+ // result: (SETBE (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETBE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end9c24a81bc6a4a92267bd6638362dfbfc
+ end9c24a81bc6a4a92267bd6638362dfbfc:
+ ;
+ case OpLeq32:
+ // match: (Leq32 x y)
+ // cond:
+ // result: (SETLE (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETLE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end595ee99a9fc3460b2748b9129b139f88
+ end595ee99a9fc3460b2748b9129b139f88:
+ ;
+ case OpLeq32F:
+ // match: (Leq32F x y)
+ // cond:
+ // result: (SETGEF (UCOMISS y x))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGEF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISS, TypeInvalid)
+ v0.AddArg(y)
+ v0.AddArg(x)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endfee4b989a80cc43328b24f7017e80a17
+ endfee4b989a80cc43328b24f7017e80a17:
+ ;
+ case OpLeq32U:
+ // match: (Leq32U x y)
+ // cond:
+ // result: (SETBE (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETBE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end1a59850aad6cb17c295d0dc359013420
+ end1a59850aad6cb17c295d0dc359013420:
+ ;
+ case OpLeq64:
+ // match: (Leq64 x y)
+ // cond:
+ // result: (SETLE (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETLE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end406def83fcbf29cd8fa306170b512de2
+ end406def83fcbf29cd8fa306170b512de2:
+ ;
+ case OpLeq64F:
+ // match: (Leq64F x y)
+ // cond:
+ // result: (SETGEF (UCOMISD y x))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGEF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISD, TypeInvalid)
+ v0.AddArg(y)
+ v0.AddArg(x)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end6e3de6d4b5668f673e3822d5947edbd0
+ end6e3de6d4b5668f673e3822d5947edbd0:
+ ;
+ case OpLeq64U:
+ // match: (Leq64U x y)
+ // cond:
+ // result: (SETBE (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETBE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end52f23c145b80639c8d60420ad4057bc7
+ end52f23c145b80639c8d60420ad4057bc7:
+ ;
+ case OpLeq8:
+ // match: (Leq8 x y)
+ // cond:
+ // result: (SETLE (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETLE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end72ecba6f2a7062cb266923dfec811f79
+ end72ecba6f2a7062cb266923dfec811f79:
+ ;
+ case OpLeq8U:
+ // match: (Leq8U x y)
+ // cond:
+ // result: (SETBE (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETBE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endb043b338cced4f15400d8d6e584ebea7
+ endb043b338cced4f15400d8d6e584ebea7:
+ ;
+ case OpLess16:
+ // match: (Less16 x y)
+ // cond:
+ // result: (SETL (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end2f6c6ba80eda8d68e77a58cba13d3f16
+ end2f6c6ba80eda8d68e77a58cba13d3f16:
+ ;
+ case OpLess16U:
+ // match: (Less16U x y)
+ // cond:
+ // result: (SETB (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end9f65eefe7b83a3c436b5c16664c93703
+ end9f65eefe7b83a3c436b5c16664c93703:
+ ;
+ case OpLess32:
+ // match: (Less32 x y)
+ // cond:
+ // result: (SETL (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end6632ff4ee994eb5b14cdf60c99ac3798
+ end6632ff4ee994eb5b14cdf60c99ac3798:
+ ;
+ case OpLess32F:
+ // match: (Less32F x y)
+ // cond:
+ // result: (SETGF (UCOMISS y x))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISS, TypeInvalid)
+ v0.AddArg(y)
+ v0.AddArg(x)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end5b3b0c96a7fc2ede81bc89c9abaac9d0
+ end5b3b0c96a7fc2ede81bc89c9abaac9d0:
+ ;
+ case OpLess32U:
+ // match: (Less32U x y)
+ // cond:
+ // result: (SETB (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end39e5a513c7fb0a42817a6cf9c6143b60
+ end39e5a513c7fb0a42817a6cf9c6143b60:
+ ;
+ case OpLess64:
+ // match: (Less64 x y)
+ // cond:
+ // result: (SETL (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto enddce827d3e922e8487b61a88c2b1510f2
+ enddce827d3e922e8487b61a88c2b1510f2:
+ ;
+ case OpLess64F:
+ // match: (Less64F x y)
+ // cond:
+ // result: (SETGF (UCOMISD y x))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETGF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISD, TypeInvalid)
+ v0.AddArg(y)
+ v0.AddArg(x)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endf2be3d2dcb6543d2159e7fff5ccbbb55
+ endf2be3d2dcb6543d2159e7fff5ccbbb55:
+ ;
+ case OpLess64U:
+ // match: (Less64U x y)
+ // cond:
+ // result: (SETB (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endb76d7768f175a44baf6d63d12ab6e81d
+ endb76d7768f175a44baf6d63d12ab6e81d:
+ ;
+ case OpLess8:
+ // match: (Less8 x y)
+ // cond:
+ // result: (SETL (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end314fbffe99f3bd4b07857a80c0b914cd
+ end314fbffe99f3bd4b07857a80c0b914cd:
+ ;
+ case OpLess8U:
+ // match: (Less8U x y)
+ // cond:
+ // result: (SETB (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endadccc5d80fd053a33004ed0759f64d93
+ endadccc5d80fd053a33004ed0759f64d93:
+ ;
+ case OpLoad:
+ // match: (Load <t> ptr mem)
+ // cond: (is64BitInt(t) || isPtr(t))
+ // result: (MOVQload ptr mem)
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is64BitInt(t) || isPtr(t)) {
+ goto end7c4c53acf57ebc5f03273652ba1d5934
+ }
+ v.Op = OpAMD64MOVQload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end7c4c53acf57ebc5f03273652ba1d5934
+ end7c4c53acf57ebc5f03273652ba1d5934:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: is32BitInt(t)
+ // result: (MOVLload ptr mem)
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is32BitInt(t)) {
+ goto ende1cfcb15bfbcfd448ce303d0882a4057
+ }
+ v.Op = OpAMD64MOVLload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto ende1cfcb15bfbcfd448ce303d0882a4057
+ ende1cfcb15bfbcfd448ce303d0882a4057:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: is16BitInt(t)
+ // result: (MOVWload ptr mem)
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is16BitInt(t)) {
+ goto end2d0a1304501ed9f4e9e2d288505a9c7c
+ }
+ v.Op = OpAMD64MOVWload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end2d0a1304501ed9f4e9e2d288505a9c7c
+ end2d0a1304501ed9f4e9e2d288505a9c7c:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: (t.IsBoolean() || is8BitInt(t))
+ // result: (MOVBload ptr mem)
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(t.IsBoolean() || is8BitInt(t)) {
+ goto end8f83bf72293670e75b22d6627bd13f0b
+ }
+ v.Op = OpAMD64MOVBload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end8f83bf72293670e75b22d6627bd13f0b
+ end8f83bf72293670e75b22d6627bd13f0b:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: is32BitFloat(t)
+ // result: (MOVSSload ptr mem)
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is32BitFloat(t)) {
+ goto end63383c4895805881aabceebea3c4c533
+ }
+ v.Op = OpAMD64MOVSSload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end63383c4895805881aabceebea3c4c533
+ end63383c4895805881aabceebea3c4c533:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: is64BitFloat(t)
+ // result: (MOVSDload ptr mem)
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is64BitFloat(t)) {
+ goto end99d0858c0a5bb72f0fe4decc748da812
+ }
+ v.Op = OpAMD64MOVSDload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end99d0858c0a5bb72f0fe4decc748da812
+ end99d0858c0a5bb72f0fe4decc748da812:
+ ;
+ case OpLrot16:
+ // match: (Lrot16 <t> x [c])
+ // cond:
+ // result: (ROLWconst <t> [c&15] x)
+ {
+ t := v.Type
+ x := v.Args[0]
+ c := v.AuxInt
+ v.Op = OpAMD64ROLWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AuxInt = c & 15
+ v.AddArg(x)
+ return true
+ }
+ goto endb23dfa24c619d0068f925899d53ee7fd
+ endb23dfa24c619d0068f925899d53ee7fd:
+ ;
+ case OpLrot32:
+ // match: (Lrot32 <t> x [c])
+ // cond:
+ // result: (ROLLconst <t> [c&31] x)
+ {
+ t := v.Type
+ x := v.Args[0]
+ c := v.AuxInt
+ v.Op = OpAMD64ROLLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto end38b2215c011896c36845f72ecb72b1b0
+ end38b2215c011896c36845f72ecb72b1b0:
+ ;
+ case OpLrot64:
+ // match: (Lrot64 <t> x [c])
+ // cond:
+ // result: (ROLQconst <t> [c&63] x)
+ {
+ t := v.Type
+ x := v.Args[0]
+ c := v.AuxInt
+ v.Op = OpAMD64ROLQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AuxInt = c & 63
+ v.AddArg(x)
+ return true
+ }
+ goto end5cb355e4f3ca387f252ef4f6a55f9f68
+ end5cb355e4f3ca387f252ef4f6a55f9f68:
+ ;
+ case OpLrot8:
+ // match: (Lrot8 <t> x [c])
+ // cond:
+ // result: (ROLBconst <t> [c&7] x)
+ {
+ t := v.Type
+ x := v.Args[0]
+ c := v.AuxInt
+ v.Op = OpAMD64ROLBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AuxInt = c & 7
+ v.AddArg(x)
+ return true
+ }
+ goto end26bfb3dd5b537cf13ac9f2978d94ed71
+ end26bfb3dd5b537cf13ac9f2978d94ed71:
+ ;
+ case OpLsh16x16:
+ // match: (Lsh16x16 <t> x y)
+ // cond:
+ // result: (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPWconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end7ffc4f31c526f7fcb2283215b458f589
+ end7ffc4f31c526f7fcb2283215b458f589:
+ ;
+ case OpLsh16x32:
+ // match: (Lsh16x32 <t> x y)
+ // cond:
+ // result: (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPLconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto enddcc0e751d315967423c99518c0cc065e
+ enddcc0e751d315967423c99518c0cc065e:
+ ;
+ case OpLsh16x64:
+ // match: (Lsh16x64 <t> x y)
+ // cond:
+ // result: (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPQconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto endf6368b59d046ca83050cd75fbe8715d2
+ endf6368b59d046ca83050cd75fbe8715d2:
+ ;
+ case OpLsh16x8:
+ // match: (Lsh16x8 <t> x y)
+ // cond:
+ // result: (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPBconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end8730d944c8fb358001ba2d165755bdc4
+ end8730d944c8fb358001ba2d165755bdc4:
+ ;
+ case OpLsh32x16:
+ // match: (Lsh32x16 <t> x y)
+ // cond:
+ // result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end5a43b7e9b0780e62f622bac0a68524d2
+ end5a43b7e9b0780e62f622bac0a68524d2:
+ ;
+ case OpLsh32x32:
+ // match: (Lsh32x32 <t> x y)
+ // cond:
+ // result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end9ce0ab6f9095c24ea46ca8fe2d7e5507
+ end9ce0ab6f9095c24ea46ca8fe2d7e5507:
+ ;
+ case OpLsh32x64:
+ // match: (Lsh32x64 <t> x y)
+ // cond:
+ // result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end646b5471b709d5ea6c21f49a2815236f
+ end646b5471b709d5ea6c21f49a2815236f:
+ ;
+ case OpLsh32x8:
+ // match: (Lsh32x8 <t> x y)
+ // cond:
+ // result: (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end96a677c71370e7c9179125f92cbdfda8
+ end96a677c71370e7c9179125f92cbdfda8:
+ ;
+ case OpLsh64x16:
+ // match: (Lsh64x16 <t> x y)
+ // cond:
+ // result: (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPWconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end5f88f241d68d38954222d81559cd7f9f
+ end5f88f241d68d38954222d81559cd7f9f:
+ ;
+ case OpLsh64x32:
+ // match: (Lsh64x32 <t> x y)
+ // cond:
+ // result: (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPLconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto endae1705f03ed3d6f43cd63b53496a910a
+ endae1705f03ed3d6f43cd63b53496a910a:
+ ;
+ case OpLsh64x64:
+ // match: (Lsh64x64 <t> x y)
+ // cond:
+ // result: (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPQconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end1f6f5f510c5c68e4ce4a78643e6d85a1
+ end1f6f5f510c5c68e4ce4a78643e6d85a1:
+ ;
+ case OpLsh64x8:
+ // match: (Lsh64x8 <t> x y)
+ // cond:
+ // result: (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMPBconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto endd14f5c89e3496b0e425aa1ae366f4b53
+ endd14f5c89e3496b0e425aa1ae366f4b53:
+ ;
+ case OpLsh8x16:
+ // match: (Lsh8x16 <t> x y)
+ // cond:
+ // result: (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPWconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end0926c3d8b9a0776ba5058946f6e1a4b7
+ end0926c3d8b9a0776ba5058946f6e1a4b7:
+ ;
+ case OpLsh8x32:
+ // match: (Lsh8x32 <t> x y)
+ // cond:
+ // result: (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPLconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end5987682d77f197ef0fd95251f413535a
+ end5987682d77f197ef0fd95251f413535a:
+ ;
+ case OpLsh8x64:
+ // match: (Lsh8x64 <t> x y)
+ // cond:
+ // result: (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPQconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end9ffe6731d7d6514b8c0482f1645eee18
+ end9ffe6731d7d6514b8c0482f1645eee18:
+ ;
+ case OpLsh8x8:
+ // match: (Lsh8x8 <t> x y)
+ // cond:
+ // result: (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPBconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHLB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end2b75242a31c3713ffbfdd8f0288b1c12
+ end2b75242a31c3713ffbfdd8f0288b1c12:
+ ;
+ case OpAMD64MOVBQSX:
+ // match: (MOVBQSX (MOVBload [off] {sym} ptr mem))
+ // cond:
+ // result: @v.Args[0].Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+ {
+ if v.Args[0].Op != OpAMD64MOVBload {
+ goto end19c38f3a1a37dca50637c917fa26e4f7
+ }
+ off := v.Args[0].AuxInt
+ sym := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[0].Args[1]
+ v0 := v.Args[0].Block.NewValue0(v.Line, OpAMD64MOVBQSXload, TypeInvalid)
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(v0)
+ v0.Type = v.Type
+ v0.AuxInt = off
+ v0.Aux = sym
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
+ return true
+ }
+ goto end19c38f3a1a37dca50637c917fa26e4f7
+ end19c38f3a1a37dca50637c917fa26e4f7:
+ ;
+ case OpAMD64MOVBQZX:
+ // match: (MOVBQZX (MOVBload [off] {sym} ptr mem))
+ // cond:
+ // result: @v.Args[0].Block (MOVBQZXload <v.Type> [off] {sym} ptr mem)
+ {
+ if v.Args[0].Op != OpAMD64MOVBload {
+ goto end1169bcf3d56fa24321b002eaebd5a62d
+ }
+ off := v.Args[0].AuxInt
+ sym := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[0].Args[1]
+ v0 := v.Args[0].Block.NewValue0(v.Line, OpAMD64MOVBQZXload, TypeInvalid)
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(v0)
+ v0.Type = v.Type
+ v0.AuxInt = off
+ v0.Aux = sym
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
+ return true
+ }
+ goto end1169bcf3d56fa24321b002eaebd5a62d
+ end1169bcf3d56fa24321b002eaebd5a62d:
+ ;
+ case OpAMD64MOVBload:
+ // match: (MOVBload [off1] {sym} (ADDQconst [off2] ptr) mem)
+ // cond:
+ // result: (MOVBload [addOff(off1, off2)] {sym} ptr mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end7ec9147ab863c1bd59190fed81f894b6
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVBload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end7ec9147ab863c1bd59190fed81f894b6
+ end7ec9147ab863c1bd59190fed81f894b6:
+ ;
+ // match: (MOVBload [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVBload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end3771a59cf66b0df99120d76f4c358fab
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end3771a59cf66b0df99120d76f4c358fab
+ }
+ v.Op = OpAMD64MOVBload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(mem)
+ return true
+ }
+ goto end3771a59cf66b0df99120d76f4c358fab
+ end3771a59cf66b0df99120d76f4c358fab:
+ ;
+ case OpAMD64MOVBstore:
+ // match: (MOVBstore [off] {sym} ptr (MOVBQSX x) mem)
+ // cond:
+ // result: (MOVBstore [off] {sym} ptr x mem)
+ {
+ off := v.AuxInt
+ sym := v.Aux
+ ptr := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBQSX {
+ goto end5b3f41f0770d566ff1647dea1d4a40e8
+ }
+ x := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
+ goto end5b3f41f0770d566ff1647dea1d4a40e8
+ end5b3f41f0770d566ff1647dea1d4a40e8:
+ ;
+ // match: (MOVBstore [off] {sym} ptr (MOVBQZX x) mem)
+ // cond:
+ // result: (MOVBstore [off] {sym} ptr x mem)
+ {
+ off := v.AuxInt
+ sym := v.Aux
+ ptr := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBQZX {
+ goto end3a2e55db7e03920700c4875f6a55de3b
+ }
+ x := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
+ goto end3a2e55db7e03920700c4875f6a55de3b
+ end3a2e55db7e03920700c4875f6a55de3b:
+ ;
+ // match: (MOVBstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
+ // cond:
+ // result: (MOVBstore [addOff(off1, off2)] {sym} ptr val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto ende6347ac19d0469ee59d2e7f2e18d1070
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto ende6347ac19d0469ee59d2e7f2e18d1070
+ ende6347ac19d0469ee59d2e7f2e18d1070:
+ ;
+ // match: (MOVBstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVBstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto enda7086cf7f6b8cf81972e2c3d4b12f3fc
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto enda7086cf7f6b8cf81972e2c3d4b12f3fc
+ }
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto enda7086cf7f6b8cf81972e2c3d4b12f3fc
+ enda7086cf7f6b8cf81972e2c3d4b12f3fc:
+ ;
+ case OpAMD64MOVLload:
+ // match: (MOVLload [off1] {sym} (ADDQconst [off2] ptr) mem)
+ // cond:
+ // result: (MOVLload [addOff(off1, off2)] {sym} ptr mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end0c8b8a40360c5c581d92723eca04d340
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVLload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end0c8b8a40360c5c581d92723eca04d340
+ end0c8b8a40360c5c581d92723eca04d340:
+ ;
+ // match: (MOVLload [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVLload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto enddb9e59335876d8a565c425731438a1b3
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto enddb9e59335876d8a565c425731438a1b3
+ }
+ v.Op = OpAMD64MOVLload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(mem)
+ return true
+ }
+ goto enddb9e59335876d8a565c425731438a1b3
+ enddb9e59335876d8a565c425731438a1b3:
+ ;
+ case OpAMD64MOVLstore:
+ // match: (MOVLstore [off] {sym} ptr (MOVLQSX x) mem)
+ // cond:
+ // result: (MOVLstore [off] {sym} ptr x mem)
+ {
+ off := v.AuxInt
+ sym := v.Aux
+ ptr := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLQSX {
+ goto end1fb7b2ae707c76d30927c21f85d77472
+ }
+ x := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
+ goto end1fb7b2ae707c76d30927c21f85d77472
+ end1fb7b2ae707c76d30927c21f85d77472:
+ ;
+ // match: (MOVLstore [off] {sym} ptr (MOVLQZX x) mem)
+ // cond:
+ // result: (MOVLstore [off] {sym} ptr x mem)
+ {
+ off := v.AuxInt
+ sym := v.Aux
+ ptr := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLQZX {
+ goto end199e8c23a5e7e99728a43d6a83b2c2cf
+ }
+ x := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
+ goto end199e8c23a5e7e99728a43d6a83b2c2cf
+ end199e8c23a5e7e99728a43d6a83b2c2cf:
+ ;
+ // match: (MOVLstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
+ // cond:
+ // result: (MOVLstore [addOff(off1, off2)] {sym} ptr val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end43bffdb8d9c1fc85a95778d4911955f1
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end43bffdb8d9c1fc85a95778d4911955f1
+ end43bffdb8d9c1fc85a95778d4911955f1:
+ ;
+ // match: (MOVLstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVLstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto endd57b1e4313fc7a3331340a9af00ba116
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto endd57b1e4313fc7a3331340a9af00ba116
+ }
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endd57b1e4313fc7a3331340a9af00ba116
+ endd57b1e4313fc7a3331340a9af00ba116:
+ ;
+ case OpAMD64MOVQload:
+ // match: (MOVQload [off1] {sym} (ADDQconst [off2] ptr) mem)
+ // cond:
+ // result: (MOVQload [addOff(off1, off2)] {sym} ptr mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end0b8c50dd7faefb7d046f9a27e054df77
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVQload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end0b8c50dd7faefb7d046f9a27e054df77
+ end0b8c50dd7faefb7d046f9a27e054df77:
+ ;
+ // match: (MOVQload [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVQload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto endd0c093adc4f05f2037005734c77d3cc4
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto endd0c093adc4f05f2037005734c77d3cc4
+ }
+ v.Op = OpAMD64MOVQload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(mem)
+ return true
+ }
+ goto endd0c093adc4f05f2037005734c77d3cc4
+ endd0c093adc4f05f2037005734c77d3cc4:
+ ;
+ // match: (MOVQload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVQloadidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ8 {
+ goto end74a50d810fb3945e809f608cd094a59c
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[0].Args[1]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end74a50d810fb3945e809f608cd094a59c
+ }
+ v.Op = OpAMD64MOVQloadidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(mem)
+ return true
+ }
+ goto end74a50d810fb3945e809f608cd094a59c
+ end74a50d810fb3945e809f608cd094a59c:
+ ;
+ case OpAMD64MOVQloadidx8:
+ // match: (MOVQloadidx8 [off1] {sym} (ADDQconst [off2] ptr) idx mem)
+ // cond:
+ // result: (MOVQloadidx8 [addOff(off1, off2)] {sym} ptr idx mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto endb138bf9b0b33ec824bf0aff619f8bafa
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVQloadidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(mem)
+ return true
+ }
+ goto endb138bf9b0b33ec824bf0aff619f8bafa
+ endb138bf9b0b33ec824bf0aff619f8bafa:
+ ;
+ case OpAMD64MOVQstore:
+ // match: (MOVQstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
+ // cond:
+ // result: (MOVQstore [addOff(off1, off2)] {sym} ptr val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end0a110b5e42a4576c32fda50590092848
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end0a110b5e42a4576c32fda50590092848
+ end0a110b5e42a4576c32fda50590092848:
+ ;
+ // match: (MOVQstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVQstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end9a0cfe20b3b0f587e252760907c1b5c0
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end9a0cfe20b3b0f587e252760907c1b5c0
+ }
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end9a0cfe20b3b0f587e252760907c1b5c0
+ end9a0cfe20b3b0f587e252760907c1b5c0:
+ ;
+ // match: (MOVQstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVQstoreidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ8 {
+ goto end442c322e6719e280b6be1c12858e49d7
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[0].Args[1]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end442c322e6719e280b6be1c12858e49d7
+ }
+ v.Op = OpAMD64MOVQstoreidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end442c322e6719e280b6be1c12858e49d7
+ end442c322e6719e280b6be1c12858e49d7:
+ ;
+ case OpAMD64MOVQstoreidx8:
+ // match: (MOVQstoreidx8 [off1] {sym} (ADDQconst [off2] ptr) idx val mem)
+ // cond:
+ // result: (MOVQstoreidx8 [addOff(off1, off2)] {sym} ptr idx val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end50671766fdab364c1edbd2072fb8e525
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[1]
+ val := v.Args[2]
+ mem := v.Args[3]
+ v.Op = OpAMD64MOVQstoreidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end50671766fdab364c1edbd2072fb8e525
+ end50671766fdab364c1edbd2072fb8e525:
+ ;
+ case OpAMD64MOVSDload:
+ // match: (MOVSDload [off1] {sym} (ADDQconst [off2] ptr) mem)
+ // cond:
+ // result: (MOVSDload [addOff(off1, off2)] {sym} ptr mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end6dad9bf78e7368bb095eb2dfba7e244a
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVSDload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end6dad9bf78e7368bb095eb2dfba7e244a
+ end6dad9bf78e7368bb095eb2dfba7e244a:
+ ;
+ // match: (MOVSDload [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSDload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end96fa9c439e31050aa91582bc2a9f2c20
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end96fa9c439e31050aa91582bc2a9f2c20
+ }
+ v.Op = OpAMD64MOVSDload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(mem)
+ return true
+ }
+ goto end96fa9c439e31050aa91582bc2a9f2c20
+ end96fa9c439e31050aa91582bc2a9f2c20:
+ ;
+ // match: (MOVSDload [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSDloadidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ8 {
+ goto endbcb2ce441824d0e3a4b501018cfa7f60
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[0].Args[1]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto endbcb2ce441824d0e3a4b501018cfa7f60
+ }
+ v.Op = OpAMD64MOVSDloadidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(mem)
+ return true
+ }
+ goto endbcb2ce441824d0e3a4b501018cfa7f60
+ endbcb2ce441824d0e3a4b501018cfa7f60:
+ ;
+ case OpAMD64MOVSDloadidx8:
+ // match: (MOVSDloadidx8 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx mem)
+ // cond:
+ // result: (MOVSDloadidx8 [addOff(off1, off2)] {sym} ptr idx mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end84f0f457e271104a92343e3b1d2804c6
+ }
+ off2 := v.Args[0].AuxInt
+ if v.Args[0].Aux != v.Aux {
+ goto end84f0f457e271104a92343e3b1d2804c6
+ }
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVSDloadidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(mem)
+ return true
+ }
+ goto end84f0f457e271104a92343e3b1d2804c6
+ end84f0f457e271104a92343e3b1d2804c6:
+ ;
+ case OpAMD64MOVSDstore:
+ // match: (MOVSDstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
+ // cond:
+ // result: (MOVSDstore [addOff(off1, off2)] {sym} ptr val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end6c6160664143cc66e63e67b9aa43a7ef
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVSDstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end6c6160664143cc66e63e67b9aa43a7ef
+ end6c6160664143cc66e63e67b9aa43a7ef:
+ ;
+ // match: (MOVSDstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSDstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end415dde14f3400bec1b2756174a5d7179
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end415dde14f3400bec1b2756174a5d7179
+ }
+ v.Op = OpAMD64MOVSDstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end415dde14f3400bec1b2756174a5d7179
+ end415dde14f3400bec1b2756174a5d7179:
+ ;
+ // match: (MOVSDstore [off1] {sym1} (LEAQ8 [off2] {sym2} ptr idx) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSDstoreidx8 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ8 {
+ goto end1ad6fc0c5b59610dabf7f9595a48a230
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[0].Args[1]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end1ad6fc0c5b59610dabf7f9595a48a230
+ }
+ v.Op = OpAMD64MOVSDstoreidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end1ad6fc0c5b59610dabf7f9595a48a230
+ end1ad6fc0c5b59610dabf7f9595a48a230:
+ ;
+ case OpAMD64MOVSDstoreidx8:
+ // match: (MOVSDstoreidx8 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx val mem)
+ // cond:
+ // result: (MOVSDstoreidx8 [addOff(off1, off2)] {sym} ptr idx val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto endc0e28f57697cb6038d5d09eafe26c947
+ }
+ off2 := v.Args[0].AuxInt
+ if v.Args[0].Aux != v.Aux {
+ goto endc0e28f57697cb6038d5d09eafe26c947
+ }
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[1]
+ val := v.Args[2]
+ mem := v.Args[3]
+ v.Op = OpAMD64MOVSDstoreidx8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endc0e28f57697cb6038d5d09eafe26c947
+ endc0e28f57697cb6038d5d09eafe26c947:
+ ;
+ case OpAMD64MOVSSload:
+ // match: (MOVSSload [off1] {sym} (ADDQconst [off2] ptr) mem)
+ // cond:
+ // result: (MOVSSload [addOff(off1, off2)] {sym} ptr mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end96d63dbb64b0adfa944684c9e939c972
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVSSload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto end96d63dbb64b0adfa944684c9e939c972
+ end96d63dbb64b0adfa944684c9e939c972:
+ ;
+ // match: (MOVSSload [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSSload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end15f2583bd72ad7fc077b3952634a1c85
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end15f2583bd72ad7fc077b3952634a1c85
+ }
+ v.Op = OpAMD64MOVSSload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(mem)
+ return true
+ }
+ goto end15f2583bd72ad7fc077b3952634a1c85
+ end15f2583bd72ad7fc077b3952634a1c85:
+ ;
+ // match: (MOVSSload [off1] {sym1} (LEAQ4 [off2] {sym2} ptr idx) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSSloadidx4 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ4 {
+ goto end49722f4a0adba31bb143601ce1d2aae0
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[0].Args[1]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end49722f4a0adba31bb143601ce1d2aae0
+ }
+ v.Op = OpAMD64MOVSSloadidx4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(mem)
+ return true
+ }
+ goto end49722f4a0adba31bb143601ce1d2aae0
+ end49722f4a0adba31bb143601ce1d2aae0:
+ ;
+ case OpAMD64MOVSSloadidx4:
+ // match: (MOVSSloadidx4 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx mem)
+ // cond:
+ // result: (MOVSSloadidx4 [addOff(off1, off2)] {sym} ptr idx mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end7eb5a1ab1e2508683d879ec25286754b
+ }
+ off2 := v.Args[0].AuxInt
+ if v.Args[0].Aux != v.Aux {
+ goto end7eb5a1ab1e2508683d879ec25286754b
+ }
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVSSloadidx4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(mem)
+ return true
+ }
+ goto end7eb5a1ab1e2508683d879ec25286754b
+ end7eb5a1ab1e2508683d879ec25286754b:
+ ;
+ case OpAMD64MOVSSstore:
+ // match: (MOVSSstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
+ // cond:
+ // result: (MOVSSstore [addOff(off1, off2)] {sym} ptr val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto endf711aa4081a9b2924b55387d4f70cfd6
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVSSstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endf711aa4081a9b2924b55387d4f70cfd6
+ endf711aa4081a9b2924b55387d4f70cfd6:
+ ;
+ // match: (MOVSSstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSSstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end70ebc170131920e515e3f416a6b952c5
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end70ebc170131920e515e3f416a6b952c5
+ }
+ v.Op = OpAMD64MOVSSstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end70ebc170131920e515e3f416a6b952c5
+ end70ebc170131920e515e3f416a6b952c5:
+ ;
+ // match: (MOVSSstore [off1] {sym1} (LEAQ4 [off2] {sym2} ptr idx) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVSSstoreidx4 [addOff(off1, off2)] {mergeSym(sym1,sym2)} ptr idx val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ4 {
+ goto end1622dc435e45833eda4d29d44df7cc34
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[0].Args[1]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end1622dc435e45833eda4d29d44df7cc34
+ }
+ v.Op = OpAMD64MOVSSstoreidx4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end1622dc435e45833eda4d29d44df7cc34
+ end1622dc435e45833eda4d29d44df7cc34:
+ ;
+ case OpAMD64MOVSSstoreidx4:
+ // match: (MOVSSstoreidx4 [off1] {sym} (ADDQconst [off2] {sym} ptr) idx val mem)
+ // cond:
+ // result: (MOVSSstoreidx4 [addOff(off1, off2)] {sym} ptr idx val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto end66e4853026306cd46f414c22d281254f
+ }
+ off2 := v.Args[0].AuxInt
+ if v.Args[0].Aux != v.Aux {
+ goto end66e4853026306cd46f414c22d281254f
+ }
+ ptr := v.Args[0].Args[0]
+ idx := v.Args[1]
+ val := v.Args[2]
+ mem := v.Args[3]
+ v.Op = OpAMD64MOVSSstoreidx4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(idx)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end66e4853026306cd46f414c22d281254f
+ end66e4853026306cd46f414c22d281254f:
+ ;
+ case OpAMD64MOVWload:
+ // match: (MOVWload [off1] {sym} (ADDQconst [off2] ptr) mem)
+ // cond:
+ // result: (MOVWload [addOff(off1, off2)] {sym} ptr mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto endfcb0ce76f96e8b0c2eb19a9b827c1b73
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVWload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto endfcb0ce76f96e8b0c2eb19a9b827c1b73
+ endfcb0ce76f96e8b0c2eb19a9b827c1b73:
+ ;
+ // match: (MOVWload [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVWload [addOff(off1,off2)] {mergeSym(sym1,sym2)} base mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end7a79314cb49bf53d79c38c3077d87457
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ mem := v.Args[1]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end7a79314cb49bf53d79c38c3077d87457
+ }
+ v.Op = OpAMD64MOVWload
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(mem)
+ return true
+ }
+ goto end7a79314cb49bf53d79c38c3077d87457
+ end7a79314cb49bf53d79c38c3077d87457:
+ ;
+ case OpAMD64MOVWstore:
+ // match: (MOVWstore [off] {sym} ptr (MOVWQSX x) mem)
+ // cond:
+ // result: (MOVWstore [off] {sym} ptr x mem)
+ {
+ off := v.AuxInt
+ sym := v.Aux
+ ptr := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWQSX {
+ goto endca90c534e75c7f5cb803504d119a853f
+ }
+ x := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
+ goto endca90c534e75c7f5cb803504d119a853f
+ endca90c534e75c7f5cb803504d119a853f:
+ ;
+ // match: (MOVWstore [off] {sym} ptr (MOVWQZX x) mem)
+ // cond:
+ // result: (MOVWstore [off] {sym} ptr x mem)
+ {
+ off := v.AuxInt
+ sym := v.Aux
+ ptr := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWQZX {
+ goto end187fe73dfaf9cf5f4c349283b4dfd9d1
+ }
+ x := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(x)
+ v.AddArg(mem)
+ return true
+ }
+ goto end187fe73dfaf9cf5f4c349283b4dfd9d1
+ end187fe73dfaf9cf5f4c349283b4dfd9d1:
+ ;
+ // match: (MOVWstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
+ // cond:
+ // result: (MOVWstore [addOff(off1, off2)] {sym} ptr val mem)
+ {
+ off1 := v.AuxInt
+ sym := v.Aux
+ if v.Args[0].Op != OpAMD64ADDQconst {
+ goto endda15fdd59aa956ded0440188f38de1aa
+ }
+ off2 := v.Args[0].AuxInt
+ ptr := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = sym
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endda15fdd59aa956ded0440188f38de1aa
+ endda15fdd59aa956ded0440188f38de1aa:
+ ;
+ // match: (MOVWstore [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+ // cond: canMergeSym(sym1, sym2)
+ // result: (MOVWstore [addOff(off1,off2)] {mergeSym(sym1,sym2)} base val mem)
+ {
+ off1 := v.AuxInt
+ sym1 := v.Aux
+ if v.Args[0].Op != OpAMD64LEAQ {
+ goto end4cc466ede8e64e415c899ccac81c0f27
+ }
+ off2 := v.Args[0].AuxInt
+ sym2 := v.Args[0].Aux
+ base := v.Args[0].Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(canMergeSym(sym1, sym2)) {
+ goto end4cc466ede8e64e415c899ccac81c0f27
+ }
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = addOff(off1, off2)
+ v.Aux = mergeSym(sym1, sym2)
+ v.AddArg(base)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end4cc466ede8e64e415c899ccac81c0f27
+ end4cc466ede8e64e415c899ccac81c0f27:
+ ;
+ case OpAMD64MULB:
+ // match: (MULB x (MOVBconst [c]))
+ // cond:
+ // result: (MULBconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto end66c6419213ddeb52b1c53fb589a70e5f
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64MULBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end66c6419213ddeb52b1c53fb589a70e5f
+ end66c6419213ddeb52b1c53fb589a70e5f:
+ ;
+ // match: (MULB (MOVBconst [c]) x)
+ // cond:
+ // result: (MULBconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end7e82c8dbbba265b78035ca7df394bb06
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64MULBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end7e82c8dbbba265b78035ca7df394bb06
+ end7e82c8dbbba265b78035ca7df394bb06:
+ ;
+ case OpAMD64MULBconst:
+ // match: (MULBconst [c] (MOVBconst [d]))
+ // cond:
+ // result: (MOVBconst [c*d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto endf2db9f96016085f8cb4082b4af01b2aa
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c * d
+ return true
+ }
+ goto endf2db9f96016085f8cb4082b4af01b2aa
+ endf2db9f96016085f8cb4082b4af01b2aa:
+ ;
+ case OpAMD64MULL:
+ // match: (MULL x (MOVLconst [c]))
+ // cond:
+ // result: (MULLconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end893477a261bcad6c2821b77c83075c6c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64MULLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end893477a261bcad6c2821b77c83075c6c
+ end893477a261bcad6c2821b77c83075c6c:
+ ;
+ // match: (MULL (MOVLconst [c]) x)
+ // cond:
+ // result: (MULLconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end8a0f957c528a54eecb0dbfc5d96e017a
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64MULLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end8a0f957c528a54eecb0dbfc5d96e017a
+ end8a0f957c528a54eecb0dbfc5d96e017a:
+ ;
+ case OpAMD64MULLconst:
+ // match: (MULLconst [c] (MOVLconst [d]))
+ // cond:
+ // result: (MOVLconst [c*d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto endd5732835ed1276ef8b728bcfc1289f73
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c * d
+ return true
+ }
+ goto endd5732835ed1276ef8b728bcfc1289f73
+ endd5732835ed1276ef8b728bcfc1289f73:
+ ;
+ case OpAMD64MULQ:
+ // match: (MULQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (MULQconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto endb38c6e3e0ddfa25ba0ef9684ac1528c0
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto endb38c6e3e0ddfa25ba0ef9684ac1528c0
+ }
+ v.Op = OpAMD64MULQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endb38c6e3e0ddfa25ba0ef9684ac1528c0
+ endb38c6e3e0ddfa25ba0ef9684ac1528c0:
+ ;
+ // match: (MULQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (MULQconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end9cb4f29b0bd7141639416735dcbb3b87
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto end9cb4f29b0bd7141639416735dcbb3b87
+ }
+ v.Op = OpAMD64MULQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end9cb4f29b0bd7141639416735dcbb3b87
+ end9cb4f29b0bd7141639416735dcbb3b87:
+ ;
+ case OpAMD64MULQconst:
+ // match: (MULQconst [-1] x)
+ // cond:
+ // result: (NEGQ x)
+ {
+ if v.AuxInt != -1 {
+ goto end82501cca6b5fb121a7f8b197e55f2fec
+ }
+ x := v.Args[0]
+ v.Op = OpAMD64NEGQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end82501cca6b5fb121a7f8b197e55f2fec
+ end82501cca6b5fb121a7f8b197e55f2fec:
+ ;
+ // match: (MULQconst [0] _)
+ // cond:
+ // result: (MOVQconst [0])
+ {
+ if v.AuxInt != 0 {
+ goto endcb9faa068e3558ff44daaf1d47d091b5
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto endcb9faa068e3558ff44daaf1d47d091b5
+ endcb9faa068e3558ff44daaf1d47d091b5:
+ ;
+ // match: (MULQconst [1] x)
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 1 {
+ goto end0b527e71db2b288b2841a1f757aa580d
+ }
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end0b527e71db2b288b2841a1f757aa580d
+ end0b527e71db2b288b2841a1f757aa580d:
+ ;
+ // match: (MULQconst [3] x)
+ // cond:
+ // result: (LEAQ2 x x)
+ {
+ if v.AuxInt != 3 {
+ goto end34a86f261671b5852bec6c57155fe0da
+ }
+ x := v.Args[0]
+ v.Op = OpAMD64LEAQ2
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(x)
+ return true
+ }
+ goto end34a86f261671b5852bec6c57155fe0da
+ end34a86f261671b5852bec6c57155fe0da:
+ ;
+ // match: (MULQconst [5] x)
+ // cond:
+ // result: (LEAQ4 x x)
+ {
+ if v.AuxInt != 5 {
+ goto end534601906c45a9171a9fec3e4b82b189
+ }
+ x := v.Args[0]
+ v.Op = OpAMD64LEAQ4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(x)
+ return true
+ }
+ goto end534601906c45a9171a9fec3e4b82b189
+ end534601906c45a9171a9fec3e4b82b189:
+ ;
+ // match: (MULQconst [9] x)
+ // cond:
+ // result: (LEAQ8 x x)
+ {
+ if v.AuxInt != 9 {
+ goto end48a2280b6459821289c56073b8354997
+ }
+ x := v.Args[0]
+ v.Op = OpAMD64LEAQ8
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(x)
+ return true
+ }
+ goto end48a2280b6459821289c56073b8354997
+ end48a2280b6459821289c56073b8354997:
+ ;
+ // match: (MULQconst [c] x)
+ // cond: isPowerOfTwo(c)
+ // result: (SHLQconst [log2(c)] x)
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(isPowerOfTwo(c)) {
+ goto end75076953dbfe022526a153eda99b39b2
+ }
+ v.Op = OpAMD64SHLQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = log2(c)
+ v.AddArg(x)
+ return true
+ }
+ goto end75076953dbfe022526a153eda99b39b2
+ end75076953dbfe022526a153eda99b39b2:
+ ;
+ // match: (MULQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [c*d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end55c38c5c405101e610d7ba7fc702ddc0
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c * d
+ return true
+ }
+ goto end55c38c5c405101e610d7ba7fc702ddc0
+ end55c38c5c405101e610d7ba7fc702ddc0:
+ ;
+ case OpAMD64MULW:
+ // match: (MULW x (MOVWconst [c]))
+ // cond:
+ // result: (MULWconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto end542112cc08217d4bdffc1a645d290ffb
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64MULWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end542112cc08217d4bdffc1a645d290ffb
+ end542112cc08217d4bdffc1a645d290ffb:
+ ;
+ // match: (MULW (MOVWconst [c]) x)
+ // cond:
+ // result: (MULWconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto endd97b4245ced2b3d27d8c555b06281de4
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64MULWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endd97b4245ced2b3d27d8c555b06281de4
+ endd97b4245ced2b3d27d8c555b06281de4:
+ ;
+ case OpAMD64MULWconst:
+ // match: (MULWconst [c] (MOVWconst [d]))
+ // cond:
+ // result: (MOVWconst [c*d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end61dbc9d9e93dd6946a20a1f475b3f74b
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c * d
+ return true
+ }
+ goto end61dbc9d9e93dd6946a20a1f475b3f74b
+ end61dbc9d9e93dd6946a20a1f475b3f74b:
+ ;
+ case OpMod16:
+ // match: (Mod16 x y)
+ // cond:
+ // result: (MODW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end036bac694be9fe0d6b00b86c2e625990
+ end036bac694be9fe0d6b00b86c2e625990:
+ ;
+ case OpMod16u:
+ // match: (Mod16u x y)
+ // cond:
+ // result: (MODWU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODWU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto enda75d900097f1510ca1c6df786bef0c24
+ enda75d900097f1510ca1c6df786bef0c24:
+ ;
+ case OpMod32:
+ // match: (Mod32 x y)
+ // cond:
+ // result: (MODL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end12c8c0ecf3296810b8217cd4e40f7707
+ end12c8c0ecf3296810b8217cd4e40f7707:
+ ;
+ case OpMod32u:
+ // match: (Mod32u x y)
+ // cond:
+ // result: (MODLU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODLU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end1f0892076cfd58733a08d3ab175a3c1c
+ end1f0892076cfd58733a08d3ab175a3c1c:
+ ;
+ case OpMod64:
+ // match: (Mod64 x y)
+ // cond:
+ // result: (MODQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endaae75f449baf5dc108be4e0439af97f2
+ endaae75f449baf5dc108be4e0439af97f2:
+ ;
+ case OpMod64u:
+ // match: (Mod64u x y)
+ // cond:
+ // result: (MODQU x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODQU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end0d4c8b9df77e59289fb14e2496559d1d
+ end0d4c8b9df77e59289fb14e2496559d1d:
+ ;
+ case OpMod8:
+ // match: (Mod8 x y)
+ // cond:
+ // result: (MODW (SignExt8to16 x) (SignExt8to16 y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpSignExt8to16, TypeInvalid)
+ v0.AddArg(x)
+ v0.Type = config.fe.TypeInt16()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpSignExt8to16, TypeInvalid)
+ v1.AddArg(y)
+ v1.Type = config.fe.TypeInt16()
+ v.AddArg(v1)
+ return true
+ }
+ goto endf959fc16e72bc6dc47ab7c9ee3778901
+ endf959fc16e72bc6dc47ab7c9ee3778901:
+ ;
+ case OpMod8u:
+ // match: (Mod8u x y)
+ // cond:
+ // result: (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MODWU
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpZeroExt8to16, TypeInvalid)
+ v0.AddArg(x)
+ v0.Type = config.fe.TypeUInt16()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpZeroExt8to16, TypeInvalid)
+ v1.AddArg(y)
+ v1.Type = config.fe.TypeUInt16()
+ v.AddArg(v1)
+ return true
+ }
+ goto end9b3274d9dd7f1e91c75ce5e7b548fe97
+ end9b3274d9dd7f1e91c75ce5e7b548fe97:
+ ;
+ case OpMove:
+ // match: (Move [size] dst src mem)
+ // cond:
+ // result: (REPMOVSB dst src (MOVQconst <config.Frontend().TypeUInt64()> [size]) mem)
+ {
+ size := v.AuxInt
+ dst := v.Args[0]
+ src := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64REPMOVSB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(dst)
+ v.AddArg(src)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v0.Type = config.Frontend().TypeUInt64()
+ v0.AuxInt = size
+ v.AddArg(v0)
+ v.AddArg(mem)
+ return true
+ }
+ goto end4dd156b33beb9981378c91e46f055a56
+ end4dd156b33beb9981378c91e46f055a56:
+ ;
+ case OpMul16:
+ // match: (Mul16 x y)
+ // cond:
+ // result: (MULW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end1addf5ea2c885aa1729b8f944859d00c
+ end1addf5ea2c885aa1729b8f944859d00c:
+ ;
+ case OpMul32:
+ // match: (Mul32 x y)
+ // cond:
+ // result: (MULL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto ende144381f85808e5144782804768e2859
+ ende144381f85808e5144782804768e2859:
+ ;
+ case OpMul32F:
+ // match: (Mul32F x y)
+ // cond:
+ // result: (MULSS x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULSS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end32105a3bfe0237b799b69d83b3f171ca
+ end32105a3bfe0237b799b69d83b3f171ca:
+ ;
+ case OpMul64:
+ // match: (Mul64 x y)
+ // cond:
+ // result: (MULQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end38da21e77ac329eb643b20e7d97d5853
+ end38da21e77ac329eb643b20e7d97d5853:
+ ;
+ case OpMul64F:
+ // match: (Mul64F x y)
+ // cond:
+ // result: (MULSD x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULSD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end0ff6e1919fb0a3e549eb82b43edf1f52
+ end0ff6e1919fb0a3e549eb82b43edf1f52:
+ ;
+ case OpMul8:
+ // match: (Mul8 x y)
+ // cond:
+ // result: (MULB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endd876d6bc42a2285b801f42dadbd8757c
+ endd876d6bc42a2285b801f42dadbd8757c:
+ ;
+ case OpMulPtr:
+ // match: (MulPtr x y)
+ // cond:
+ // result: (MULQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64MULQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endbbedad106c011a93243e2062afdcc75f
+ endbbedad106c011a93243e2062afdcc75f:
+ ;
+ case OpAMD64NEGB:
+ // match: (NEGB (MOVBconst [c]))
+ // cond:
+ // result: (MOVBconst [-c])
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end36d0300ba9eab8c9da86246ff653ca96
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c
+ return true
+ }
+ goto end36d0300ba9eab8c9da86246ff653ca96
+ end36d0300ba9eab8c9da86246ff653ca96:
+ ;
+ case OpAMD64NEGL:
+ // match: (NEGL (MOVLconst [c]))
+ // cond:
+ // result: (MOVLconst [-c])
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end7a245ec67e56bd51911e5ba2d0aa0a16
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c
+ return true
+ }
+ goto end7a245ec67e56bd51911e5ba2d0aa0a16
+ end7a245ec67e56bd51911e5ba2d0aa0a16:
+ ;
+ case OpAMD64NEGQ:
+ // match: (NEGQ (MOVQconst [c]))
+ // cond:
+ // result: (MOVQconst [-c])
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end04ddd98bc6724ecb85c80c2a4e2bca5a
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c
+ return true
+ }
+ goto end04ddd98bc6724ecb85c80c2a4e2bca5a
+ end04ddd98bc6724ecb85c80c2a4e2bca5a:
+ ;
+ case OpAMD64NEGW:
+ // match: (NEGW (MOVWconst [c]))
+ // cond:
+ // result: (MOVWconst [-c])
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end1db6636f0a51848d8a34f6561ecfe7ae
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c
+ return true
+ }
+ goto end1db6636f0a51848d8a34f6561ecfe7ae
+ end1db6636f0a51848d8a34f6561ecfe7ae:
+ ;
+ case OpAMD64NOTB:
+ // match: (NOTB (MOVBconst [c]))
+ // cond:
+ // result: (MOVBconst [^c])
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end9e383a9ceb29a9e2bf890ec6a67212a8
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = ^c
+ return true
+ }
+ goto end9e383a9ceb29a9e2bf890ec6a67212a8
+ end9e383a9ceb29a9e2bf890ec6a67212a8:
+ ;
+ case OpAMD64NOTL:
+ // match: (NOTL (MOVLconst [c]))
+ // cond:
+ // result: (MOVLconst [^c])
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto endcc73972c088d5e652a1370a96e56502d
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = ^c
+ return true
+ }
+ goto endcc73972c088d5e652a1370a96e56502d
+ endcc73972c088d5e652a1370a96e56502d:
+ ;
+ case OpAMD64NOTQ:
+ // match: (NOTQ (MOVQconst [c]))
+ // cond:
+ // result: (MOVQconst [^c])
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto endb39ddb6bf7339d46f74114baad4333b6
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = ^c
+ return true
+ }
+ goto endb39ddb6bf7339d46f74114baad4333b6
+ endb39ddb6bf7339d46f74114baad4333b6:
+ ;
+ case OpAMD64NOTW:
+ // match: (NOTW (MOVWconst [c]))
+ // cond:
+ // result: (MOVWconst [^c])
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end35848095ebcf894c6957ad3be5f82c43
+ }
+ c := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = ^c
+ return true
+ }
+ goto end35848095ebcf894c6957ad3be5f82c43
+ end35848095ebcf894c6957ad3be5f82c43:
+ ;
+ case OpNeg16:
+ // match: (Neg16 x)
+ // cond:
+ // result: (NEGW x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NEGW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end7a8c652f4ffeb49656119af69512edb2
+ end7a8c652f4ffeb49656119af69512edb2:
+ ;
+ case OpNeg32:
+ // match: (Neg32 x)
+ // cond:
+ // result: (NEGL x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NEGL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endce1f7e17fc193f6c076e47d5e401e126
+ endce1f7e17fc193f6c076e47d5e401e126:
+ ;
+ case OpNeg32F:
+ // match: (Neg32F x)
+ // cond:
+ // result: (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64PXOR
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVSSconst, TypeInvalid)
+ v0.Type = config.Frontend().TypeFloat32()
+ v0.AuxInt = f2i(math.Copysign(0, -1))
+ v.AddArg(v0)
+ return true
+ }
+ goto end685a5fc899e195b9091afbe2a7146051
+ end685a5fc899e195b9091afbe2a7146051:
+ ;
+ case OpNeg64:
+ // match: (Neg64 x)
+ // cond:
+ // result: (NEGQ x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NEGQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto enda06c5b1718f2b96aba10bf5a5c437c6c
+ enda06c5b1718f2b96aba10bf5a5c437c6c:
+ ;
+ case OpNeg64F:
+ // match: (Neg64F x)
+ // cond:
+ // result: (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64PXOR
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVSDconst, TypeInvalid)
+ v0.Type = config.Frontend().TypeFloat64()
+ v0.AuxInt = f2i(math.Copysign(0, -1))
+ v.AddArg(v0)
+ return true
+ }
+ goto ende85ae82b7a51e75000eb9158d584acb2
+ ende85ae82b7a51e75000eb9158d584acb2:
+ ;
+ case OpNeg8:
+ // match: (Neg8 x)
+ // cond:
+ // result: (NEGB x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64NEGB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end1e5f495a2ac6cdea47b1ae5ba62aa95d
+ end1e5f495a2ac6cdea47b1ae5ba62aa95d:
+ ;
+ case OpNeq16:
+ // match: (Neq16 x y)
+ // cond:
+ // result: (SETNE (CMPW x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPW, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end6413ee42d523a005cce9e3372ff2c8e9
+ end6413ee42d523a005cce9e3372ff2c8e9:
+ ;
+ case OpNeq32:
+ // match: (Neq32 x y)
+ // cond:
+ // result: (SETNE (CMPL x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPL, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endb1a3ad499a09d8262952e6cbc47a23a8
+ endb1a3ad499a09d8262952e6cbc47a23a8:
+ ;
+ case OpNeq32F:
+ // match: (Neq32F x y)
+ // cond:
+ // result: (SETNEF (UCOMISS x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNEF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISS, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end2a001b2774f58aaf8c1e9efce6ae59e7
+ end2a001b2774f58aaf8c1e9efce6ae59e7:
+ ;
+ case OpNeq64:
+ // match: (Neq64 x y)
+ // cond:
+ // result: (SETNE (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end092b9159bce08d2ef7896f7d3da5a595
+ end092b9159bce08d2ef7896f7d3da5a595:
+ ;
+ case OpNeq64F:
+ // match: (Neq64F x y)
+ // cond:
+ // result: (SETNEF (UCOMISD x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNEF
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64UCOMISD, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto endb9c010023c38bd2fee7800fbefc85d98
+ endb9c010023c38bd2fee7800fbefc85d98:
+ ;
+ case OpNeq8:
+ // match: (Neq8 x y)
+ // cond:
+ // result: (SETNE (CMPB x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPB, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end89e59f45e068c89458cc4db1692bf3bb
+ end89e59f45e068c89458cc4db1692bf3bb:
+ ;
+ case OpNeqPtr:
+ // match: (NeqPtr x y)
+ // cond:
+ // result: (SETNE (CMPQ x y))
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64CMPQ, TypeInvalid)
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v0.Type = TypeFlags
+ v.AddArg(v0)
+ return true
+ }
+ goto end3b8bb3b4952011d1d40f993d8717cf16
+ end3b8bb3b4952011d1d40f993d8717cf16:
+ ;
+ case OpNot:
+ // match: (Not x)
+ // cond:
+ // result: (XORBconst [1] x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64XORBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 1
+ v.AddArg(x)
+ return true
+ }
+ goto end73973101aad60079c62fa64624e21db1
+ end73973101aad60079c62fa64624e21db1:
+ ;
+ case OpAMD64ORB:
+ // match: (ORB x (MOVBconst [c]))
+ // cond:
+ // result: (ORBconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto end7b63870decde2515cb77ec4f8f76817c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ORBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end7b63870decde2515cb77ec4f8f76817c
+ end7b63870decde2515cb77ec4f8f76817c:
+ ;
+ // match: (ORB (MOVBconst [c]) x)
+ // cond:
+ // result: (ORBconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end70b43d531e2097a4f6293f66256a642e
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ORBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end70b43d531e2097a4f6293f66256a642e
+ end70b43d531e2097a4f6293f66256a642e:
+ ;
+ // match: (ORB x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto enddca5ce800a9eca157f243cb2fdb1408a
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto enddca5ce800a9eca157f243cb2fdb1408a
+ enddca5ce800a9eca157f243cb2fdb1408a:
+ ;
+ case OpAMD64ORBconst:
+ // match: (ORBconst [c] x)
+ // cond: int8(c)==0
+ // result: x
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(int8(c) == 0) {
+ goto end565f78e3a843dc73943b59227b39a1b3
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end565f78e3a843dc73943b59227b39a1b3
+ end565f78e3a843dc73943b59227b39a1b3:
+ ;
+ // match: (ORBconst [c] _)
+ // cond: int8(c)==-1
+ // result: (MOVBconst [-1])
+ {
+ c := v.AuxInt
+ if !(int8(c) == -1) {
+ goto end6033c7910d8cd536b31446e179e4610d
+ }
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end6033c7910d8cd536b31446e179e4610d
+ end6033c7910d8cd536b31446e179e4610d:
+ ;
+ // match: (ORBconst [c] (MOVBconst [d]))
+ // cond:
+ // result: (MOVBconst [c|d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto endbe5263f022dc10a5cf53c118937d79dd
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c | d
+ return true
+ }
+ goto endbe5263f022dc10a5cf53c118937d79dd
+ endbe5263f022dc10a5cf53c118937d79dd:
+ ;
+ case OpAMD64ORL:
+ // match: (ORL x (MOVLconst [c]))
+ // cond:
+ // result: (ORLconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end1b883e30d860b6fac14ae98462c4f61a
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ORLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end1b883e30d860b6fac14ae98462c4f61a
+ end1b883e30d860b6fac14ae98462c4f61a:
+ ;
+ // match: (ORL (MOVLconst [c]) x)
+ // cond:
+ // result: (ORLconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto enda5bc49524a0cbd2241f792837d0a48a8
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ORLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto enda5bc49524a0cbd2241f792837d0a48a8
+ enda5bc49524a0cbd2241f792837d0a48a8:
+ ;
+ // match: (ORL x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end2dd719b68f4938777ef0d820aab93659
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end2dd719b68f4938777ef0d820aab93659
+ end2dd719b68f4938777ef0d820aab93659:
+ ;
+ case OpAMD64ORLconst:
+ // match: (ORLconst [c] x)
+ // cond: int32(c)==0
+ // result: x
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(int32(c) == 0) {
+ goto end5b52623a724e8a7167c71289fb7192f1
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end5b52623a724e8a7167c71289fb7192f1
+ end5b52623a724e8a7167c71289fb7192f1:
+ ;
+ // match: (ORLconst [c] _)
+ // cond: int32(c)==-1
+ // result: (MOVLconst [-1])
+ {
+ c := v.AuxInt
+ if !(int32(c) == -1) {
+ goto end345a8ea439ef2ef54bd84fc8a0f73e97
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end345a8ea439ef2ef54bd84fc8a0f73e97
+ end345a8ea439ef2ef54bd84fc8a0f73e97:
+ ;
+ // match: (ORLconst [c] (MOVLconst [d]))
+ // cond:
+ // result: (MOVLconst [c|d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto ende9ca05024248f782c88084715f81d727
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c | d
+ return true
+ }
+ goto ende9ca05024248f782c88084715f81d727
+ ende9ca05024248f782c88084715f81d727:
+ ;
+ case OpAMD64ORQ:
+ // match: (ORQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (ORQconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end601f2bb3ccda102e484ff60adeaf6d26
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto end601f2bb3ccda102e484ff60adeaf6d26
+ }
+ v.Op = OpAMD64ORQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end601f2bb3ccda102e484ff60adeaf6d26
+ end601f2bb3ccda102e484ff60adeaf6d26:
+ ;
+ // match: (ORQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (ORQconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end010afbebcd314e288509d79a16a6d5cc
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto end010afbebcd314e288509d79a16a6d5cc
+ }
+ v.Op = OpAMD64ORQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end010afbebcd314e288509d79a16a6d5cc
+ end010afbebcd314e288509d79a16a6d5cc:
+ ;
+ // match: (ORQ x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end47a27d30b82db576978c5a3a57b520fb
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end47a27d30b82db576978c5a3a57b520fb
+ end47a27d30b82db576978c5a3a57b520fb:
+ ;
+ case OpAMD64ORQconst:
+ // match: (ORQconst [0] x)
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 0 {
+ goto end44534da6b9ce98d33fad7e20f0be1fbd
+ }
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end44534da6b9ce98d33fad7e20f0be1fbd
+ end44534da6b9ce98d33fad7e20f0be1fbd:
+ ;
+ // match: (ORQconst [-1] _)
+ // cond:
+ // result: (MOVQconst [-1])
+ {
+ if v.AuxInt != -1 {
+ goto endcde9b9d7c4527eaa5d50b252f50b43c1
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto endcde9b9d7c4527eaa5d50b252f50b43c1
+ endcde9b9d7c4527eaa5d50b252f50b43c1:
+ ;
+ // match: (ORQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [c|d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto enda2488509b71db9abcb06a5115c4ddc2c
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c | d
+ return true
+ }
+ goto enda2488509b71db9abcb06a5115c4ddc2c
+ enda2488509b71db9abcb06a5115c4ddc2c:
+ ;
+ case OpAMD64ORW:
+ // match: (ORW x (MOVWconst [c]))
+ // cond:
+ // result: (ORWconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto end9f98df10892dbf170b49aace86ee0d7f
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64ORWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end9f98df10892dbf170b49aace86ee0d7f
+ end9f98df10892dbf170b49aace86ee0d7f:
+ ;
+ // match: (ORW (MOVWconst [c]) x)
+ // cond:
+ // result: (ORWconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end96405942c9ceb5fcb0ddb85a8709d015
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64ORWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end96405942c9ceb5fcb0ddb85a8709d015
+ end96405942c9ceb5fcb0ddb85a8709d015:
+ ;
+ // match: (ORW x x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto endc6a23b64e541dc9cfc6a90fd7028e8c1
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endc6a23b64e541dc9cfc6a90fd7028e8c1
+ endc6a23b64e541dc9cfc6a90fd7028e8c1:
+ ;
+ case OpAMD64ORWconst:
+ // match: (ORWconst [c] x)
+ // cond: int16(c)==0
+ // result: x
+ {
+ c := v.AuxInt
+ x := v.Args[0]
+ if !(int16(c) == 0) {
+ goto endbbbdec9091c8b4c58e587eac8a43402d
+ }
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endbbbdec9091c8b4c58e587eac8a43402d
+ endbbbdec9091c8b4c58e587eac8a43402d:
+ ;
+ // match: (ORWconst [c] _)
+ // cond: int16(c)==-1
+ // result: (MOVWconst [-1])
+ {
+ c := v.AuxInt
+ if !(int16(c) == -1) {
+ goto ended87a5775f5e04b2d2a117a63d82dd9b
+ }
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto ended87a5775f5e04b2d2a117a63d82dd9b
+ ended87a5775f5e04b2d2a117a63d82dd9b:
+ ;
+ // match: (ORWconst [c] (MOVWconst [d]))
+ // cond:
+ // result: (MOVWconst [c|d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto endba9221a8462b5c62e8d7c686f64c2778
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c | d
+ return true
+ }
+ goto endba9221a8462b5c62e8d7c686f64c2778
+ endba9221a8462b5c62e8d7c686f64c2778:
+ ;
+ case OpOffPtr:
+ // match: (OffPtr [off] ptr)
+ // cond:
+ // result: (ADDQconst [off] ptr)
+ {
+ off := v.AuxInt
+ ptr := v.Args[0]
+ v.Op = OpAMD64ADDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = off
+ v.AddArg(ptr)
+ return true
+ }
+ goto end0429f947ee7ac49ff45a243e461a5290
+ end0429f947ee7ac49ff45a243e461a5290:
+ ;
+ case OpOr16:
+ // match: (Or16 x y)
+ // cond:
+ // result: (ORW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ORW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end8fedf2c79d5607b7056b0ff015199cbd
+ end8fedf2c79d5607b7056b0ff015199cbd:
+ ;
+ case OpOr32:
+ // match: (Or32 x y)
+ // cond:
+ // result: (ORL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ORL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endea45bed9ca97d2995b68b53e6012d384
+ endea45bed9ca97d2995b68b53e6012d384:
+ ;
+ case OpOr64:
+ // match: (Or64 x y)
+ // cond:
+ // result: (ORQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ORQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end3a446becaf2461f4f1a41faeef313f41
+ end3a446becaf2461f4f1a41faeef313f41:
+ ;
+ case OpOr8:
+ // match: (Or8 x y)
+ // cond:
+ // result: (ORB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ORB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end6f8a8c559a167d1f0a5901d09a1fb248
+ end6f8a8c559a167d1f0a5901d09a1fb248:
+ ;
+ case OpPanicNilCheck:
+ // match: (PanicNilCheck ptr mem)
+ // cond:
+ // result: (LoweredPanicNilCheck ptr mem)
+ {
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64LoweredPanicNilCheck
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ goto enda02b1ad5a6f929b782190145f2c8628b
+ enda02b1ad5a6f929b782190145f2c8628b:
+ ;
+ case OpRsh16Ux16:
+ // match: (Rsh16Ux16 <t> x y)
+ // cond:
+ // result: (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end4d5e000764dcea396f2d86472c2af6eb
+ end4d5e000764dcea396f2d86472c2af6eb:
+ ;
+ case OpRsh16Ux32:
+ // match: (Rsh16Ux32 <t> x y)
+ // cond:
+ // result: (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end9ef4fe2ea4565865cd4b3aa9c7596c00
+ end9ef4fe2ea4565865cd4b3aa9c7596c00:
+ ;
+ case OpRsh16Ux64:
+ // match: (Rsh16Ux64 <t> x y)
+ // cond:
+ // result: (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end48bc94b9a68aad454eaabc42b2e1d646
+ end48bc94b9a68aad454eaabc42b2e1d646:
+ ;
+ case OpRsh16Ux8:
+ // match: (Rsh16Ux8 <t> x y)
+ // cond:
+ // result: (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst [16] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRW, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 16
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto ende98f618fa53b1f1d5d3f79781d5cb2cc
+ ende98f618fa53b1f1d5d3f79781d5cb2cc:
+ ;
+ case OpRsh16x16:
+ // match: (Rsh16x16 <t> x y)
+ // cond:
+ // result: (SARW <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [16] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORW, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v3.AuxInt = 16
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end1de548dcf8d7c7222c7a739809597526
+ end1de548dcf8d7c7222c7a739809597526:
+ ;
+ case OpRsh16x32:
+ // match: (Rsh16x32 <t> x y)
+ // cond:
+ // result: (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [16] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORL, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v3.AuxInt = 16
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end74419e1036ea7e0c3a09d05b1eabad22
+ end74419e1036ea7e0c3a09d05b1eabad22:
+ ;
+ case OpRsh16x64:
+ // match: (Rsh16x64 <t> x y)
+ // cond:
+ // result: (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [16] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORQ, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTQ, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v3.AuxInt = 16
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto ende35d1c2918196fae04fca22e80936bab
+ ende35d1c2918196fae04fca22e80936bab:
+ ;
+ case OpRsh16x8:
+ // match: (Rsh16x8 <t> x y)
+ // cond:
+ // result: (SARW <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [16] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORB, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v3.AuxInt = 16
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto endaa6a45afc4c6552c1a90a13160578fba
+ endaa6a45afc4c6552c1a90a13160578fba:
+ ;
+ case OpRsh32Ux16:
+ // match: (Rsh32Ux16 <t> x y)
+ // cond:
+ // result: (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end74495683df77023ed619b4ecee98d94a
+ end74495683df77023ed619b4ecee98d94a:
+ ;
+ case OpRsh32Ux32:
+ // match: (Rsh32Ux32 <t> x y)
+ // cond:
+ // result: (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPLconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto enda7d6c92ab2d7467102db447d6b431b28
+ enda7d6c92ab2d7467102db447d6b431b28:
+ ;
+ case OpRsh32Ux64:
+ // match: (Rsh32Ux64 <t> x y)
+ // cond:
+ // result: (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPQconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end7c0829166a6219a15de2c0aa688a9bb3
+ end7c0829166a6219a15de2c0aa688a9bb3:
+ ;
+ case OpRsh32Ux8:
+ // match: (Rsh32Ux8 <t> x y)
+ // cond:
+ // result: (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst [32] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRL, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 32
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end221315aa8a09c9d8d2f243bf445446ea
+ end221315aa8a09c9d8d2f243bf445446ea:
+ ;
+ case OpRsh32x16:
+ // match: (Rsh32x16 <t> x y)
+ // cond:
+ // result: (SARL <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [32] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORW, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v3.AuxInt = 32
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end521b60d91648f07fe1be359f1cdbde29
+ end521b60d91648f07fe1be359f1cdbde29:
+ ;
+ case OpRsh32x32:
+ // match: (Rsh32x32 <t> x y)
+ // cond:
+ // result: (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [32] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORL, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v3.AuxInt = 32
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end0fc03188975afbca2139e28c38b7cd17
+ end0fc03188975afbca2139e28c38b7cd17:
+ ;
+ case OpRsh32x64:
+ // match: (Rsh32x64 <t> x y)
+ // cond:
+ // result: (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [32] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORQ, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTQ, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v3.AuxInt = 32
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto endf36790cc7ba330d448b403a450a7c1d4
+ endf36790cc7ba330d448b403a450a7c1d4:
+ ;
+ case OpRsh32x8:
+ // match: (Rsh32x8 <t> x y)
+ // cond:
+ // result: (SARL <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [32] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORB, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v3.AuxInt = 32
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end1242709228488be2f2505ead8eabb871
+ end1242709228488be2f2505ead8eabb871:
+ ;
+ case OpRsh64Ux16:
+ // match: (Rsh64Ux16 <t> x y)
+ // cond:
+ // result: (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPWconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end0bc6c36a57ebaf0b90fc418f976fe210
+ end0bc6c36a57ebaf0b90fc418f976fe210:
+ ;
+ case OpRsh64Ux32:
+ // match: (Rsh64Ux32 <t> x y)
+ // cond:
+ // result: (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPLconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto ende3f52062f53bc3b5aa0461a644e38a1b
+ ende3f52062f53bc3b5aa0461a644e38a1b:
+ ;
+ case OpRsh64Ux64:
+ // match: (Rsh64Ux64 <t> x y)
+ // cond:
+ // result: (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPQconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto endaec410d0544f817303c79bad739c50fd
+ endaec410d0544f817303c79bad739c50fd:
+ ;
+ case OpRsh64Ux8:
+ // match: (Rsh64Ux8 <t> x y)
+ // cond:
+ // result: (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMPBconst [64] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRQ, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 64
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end0318851ecb02e4ad8a2669034adf7862
+ end0318851ecb02e4ad8a2669034adf7862:
+ ;
+ case OpRsh64x16:
+ // match: (Rsh64x16 <t> x y)
+ // cond:
+ // result: (SARQ <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [64] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORW, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v3.AuxInt = 64
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto endcf8bbca9a7a848fbebaaaa8b699cd086
+ endcf8bbca9a7a848fbebaaaa8b699cd086:
+ ;
+ case OpRsh64x32:
+ // match: (Rsh64x32 <t> x y)
+ // cond:
+ // result: (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [64] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORL, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v3.AuxInt = 64
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end7604d45b06ee69bf2feddf88b2f33cb6
+ end7604d45b06ee69bf2feddf88b2f33cb6:
+ ;
+ case OpRsh64x64:
+ // match: (Rsh64x64 <t> x y)
+ // cond:
+ // result: (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [64] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORQ, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTQ, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v3.AuxInt = 64
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end12a3b44af604b515ad5530502336486f
+ end12a3b44af604b515ad5530502336486f:
+ ;
+ case OpRsh64x8:
+ // match: (Rsh64x8 <t> x y)
+ // cond:
+ // result: (SARQ <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [64] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORB, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v3.AuxInt = 64
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end4e2a83809914aad301a2f74d3c38fbbb
+ end4e2a83809914aad301a2f74d3c38fbbb:
+ ;
+ case OpRsh8Ux16:
+ // match: (Rsh8Ux16 <t> x y)
+ // cond:
+ // result: (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end724175a51b6efac60c6bb9d83d81215a
+ end724175a51b6efac60c6bb9d83d81215a:
+ ;
+ case OpRsh8Ux32:
+ // match: (Rsh8Ux32 <t> x y)
+ // cond:
+ // result: (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end9d973431bed6682c1d557a535cf440ed
+ end9d973431bed6682c1d557a535cf440ed:
+ ;
+ case OpRsh8Ux64:
+ // match: (Rsh8Ux64 <t> x y)
+ // cond:
+ // result: (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto end9586937cdeb7946c337d46cd30cb9a11
+ end9586937cdeb7946c337d46cd30cb9a11:
+ ;
+ case OpRsh8Ux8:
+ // match: (Rsh8Ux8 <t> x y)
+ // cond:
+ // result: (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst [8] y)))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64ANDB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SHRB, TypeInvalid)
+ v0.Type = t
+ v0.AddArg(x)
+ v0.AddArg(y)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v1.Type = t
+ v2 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v2.AuxInt = 8
+ v2.AddArg(y)
+ v2.Type = TypeFlags
+ v1.AddArg(v2)
+ v.AddArg(v1)
+ return true
+ }
+ goto endc5a55ef63d86e6b8d4d366a947bf563d
+ endc5a55ef63d86e6b8d4d366a947bf563d:
+ ;
+ case OpRsh8x16:
+ // match: (Rsh8x16 <t> x y)
+ // cond:
+ // result: (SARB <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst [8] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORW, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPWconst, TypeInvalid)
+ v3.AuxInt = 8
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto endfa967d6583c1bb9644514c2013b919f8
+ endfa967d6583c1bb9644514c2013b919f8:
+ ;
+ case OpRsh8x32:
+ // match: (Rsh8x32 <t> x y)
+ // cond:
+ // result: (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst [8] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORL, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPLconst, TypeInvalid)
+ v3.AuxInt = 8
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto ende5a630810624a1bd3677618c2cbc8619
+ ende5a630810624a1bd3677618c2cbc8619:
+ ;
+ case OpRsh8x64:
+ // match: (Rsh8x64 <t> x y)
+ // cond:
+ // result: (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst [8] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORQ, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTQ, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBQcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPQconst, TypeInvalid)
+ v3.AuxInt = 8
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto end23c55e49d8bc44afc680b2a4eade5af6
+ end23c55e49d8bc44afc680b2a4eade5af6:
+ ;
+ case OpRsh8x8:
+ // match: (Rsh8x8 <t> x y)
+ // cond:
+ // result: (SARB <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst [8] y)))))
+ {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SARB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = t
+ v.AddArg(x)
+ v0 := b.NewValue0(v.Line, OpAMD64ORB, TypeInvalid)
+ v0.Type = y.Type
+ v0.AddArg(y)
+ v1 := b.NewValue0(v.Line, OpAMD64NOTL, TypeInvalid)
+ v1.Type = y.Type
+ v2 := b.NewValue0(v.Line, OpAMD64SBBLcarrymask, TypeInvalid)
+ v2.Type = y.Type
+ v3 := b.NewValue0(v.Line, OpAMD64CMPBconst, TypeInvalid)
+ v3.AuxInt = 8
+ v3.AddArg(y)
+ v3.Type = TypeFlags
+ v2.AddArg(v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ goto enddab0c33c56e2e9434b880e1718621979
+ enddab0c33c56e2e9434b880e1718621979:
+ ;
+ case OpAMD64SARB:
+ // match: (SARB x (MOVBconst [c]))
+ // cond:
+ // result: (SARBconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto end3bf3d17717aa6c04462e56d1c87902ce
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SARBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto end3bf3d17717aa6c04462e56d1c87902ce
+ end3bf3d17717aa6c04462e56d1c87902ce:
+ ;
+ case OpAMD64SARBconst:
+ // match: (SARBconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [d>>uint64(c)])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end06e0e38775f0650ed672427d19cd8fff
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d >> uint64(c)
+ return true
+ }
+ goto end06e0e38775f0650ed672427d19cd8fff
+ end06e0e38775f0650ed672427d19cd8fff:
+ ;
+ case OpAMD64SARL:
+ // match: (SARL x (MOVLconst [c]))
+ // cond:
+ // result: (SARLconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto ende586a72c1b232ee0b63e37c71eeb8470
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SARLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto ende586a72c1b232ee0b63e37c71eeb8470
+ ende586a72c1b232ee0b63e37c71eeb8470:
+ ;
+ case OpAMD64SARLconst:
+ // match: (SARLconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [d>>uint64(c)])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end8f34dc94323303e75b7bcc8e731cf1db
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d >> uint64(c)
+ return true
+ }
+ goto end8f34dc94323303e75b7bcc8e731cf1db
+ end8f34dc94323303e75b7bcc8e731cf1db:
+ ;
+ case OpAMD64SARQ:
+ // match: (SARQ x (MOVQconst [c]))
+ // cond:
+ // result: (SARQconst [c&63] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end25e720ab203be2745dded5550e6d8a7c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SARQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 63
+ v.AddArg(x)
+ return true
+ }
+ goto end25e720ab203be2745dded5550e6d8a7c
+ end25e720ab203be2745dded5550e6d8a7c:
+ ;
+ case OpAMD64SARQconst:
+ // match: (SARQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [d>>uint64(c)])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto endd949ba69a1ff71ba62c49b39c68f269e
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d >> uint64(c)
+ return true
+ }
+ goto endd949ba69a1ff71ba62c49b39c68f269e
+ endd949ba69a1ff71ba62c49b39c68f269e:
+ ;
+ case OpAMD64SARW:
+ // match: (SARW x (MOVWconst [c]))
+ // cond:
+ // result: (SARWconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto endc46e3f211f94238f9a0aec3c498af490
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SARWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto endc46e3f211f94238f9a0aec3c498af490
+ endc46e3f211f94238f9a0aec3c498af490:
+ ;
+ case OpAMD64SARWconst:
+ // match: (SARWconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [d>>uint64(c)])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto endca23e80dba22ab574f843c7a4cef24ab
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d >> uint64(c)
+ return true
+ }
+ goto endca23e80dba22ab574f843c7a4cef24ab
+ endca23e80dba22ab574f843c7a4cef24ab:
+ ;
+ case OpAMD64SBBLcarrymask:
+ // match: (SBBLcarrymask (CMPQconst [c] (MOVQconst [d])))
+ // cond: inBounds64(d, c)
+ // result: (MOVLconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPQconst {
+ goto end490c8a7039bab41e90e564fbb8500233
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVQconst {
+ goto end490c8a7039bab41e90e564fbb8500233
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds64(d, c)) {
+ goto end490c8a7039bab41e90e564fbb8500233
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end490c8a7039bab41e90e564fbb8500233
+ end490c8a7039bab41e90e564fbb8500233:
+ ;
+ // match: (SBBLcarrymask (CMPQconst [c] (MOVQconst [d])))
+ // cond: !inBounds64(d, c)
+ // result: (MOVLconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPQconst {
+ goto end95e703eabe71d831b7a3d2f9fabe7de9
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVQconst {
+ goto end95e703eabe71d831b7a3d2f9fabe7de9
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds64(d, c)) {
+ goto end95e703eabe71d831b7a3d2f9fabe7de9
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end95e703eabe71d831b7a3d2f9fabe7de9
+ end95e703eabe71d831b7a3d2f9fabe7de9:
+ ;
+ // match: (SBBLcarrymask (CMPLconst [c] (MOVLconst [d])))
+ // cond: inBounds32(d, c)
+ // result: (MOVLconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPLconst {
+ goto end00c0a561340b0172c9a21f63648b86e2
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVLconst {
+ goto end00c0a561340b0172c9a21f63648b86e2
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds32(d, c)) {
+ goto end00c0a561340b0172c9a21f63648b86e2
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end00c0a561340b0172c9a21f63648b86e2
+ end00c0a561340b0172c9a21f63648b86e2:
+ ;
+ // match: (SBBLcarrymask (CMPLconst [c] (MOVLconst [d])))
+ // cond: !inBounds32(d, c)
+ // result: (MOVLconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPLconst {
+ goto enda73c8bf14f7b45dd97c6a006e317b0b8
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVLconst {
+ goto enda73c8bf14f7b45dd97c6a006e317b0b8
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds32(d, c)) {
+ goto enda73c8bf14f7b45dd97c6a006e317b0b8
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto enda73c8bf14f7b45dd97c6a006e317b0b8
+ enda73c8bf14f7b45dd97c6a006e317b0b8:
+ ;
+ // match: (SBBLcarrymask (CMPWconst [c] (MOVWconst [d])))
+ // cond: inBounds16(d, c)
+ // result: (MOVLconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPWconst {
+ goto endb94dc44cd77f66ed3bf3742874b666fc
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVWconst {
+ goto endb94dc44cd77f66ed3bf3742874b666fc
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds16(d, c)) {
+ goto endb94dc44cd77f66ed3bf3742874b666fc
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto endb94dc44cd77f66ed3bf3742874b666fc
+ endb94dc44cd77f66ed3bf3742874b666fc:
+ ;
+ // match: (SBBLcarrymask (CMPWconst [c] (MOVWconst [d])))
+ // cond: !inBounds16(d, c)
+ // result: (MOVLconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPWconst {
+ goto end7a02def6194822f7ab937d78088504d2
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVWconst {
+ goto end7a02def6194822f7ab937d78088504d2
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds16(d, c)) {
+ goto end7a02def6194822f7ab937d78088504d2
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end7a02def6194822f7ab937d78088504d2
+ end7a02def6194822f7ab937d78088504d2:
+ ;
+ // match: (SBBLcarrymask (CMPBconst [c] (MOVBconst [d])))
+ // cond: inBounds8(d, c)
+ // result: (MOVLconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPBconst {
+ goto end79c8e4a20761df731521e6cd956c4245
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVBconst {
+ goto end79c8e4a20761df731521e6cd956c4245
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds8(d, c)) {
+ goto end79c8e4a20761df731521e6cd956c4245
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end79c8e4a20761df731521e6cd956c4245
+ end79c8e4a20761df731521e6cd956c4245:
+ ;
+ // match: (SBBLcarrymask (CMPBconst [c] (MOVBconst [d])))
+ // cond: !inBounds8(d, c)
+ // result: (MOVLconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPBconst {
+ goto end95b5b21dd7756ae41575759a1eff2bea
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVBconst {
+ goto end95b5b21dd7756ae41575759a1eff2bea
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds8(d, c)) {
+ goto end95b5b21dd7756ae41575759a1eff2bea
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end95b5b21dd7756ae41575759a1eff2bea
+ end95b5b21dd7756ae41575759a1eff2bea:
+ ;
+ case OpAMD64SBBQcarrymask:
+ // match: (SBBQcarrymask (CMPQconst [c] (MOVQconst [d])))
+ // cond: inBounds64(d, c)
+ // result: (MOVQconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPQconst {
+ goto end0c26df98feb38f149eca12f33c15de1b
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVQconst {
+ goto end0c26df98feb38f149eca12f33c15de1b
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds64(d, c)) {
+ goto end0c26df98feb38f149eca12f33c15de1b
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end0c26df98feb38f149eca12f33c15de1b
+ end0c26df98feb38f149eca12f33c15de1b:
+ ;
+ // match: (SBBQcarrymask (CMPQconst [c] (MOVQconst [d])))
+ // cond: !inBounds64(d, c)
+ // result: (MOVQconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPQconst {
+ goto end8965aa1e1153e5ecd123bbb31a618570
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVQconst {
+ goto end8965aa1e1153e5ecd123bbb31a618570
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds64(d, c)) {
+ goto end8965aa1e1153e5ecd123bbb31a618570
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end8965aa1e1153e5ecd123bbb31a618570
+ end8965aa1e1153e5ecd123bbb31a618570:
+ ;
+ // match: (SBBQcarrymask (CMPLconst [c] (MOVLconst [d])))
+ // cond: inBounds32(d, c)
+ // result: (MOVQconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPLconst {
+ goto end8772ede6098981a61af0f478841d7d54
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVLconst {
+ goto end8772ede6098981a61af0f478841d7d54
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds32(d, c)) {
+ goto end8772ede6098981a61af0f478841d7d54
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end8772ede6098981a61af0f478841d7d54
+ end8772ede6098981a61af0f478841d7d54:
+ ;
+ // match: (SBBQcarrymask (CMPLconst [c] (MOVLconst [d])))
+ // cond: !inBounds32(d, c)
+ // result: (MOVQconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPLconst {
+ goto end2d535e90075ee777fc616e6b9847a384
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVLconst {
+ goto end2d535e90075ee777fc616e6b9847a384
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds32(d, c)) {
+ goto end2d535e90075ee777fc616e6b9847a384
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end2d535e90075ee777fc616e6b9847a384
+ end2d535e90075ee777fc616e6b9847a384:
+ ;
+ // match: (SBBQcarrymask (CMPWconst [c] (MOVWconst [d])))
+ // cond: inBounds16(d, c)
+ // result: (MOVQconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPWconst {
+ goto end3103c51e14b4fc894b4170f16f37eebc
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVWconst {
+ goto end3103c51e14b4fc894b4170f16f37eebc
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds16(d, c)) {
+ goto end3103c51e14b4fc894b4170f16f37eebc
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end3103c51e14b4fc894b4170f16f37eebc
+ end3103c51e14b4fc894b4170f16f37eebc:
+ ;
+ // match: (SBBQcarrymask (CMPWconst [c] (MOVWconst [d])))
+ // cond: !inBounds16(d, c)
+ // result: (MOVQconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPWconst {
+ goto enddae2191a59cfef5efb04ebab9354745c
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVWconst {
+ goto enddae2191a59cfef5efb04ebab9354745c
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds16(d, c)) {
+ goto enddae2191a59cfef5efb04ebab9354745c
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto enddae2191a59cfef5efb04ebab9354745c
+ enddae2191a59cfef5efb04ebab9354745c:
+ ;
+ // match: (SBBQcarrymask (CMPBconst [c] (MOVBconst [d])))
+ // cond: inBounds8(d, c)
+ // result: (MOVQconst [-1])
+ {
+ if v.Args[0].Op != OpAMD64CMPBconst {
+ goto end72e088325ca005b0251b1ee82da3c5d9
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVBconst {
+ goto end72e088325ca005b0251b1ee82da3c5d9
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(inBounds8(d, c)) {
+ goto end72e088325ca005b0251b1ee82da3c5d9
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -1
+ return true
+ }
+ goto end72e088325ca005b0251b1ee82da3c5d9
+ end72e088325ca005b0251b1ee82da3c5d9:
+ ;
+ // match: (SBBQcarrymask (CMPBconst [c] (MOVBconst [d])))
+ // cond: !inBounds8(d, c)
+ // result: (MOVQconst [0])
+ {
+ if v.Args[0].Op != OpAMD64CMPBconst {
+ goto endcb388100f5b933aa94095096d2bb425e
+ }
+ c := v.Args[0].AuxInt
+ if v.Args[0].Args[0].Op != OpAMD64MOVBconst {
+ goto endcb388100f5b933aa94095096d2bb425e
+ }
+ d := v.Args[0].Args[0].AuxInt
+ if !(!inBounds8(d, c)) {
+ goto endcb388100f5b933aa94095096d2bb425e
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto endcb388100f5b933aa94095096d2bb425e
+ endcb388100f5b933aa94095096d2bb425e:
+ ;
+ case OpAMD64SETA:
+ // match: (SETA (InvertFlags x))
+ // cond:
+ // result: (SETB x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto enda4ac36e94fc279d762b5a6c7c6cc665d
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto enda4ac36e94fc279d762b5a6c7c6cc665d
+ enda4ac36e94fc279d762b5a6c7c6cc665d:
+ ;
+ case OpAMD64SETAE:
+ // match: (SETAE (InvertFlags x))
+ // cond:
+ // result: (SETBE x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto end0468f5be6caf682fdea6b91d6648991e
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETBE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end0468f5be6caf682fdea6b91d6648991e
+ end0468f5be6caf682fdea6b91d6648991e:
+ ;
+ case OpAMD64SETB:
+ // match: (SETB (InvertFlags x))
+ // cond:
+ // result: (SETA x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto endc9eba7aa1e54a228570d2f5cc96f3565
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETA
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endc9eba7aa1e54a228570d2f5cc96f3565
+ endc9eba7aa1e54a228570d2f5cc96f3565:
+ ;
+ case OpAMD64SETBE:
+ // match: (SETBE (InvertFlags x))
+ // cond:
+ // result: (SETAE x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto end9d9031643469798b14b8cad1f5a7a1ba
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETAE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end9d9031643469798b14b8cad1f5a7a1ba
+ end9d9031643469798b14b8cad1f5a7a1ba:
+ ;
+ case OpAMD64SETEQ:
+ // match: (SETEQ (InvertFlags x))
+ // cond:
+ // result: (SETEQ x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto end5d2039c9368d8c0cfba23b5a85b459e1
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETEQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end5d2039c9368d8c0cfba23b5a85b459e1
+ end5d2039c9368d8c0cfba23b5a85b459e1:
+ ;
+ case OpAMD64SETG:
+ // match: (SETG (InvertFlags x))
+ // cond:
+ // result: (SETL x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto endf7586738694c9cd0b74ae28bbadb649f
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endf7586738694c9cd0b74ae28bbadb649f
+ endf7586738694c9cd0b74ae28bbadb649f:
+ ;
+ case OpAMD64SETGE:
+ // match: (SETGE (InvertFlags x))
+ // cond:
+ // result: (SETLE x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto end82c11eff6f842159f564f2dad3d2eedc
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETLE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end82c11eff6f842159f564f2dad3d2eedc
+ end82c11eff6f842159f564f2dad3d2eedc:
+ ;
+ case OpAMD64SETL:
+ // match: (SETL (InvertFlags x))
+ // cond:
+ // result: (SETG x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto ende33160cd86b9d4d3b77e02fb4658d5d3
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETG
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto ende33160cd86b9d4d3b77e02fb4658d5d3
+ ende33160cd86b9d4d3b77e02fb4658d5d3:
+ ;
+ case OpAMD64SETLE:
+ // match: (SETLE (InvertFlags x))
+ // cond:
+ // result: (SETGE x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto end9307d96753efbeb888d1c98a6aba7a29
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETGE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end9307d96753efbeb888d1c98a6aba7a29
+ end9307d96753efbeb888d1c98a6aba7a29:
+ ;
+ case OpAMD64SETNE:
+ // match: (SETNE (InvertFlags x))
+ // cond:
+ // result: (SETNE x)
+ {
+ if v.Args[0].Op != OpAMD64InvertFlags {
+ goto endbc71811b789475308014550f638026eb
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64SETNE
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endbc71811b789475308014550f638026eb
+ endbc71811b789475308014550f638026eb:
+ ;
+ case OpAMD64SHLB:
+ // match: (SHLB x (MOVBconst [c]))
+ // cond:
+ // result: (SHLBconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto end2d0d0111d831d8a575b5627284a6337a
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHLBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto end2d0d0111d831d8a575b5627284a6337a
+ end2d0d0111d831d8a575b5627284a6337a:
+ ;
+ case OpAMD64SHLL:
+ // match: (SHLL x (MOVLconst [c]))
+ // cond:
+ // result: (SHLLconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end633f9ddcfbb63374c895a5f78da75d25
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHLLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto end633f9ddcfbb63374c895a5f78da75d25
+ end633f9ddcfbb63374c895a5f78da75d25:
+ ;
+ case OpAMD64SHLQ:
+ // match: (SHLQ x (MOVQconst [c]))
+ // cond:
+ // result: (SHLQconst [c&63] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end4d7e3a945cacdd6b6c8c0de6f465d4ae
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHLQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 63
+ v.AddArg(x)
+ return true
+ }
+ goto end4d7e3a945cacdd6b6c8c0de6f465d4ae
+ end4d7e3a945cacdd6b6c8c0de6f465d4ae:
+ ;
+ case OpAMD64SHLW:
+ // match: (SHLW x (MOVWconst [c]))
+ // cond:
+ // result: (SHLWconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto endba96a52aa58d28b3357828051e0e695c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHLWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto endba96a52aa58d28b3357828051e0e695c
+ endba96a52aa58d28b3357828051e0e695c:
+ ;
+ case OpAMD64SHRB:
+ // match: (SHRB x (MOVBconst [c]))
+ // cond:
+ // result: (SHRBconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto enddb1cd5aaa826d43fa4f6d1b2b8795e58
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHRBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto enddb1cd5aaa826d43fa4f6d1b2b8795e58
+ enddb1cd5aaa826d43fa4f6d1b2b8795e58:
+ ;
+ case OpAMD64SHRL:
+ // match: (SHRL x (MOVLconst [c]))
+ // cond:
+ // result: (SHRLconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end344b8b9202e1925e8d0561f1c21412fc
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHRLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto end344b8b9202e1925e8d0561f1c21412fc
+ end344b8b9202e1925e8d0561f1c21412fc:
+ ;
+ case OpAMD64SHRQ:
+ // match: (SHRQ x (MOVQconst [c]))
+ // cond:
+ // result: (SHRQconst [c&63] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end699d35e2d5cfa08b8a3b1c8a183ddcf3
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHRQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 63
+ v.AddArg(x)
+ return true
+ }
+ goto end699d35e2d5cfa08b8a3b1c8a183ddcf3
+ end699d35e2d5cfa08b8a3b1c8a183ddcf3:
+ ;
+ case OpAMD64SHRW:
+ // match: (SHRW x (MOVWconst [c]))
+ // cond:
+ // result: (SHRWconst [c&31] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto endd75ff1f9b3e9ec9c942a39b6179da1b3
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SHRWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c & 31
+ v.AddArg(x)
+ return true
+ }
+ goto endd75ff1f9b3e9ec9c942a39b6179da1b3
+ endd75ff1f9b3e9ec9c942a39b6179da1b3:
+ ;
+ case OpAMD64SUBB:
+ // match: (SUBB x (MOVBconst [c]))
+ // cond:
+ // result: (SUBBconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto end9ca5d2a70e2df1a5a3ed6786bce1f7b2
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SUBBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end9ca5d2a70e2df1a5a3ed6786bce1f7b2
+ end9ca5d2a70e2df1a5a3ed6786bce1f7b2:
+ ;
+ // match: (SUBB (MOVBconst [c]) x)
+ // cond:
+ // result: (NEGB (SUBBconst <v.Type> x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto endc288755d69b04d24a6aac32a73956411
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64NEGB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SUBBconst, TypeInvalid)
+ v0.Type = v.Type
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v.AddArg(v0)
+ return true
+ }
+ goto endc288755d69b04d24a6aac32a73956411
+ endc288755d69b04d24a6aac32a73956411:
+ ;
+ // match: (SUBB x x)
+ // cond:
+ // result: (MOVBconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto ende8904403d937d95b0d6133d3ec92bb45
+ }
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto ende8904403d937d95b0d6133d3ec92bb45
+ ende8904403d937d95b0d6133d3ec92bb45:
+ ;
+ case OpAMD64SUBBconst:
+ // match: (SUBBconst [c] (MOVBconst [d]))
+ // cond:
+ // result: (MOVBconst [d-c])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto enddc5383558e2f3eae507afcb94eada964
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d - c
+ return true
+ }
+ goto enddc5383558e2f3eae507afcb94eada964
+ enddc5383558e2f3eae507afcb94eada964:
+ ;
+ // match: (SUBBconst [c] (SUBBconst [d] x))
+ // cond:
+ // result: (ADDBconst [-c-d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64SUBBconst {
+ goto end035c57413a46eb347ecb3736d1510915
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c - d
+ v.AddArg(x)
+ return true
+ }
+ goto end035c57413a46eb347ecb3736d1510915
+ end035c57413a46eb347ecb3736d1510915:
+ ;
+ case OpAMD64SUBL:
+ // match: (SUBL x (MOVLconst [c]))
+ // cond:
+ // result: (SUBLconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto end178c1d6c86f9c16f6497586c2f7d8625
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SUBLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end178c1d6c86f9c16f6497586c2f7d8625
+ end178c1d6c86f9c16f6497586c2f7d8625:
+ ;
+ // match: (SUBL (MOVLconst [c]) x)
+ // cond:
+ // result: (NEGL (SUBLconst <v.Type> x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto endb0efe6e15ec20486b849534a00483ae2
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64NEGL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SUBLconst, TypeInvalid)
+ v0.Type = v.Type
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v.AddArg(v0)
+ return true
+ }
+ goto endb0efe6e15ec20486b849534a00483ae2
+ endb0efe6e15ec20486b849534a00483ae2:
+ ;
+ // match: (SUBL x x)
+ // cond:
+ // result: (MOVLconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end332f1f641f875c69bea7289191e69133
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end332f1f641f875c69bea7289191e69133
+ end332f1f641f875c69bea7289191e69133:
+ ;
+ case OpAMD64SUBLconst:
+ // match: (SUBLconst [c] (MOVLconst [d]))
+ // cond:
+ // result: (MOVLconst [d-c])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end6c5c6d58d4bdd0a5c2f7bf10b343b41e
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d - c
+ return true
+ }
+ goto end6c5c6d58d4bdd0a5c2f7bf10b343b41e
+ end6c5c6d58d4bdd0a5c2f7bf10b343b41e:
+ ;
+ // match: (SUBLconst [c] (SUBLconst [d] x))
+ // cond:
+ // result: (ADDLconst [-c-d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64SUBLconst {
+ goto end0c9ffb11e8a56ced1b14dbf6bf9a6737
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c - d
+ v.AddArg(x)
+ return true
+ }
+ goto end0c9ffb11e8a56ced1b14dbf6bf9a6737
+ end0c9ffb11e8a56ced1b14dbf6bf9a6737:
+ ;
+ case OpAMD64SUBQ:
+ // match: (SUBQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (SUBQconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end9bbb7b20824a498752c605942fad89c2
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto end9bbb7b20824a498752c605942fad89c2
+ }
+ v.Op = OpAMD64SUBQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end9bbb7b20824a498752c605942fad89c2
+ end9bbb7b20824a498752c605942fad89c2:
+ ;
+ // match: (SUBQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (NEGQ (SUBQconst <v.Type> x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end8beb96de3efee9206d1bd4b7d777d2cb
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto end8beb96de3efee9206d1bd4b7d777d2cb
+ }
+ v.Op = OpAMD64NEGQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SUBQconst, TypeInvalid)
+ v0.Type = v.Type
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v.AddArg(v0)
+ return true
+ }
+ goto end8beb96de3efee9206d1bd4b7d777d2cb
+ end8beb96de3efee9206d1bd4b7d777d2cb:
+ ;
+ // match: (SUBQ x x)
+ // cond:
+ // result: (MOVQconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto endd87d1d839d2dc54d9c90fa4f73383480
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto endd87d1d839d2dc54d9c90fa4f73383480
+ endd87d1d839d2dc54d9c90fa4f73383480:
+ ;
+ case OpAMD64SUBQconst:
+ // match: (SUBQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [d-c])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto endb0daebe6831cf381377c3e4248070f25
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d - c
+ return true
+ }
+ goto endb0daebe6831cf381377c3e4248070f25
+ endb0daebe6831cf381377c3e4248070f25:
+ ;
+ // match: (SUBQconst [c] (SUBQconst [d] x))
+ // cond:
+ // result: (ADDQconst [-c-d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64SUBQconst {
+ goto end2d40ddb5ae9e90679456254c61858d9d
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c - d
+ v.AddArg(x)
+ return true
+ }
+ goto end2d40ddb5ae9e90679456254c61858d9d
+ end2d40ddb5ae9e90679456254c61858d9d:
+ ;
+ case OpAMD64SUBW:
+ // match: (SUBW x (MOVWconst [c]))
+ // cond:
+ // result: (SUBWconst x [c])
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto end135aa9100b2f61d58b37cede37b63731
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64SUBWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AuxInt = c
+ return true
+ }
+ goto end135aa9100b2f61d58b37cede37b63731
+ end135aa9100b2f61d58b37cede37b63731:
+ ;
+ // match: (SUBW (MOVWconst [c]) x)
+ // cond:
+ // result: (NEGW (SUBWconst <v.Type> x [c]))
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end44d23f7e65a4b1c42d0e6463f8e493b6
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64NEGW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64SUBWconst, TypeInvalid)
+ v0.Type = v.Type
+ v0.AddArg(x)
+ v0.AuxInt = c
+ v.AddArg(v0)
+ return true
+ }
+ goto end44d23f7e65a4b1c42d0e6463f8e493b6
+ end44d23f7e65a4b1c42d0e6463f8e493b6:
+ ;
+ // match: (SUBW x x)
+ // cond:
+ // result: (MOVWconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto endb970e7c318d04a1afe1dfe08a7ca0d9c
+ }
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto endb970e7c318d04a1afe1dfe08a7ca0d9c
+ endb970e7c318d04a1afe1dfe08a7ca0d9c:
+ ;
+ case OpAMD64SUBWconst:
+ // match: (SUBWconst [c] (MOVWconst [d]))
+ // cond:
+ // result: (MOVWconst [d-c])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto endae629a229c399eaed7dbb95b1b0e6f8a
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = d - c
+ return true
+ }
+ goto endae629a229c399eaed7dbb95b1b0e6f8a
+ endae629a229c399eaed7dbb95b1b0e6f8a:
+ ;
+ // match: (SUBWconst [c] (SUBWconst [d] x))
+ // cond:
+ // result: (ADDWconst [-c-d] x)
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64SUBWconst {
+ goto enda59f08d12aa08717b0443b7bb1b71374
+ }
+ d := v.Args[0].AuxInt
+ x := v.Args[0].Args[0]
+ v.Op = OpAMD64ADDWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = -c - d
+ v.AddArg(x)
+ return true
+ }
+ goto enda59f08d12aa08717b0443b7bb1b71374
+ enda59f08d12aa08717b0443b7bb1b71374:
+ ;
+ case OpSignExt16to32:
+ // match: (SignExt16to32 x)
+ // cond:
+ // result: (MOVWQSX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVWQSX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end21e4271c2b48a5aa3561ccfa8fa67cd9
+ end21e4271c2b48a5aa3561ccfa8fa67cd9:
+ ;
+ case OpSignExt16to64:
+ // match: (SignExt16to64 x)
+ // cond:
+ // result: (MOVWQSX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVWQSX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endc6d242ee3a3e195ef0f9e8dae47ada75
+ endc6d242ee3a3e195ef0f9e8dae47ada75:
+ ;
+ case OpSignExt32to64:
+ // match: (SignExt32to64 x)
+ // cond:
+ // result: (MOVLQSX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVLQSX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endb9f1a8b2d01eee44964a71a01bca165c
+ endb9f1a8b2d01eee44964a71a01bca165c:
+ ;
+ case OpSignExt8to16:
+ // match: (SignExt8to16 x)
+ // cond:
+ // result: (MOVBQSX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVBQSX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end372869f08e147404b80634e5f83fd506
+ end372869f08e147404b80634e5f83fd506:
+ ;
+ case OpSignExt8to32:
+ // match: (SignExt8to32 x)
+ // cond:
+ // result: (MOVBQSX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVBQSX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end913e3575e5b4cf7f60585c108db40464
+ end913e3575e5b4cf7f60585c108db40464:
+ ;
+ case OpSignExt8to64:
+ // match: (SignExt8to64 x)
+ // cond:
+ // result: (MOVBQSX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVBQSX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endcef6d6001d3f25cf5dacee11a46e5c8c
+ endcef6d6001d3f25cf5dacee11a46e5c8c:
+ ;
+ case OpSqrt:
+ // match: (Sqrt x)
+ // cond:
+ // result: (SQRTSD x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64SQRTSD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end72f79ca9ec139e15856aaa03338cf543
+ end72f79ca9ec139e15856aaa03338cf543:
+ ;
+ case OpStaticCall:
+ // match: (StaticCall [argwid] {target} mem)
+ // cond:
+ // result: (CALLstatic [argwid] {target} mem)
+ {
+ argwid := v.AuxInt
+ target := v.Aux
+ mem := v.Args[0]
+ v.Op = OpAMD64CALLstatic
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = argwid
+ v.Aux = target
+ v.AddArg(mem)
+ return true
+ }
+ goto end32c5cbec813d1c2ae94fc9b1090e4b2a
+ end32c5cbec813d1c2ae94fc9b1090e4b2a:
+ ;
+ case OpStore:
+ // match: (Store [8] ptr val mem)
+ // cond: is64BitFloat(val.Type)
+ // result: (MOVSDstore ptr val mem)
+ {
+ if v.AuxInt != 8 {
+ goto endaeec4f61bc8e67dbf3fa2f79fe4c2b9e
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(is64BitFloat(val.Type)) {
+ goto endaeec4f61bc8e67dbf3fa2f79fe4c2b9e
+ }
+ v.Op = OpAMD64MOVSDstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endaeec4f61bc8e67dbf3fa2f79fe4c2b9e
+ endaeec4f61bc8e67dbf3fa2f79fe4c2b9e:
+ ;
+ // match: (Store [4] ptr val mem)
+ // cond: is32BitFloat(val.Type)
+ // result: (MOVSSstore ptr val mem)
+ {
+ if v.AuxInt != 4 {
+ goto endf638ca0a75871b5062da15324d0e0384
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(is32BitFloat(val.Type)) {
+ goto endf638ca0a75871b5062da15324d0e0384
+ }
+ v.Op = OpAMD64MOVSSstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endf638ca0a75871b5062da15324d0e0384
+ endf638ca0a75871b5062da15324d0e0384:
+ ;
+ // match: (Store [8] ptr val mem)
+ // cond:
+ // result: (MOVQstore ptr val mem)
+ {
+ if v.AuxInt != 8 {
+ goto endd1eb7c3ea0c806e7a53ff3be86186eb7
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endd1eb7c3ea0c806e7a53ff3be86186eb7
+ endd1eb7c3ea0c806e7a53ff3be86186eb7:
+ ;
+ // match: (Store [4] ptr val mem)
+ // cond:
+ // result: (MOVLstore ptr val mem)
+ {
+ if v.AuxInt != 4 {
+ goto end44e3b22360da76ecd59be9a8c2dd1347
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end44e3b22360da76ecd59be9a8c2dd1347
+ end44e3b22360da76ecd59be9a8c2dd1347:
+ ;
+ // match: (Store [2] ptr val mem)
+ // cond:
+ // result: (MOVWstore ptr val mem)
+ {
+ if v.AuxInt != 2 {
+ goto endd0342b7fd3d0713f3e26922660047c71
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto endd0342b7fd3d0713f3e26922660047c71
+ endd0342b7fd3d0713f3e26922660047c71:
+ ;
+ // match: (Store [1] ptr val mem)
+ // cond:
+ // result: (MOVBstore ptr val mem)
+ {
+ if v.AuxInt != 1 {
+ goto end8e76e20031197ca875889d2b4d0eb1d1
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
+ goto end8e76e20031197ca875889d2b4d0eb1d1
+ end8e76e20031197ca875889d2b4d0eb1d1:
+ ;
+ case OpSub16:
+ // match: (Sub16 x y)
+ // cond:
+ // result: (SUBW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end54adc5de883c0460ca71c6ee464d4244
+ end54adc5de883c0460ca71c6ee464d4244:
+ ;
+ case OpSub32:
+ // match: (Sub32 x y)
+ // cond:
+ // result: (SUBL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto enddc3a2a488bda8c5856f93343e5ffe5f8
+ enddc3a2a488bda8c5856f93343e5ffe5f8:
+ ;
+ case OpSub32F:
+ // match: (Sub32F x y)
+ // cond:
+ // result: (SUBSS x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBSS
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end20193c1804b0e707702a884fb8abd60d
+ end20193c1804b0e707702a884fb8abd60d:
+ ;
+ case OpSub64:
+ // match: (Sub64 x y)
+ // cond:
+ // result: (SUBQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endd88d5646309fd9174584888ecc8aca2c
+ endd88d5646309fd9174584888ecc8aca2c:
+ ;
+ case OpSub64F:
+ // match: (Sub64F x y)
+ // cond:
+ // result: (SUBSD x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBSD
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end5d5af7b8a3326bf9151f00a0013b73d7
+ end5d5af7b8a3326bf9151f00a0013b73d7:
+ ;
+ case OpSub8:
+ // match: (Sub8 x y)
+ // cond:
+ // result: (SUBB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end7d33bf9bdfa505f96b930563eca7955f
+ end7d33bf9bdfa505f96b930563eca7955f:
+ ;
+ case OpSubPtr:
+ // match: (SubPtr x y)
+ // cond:
+ // result: (SUBQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64SUBQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end748f63f755afe0b97a8f3cf7e4d9cbfe
+ end748f63f755afe0b97a8f3cf7e4d9cbfe:
+ ;
+ case OpTrunc16to8:
+ // match: (Trunc16to8 x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end8e2f5e0a6e3a06423c077747de6c2bdd
+ end8e2f5e0a6e3a06423c077747de6c2bdd:
+ ;
+ case OpTrunc32to16:
+ // match: (Trunc32to16 x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end5bed0e3a3c1c6374d86beb5a4397708c
+ end5bed0e3a3c1c6374d86beb5a4397708c:
+ ;
+ case OpTrunc32to8:
+ // match: (Trunc32to8 x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endef0b8032ce91979ce6cd0004260c04ee
+ endef0b8032ce91979ce6cd0004260c04ee:
+ ;
+ case OpTrunc64to16:
+ // match: (Trunc64to16 x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endd32fd6e0ce970c212835e6f71c3dcbfd
+ endd32fd6e0ce970c212835e6f71c3dcbfd:
+ ;
+ case OpTrunc64to32:
+ // match: (Trunc64to32 x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end1212c4e84153210aff7fd630fb3e1883
+ end1212c4e84153210aff7fd630fb3e1883:
+ ;
+ case OpTrunc64to8:
+ // match: (Trunc64to8 x)
+ // cond:
+ // result: x
+ {
+ x := v.Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end734f017d4b2810ca2288f7037365824c
+ end734f017d4b2810ca2288f7037365824c:
+ ;
+ case OpAMD64XORB:
+ // match: (XORB x (MOVBconst [c]))
+ // cond:
+ // result: (XORBconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVBconst {
+ goto enda9ed9fdd115ffdffa8127c007c34d7b7
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64XORBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto enda9ed9fdd115ffdffa8127c007c34d7b7
+ enda9ed9fdd115ffdffa8127c007c34d7b7:
+ ;
+ // match: (XORB (MOVBconst [c]) x)
+ // cond:
+ // result: (XORBconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto endb02a07d9dc7b802c59f013116e952f3f
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64XORBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endb02a07d9dc7b802c59f013116e952f3f
+ endb02a07d9dc7b802c59f013116e952f3f:
+ ;
+ // match: (XORB x x)
+ // cond:
+ // result: (MOVBconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end2afddc39503d04d572a3a07878f6c9c9
+ }
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end2afddc39503d04d572a3a07878f6c9c9
+ end2afddc39503d04d572a3a07878f6c9c9:
+ ;
+ case OpAMD64XORBconst:
+ // match: (XORBconst [c] (MOVBconst [d]))
+ // cond:
+ // result: (MOVBconst [c^d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVBconst {
+ goto end6d8d1b612af9d253605c8bc69b822903
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVBconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c ^ d
+ return true
+ }
+ goto end6d8d1b612af9d253605c8bc69b822903
+ end6d8d1b612af9d253605c8bc69b822903:
+ ;
+ case OpAMD64XORL:
+ // match: (XORL x (MOVLconst [c]))
+ // cond:
+ // result: (XORLconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVLconst {
+ goto enda9459d509d3416da67d13a22dd074a9c
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64XORLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto enda9459d509d3416da67d13a22dd074a9c
+ enda9459d509d3416da67d13a22dd074a9c:
+ ;
+ // match: (XORL (MOVLconst [c]) x)
+ // cond:
+ // result: (XORLconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end9c1a0af00eeadd8aa325e55f1f3fb89c
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64XORLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end9c1a0af00eeadd8aa325e55f1f3fb89c
+ end9c1a0af00eeadd8aa325e55f1f3fb89c:
+ ;
+ // match: (XORL x x)
+ // cond:
+ // result: (MOVLconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end7bcf9cfeb69a0d7647389124eb53ce2a
+ }
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end7bcf9cfeb69a0d7647389124eb53ce2a
+ end7bcf9cfeb69a0d7647389124eb53ce2a:
+ ;
+ case OpAMD64XORLconst:
+ // match: (XORLconst [c] (MOVLconst [d]))
+ // cond:
+ // result: (MOVLconst [c^d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVLconst {
+ goto end71238075b10b68a226903cc453c4715c
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVLconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c ^ d
+ return true
+ }
+ goto end71238075b10b68a226903cc453c4715c
+ end71238075b10b68a226903cc453c4715c:
+ ;
+ case OpAMD64XORQ:
+ // match: (XORQ x (MOVQconst [c]))
+ // cond: is32Bit(c)
+ // result: (XORQconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVQconst {
+ goto end452341f950062e0483f16438fb9ec500
+ }
+ c := v.Args[1].AuxInt
+ if !(is32Bit(c)) {
+ goto end452341f950062e0483f16438fb9ec500
+ }
+ v.Op = OpAMD64XORQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end452341f950062e0483f16438fb9ec500
+ end452341f950062e0483f16438fb9ec500:
+ ;
+ // match: (XORQ (MOVQconst [c]) x)
+ // cond: is32Bit(c)
+ // result: (XORQconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto endd221a7e3daaaaa29ee385ad36e061b57
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ if !(is32Bit(c)) {
+ goto endd221a7e3daaaaa29ee385ad36e061b57
+ }
+ v.Op = OpAMD64XORQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto endd221a7e3daaaaa29ee385ad36e061b57
+ endd221a7e3daaaaa29ee385ad36e061b57:
+ ;
+ // match: (XORQ x x)
+ // cond:
+ // result: (MOVQconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end10575a5d711cf14e6d4dffbb0e8dfaeb
+ }
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end10575a5d711cf14e6d4dffbb0e8dfaeb
+ end10575a5d711cf14e6d4dffbb0e8dfaeb:
+ ;
+ case OpAMD64XORQconst:
+ // match: (XORQconst [c] (MOVQconst [d]))
+ // cond:
+ // result: (MOVQconst [c^d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVQconst {
+ goto end3f404d4f07362319fbad2e1ba0827a9f
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVQconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c ^ d
+ return true
+ }
+ goto end3f404d4f07362319fbad2e1ba0827a9f
+ end3f404d4f07362319fbad2e1ba0827a9f:
+ ;
+ case OpAMD64XORW:
+ // match: (XORW x (MOVWconst [c]))
+ // cond:
+ // result: (XORWconst [c] x)
+ {
+ x := v.Args[0]
+ if v.Args[1].Op != OpAMD64MOVWconst {
+ goto end2ca109efd66c221a5691a4da95ec6c67
+ }
+ c := v.Args[1].AuxInt
+ v.Op = OpAMD64XORWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end2ca109efd66c221a5691a4da95ec6c67
+ end2ca109efd66c221a5691a4da95ec6c67:
+ ;
+ // match: (XORW (MOVWconst [c]) x)
+ // cond:
+ // result: (XORWconst [c] x)
+ {
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto end51ee62a06d4301e5a4aed7a6639b1d53
+ }
+ c := v.Args[0].AuxInt
+ x := v.Args[1]
+ v.Op = OpAMD64XORWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c
+ v.AddArg(x)
+ return true
+ }
+ goto end51ee62a06d4301e5a4aed7a6639b1d53
+ end51ee62a06d4301e5a4aed7a6639b1d53:
+ ;
+ // match: (XORW x x)
+ // cond:
+ // result: (MOVWconst [0])
+ {
+ x := v.Args[0]
+ if v.Args[1] != x {
+ goto end07f332e857be0c2707797ed480a2faf4
+ }
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = 0
+ return true
+ }
+ goto end07f332e857be0c2707797ed480a2faf4
+ end07f332e857be0c2707797ed480a2faf4:
+ ;
+ case OpAMD64XORWconst:
+ // match: (XORWconst [c] (MOVWconst [d]))
+ // cond:
+ // result: (MOVWconst [c^d])
+ {
+ c := v.AuxInt
+ if v.Args[0].Op != OpAMD64MOVWconst {
+ goto ende24881ccdfa8486c4593fd9aa5df1ed6
+ }
+ d := v.Args[0].AuxInt
+ v.Op = OpAMD64MOVWconst
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = c ^ d
+ return true
+ }
+ goto ende24881ccdfa8486c4593fd9aa5df1ed6
+ ende24881ccdfa8486c4593fd9aa5df1ed6:
+ ;
+ case OpXor16:
+ // match: (Xor16 x y)
+ // cond:
+ // result: (XORW x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64XORW
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end20efdd5dfd5130abf818de5546a991a0
+ end20efdd5dfd5130abf818de5546a991a0:
+ ;
+ case OpXor32:
+ // match: (Xor32 x y)
+ // cond:
+ // result: (XORL x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64XORL
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end9da6bce98b437e2609488346116a75d8
+ end9da6bce98b437e2609488346116a75d8:
+ ;
+ case OpXor64:
+ // match: (Xor64 x y)
+ // cond:
+ // result: (XORQ x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64XORQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto endc88cd189c2a6f07ecff324ed94809f8f
+ endc88cd189c2a6f07ecff324ed94809f8f:
+ ;
+ case OpXor8:
+ // match: (Xor8 x y)
+ // cond:
+ // result: (XORB x y)
+ {
+ x := v.Args[0]
+ y := v.Args[1]
+ v.Op = OpAMD64XORB
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ goto end50f4434ef96916d3e65ad3cc236d1723
+ end50f4434ef96916d3e65ad3cc236d1723:
+ ;
+ case OpZero:
+ // match: (Zero [0] _ mem)
+ // cond:
+ // result: mem
+ {
+ if v.AuxInt != 0 {
+ goto endc9a38a60f0322f93682daa824611272c
+ }
+ mem := v.Args[1]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = mem.Type
+ v.AddArg(mem)
+ return true
+ }
+ goto endc9a38a60f0322f93682daa824611272c
+ endc9a38a60f0322f93682daa824611272c:
+ ;
+ // match: (Zero [1] destptr mem)
+ // cond:
+ // result: (MOVBstore destptr (MOVBconst [0]) mem)
+ {
+ if v.AuxInt != 1 {
+ goto endf7c8ca6a444f19e1142977e2ac42ab24
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(destptr)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVBconst, TypeInvalid)
+ v0.AuxInt = 0
+ v0.Type = config.fe.TypeUInt8()
+ v.AddArg(v0)
+ v.AddArg(mem)
+ return true
+ }
+ goto endf7c8ca6a444f19e1142977e2ac42ab24
+ endf7c8ca6a444f19e1142977e2ac42ab24:
+ ;
+ // match: (Zero [2] destptr mem)
+ // cond:
+ // result: (MOVWstore destptr (MOVWconst [0]) mem)
+ {
+ if v.AuxInt != 2 {
+ goto end7609a67450ab21eba86f456886fc8496
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(destptr)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVWconst, TypeInvalid)
+ v0.AuxInt = 0
+ v0.Type = config.fe.TypeUInt16()
+ v.AddArg(v0)
+ v.AddArg(mem)
+ return true
+ }
+ goto end7609a67450ab21eba86f456886fc8496
+ end7609a67450ab21eba86f456886fc8496:
+ ;
+ // match: (Zero [4] destptr mem)
+ // cond:
+ // result: (MOVLstore destptr (MOVLconst [0]) mem)
+ {
+ if v.AuxInt != 4 {
+ goto enda8e1cf1298794cc3cb79cab108e33007
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(destptr)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVLconst, TypeInvalid)
+ v0.AuxInt = 0
+ v0.Type = config.fe.TypeUInt32()
+ v.AddArg(v0)
+ v.AddArg(mem)
+ return true
+ }
+ goto enda8e1cf1298794cc3cb79cab108e33007
+ enda8e1cf1298794cc3cb79cab108e33007:
+ ;
+ // match: (Zero [8] destptr mem)
+ // cond:
+ // result: (MOVQstore destptr (MOVQconst [0]) mem)
+ {
+ if v.AuxInt != 8 {
+ goto end1791556f0b03ea065d38a3267fbe01c6
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(destptr)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v0.AuxInt = 0
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v.AddArg(mem)
+ return true
+ }
+ goto end1791556f0b03ea065d38a3267fbe01c6
+ end1791556f0b03ea065d38a3267fbe01c6:
+ ;
+ // match: (Zero [3] destptr mem)
+ // cond:
+ // result: (MOVBstore (ADDQconst [2] destptr) (MOVBconst [0]) (MOVWstore destptr (MOVWconst [0]) mem))
+ {
+ if v.AuxInt != 3 {
+ goto end7f8f5c8214f8b81a73fdde78b03ce53c
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 2
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVBconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt8()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVWstore, TypeInvalid)
+ v2.AddArg(destptr)
+ v3 := b.NewValue0(v.Line, OpAMD64MOVWconst, TypeInvalid)
+ v3.AuxInt = 0
+ v3.Type = config.fe.TypeUInt16()
+ v2.AddArg(v3)
+ v2.AddArg(mem)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto end7f8f5c8214f8b81a73fdde78b03ce53c
+ end7f8f5c8214f8b81a73fdde78b03ce53c:
+ ;
+ // match: (Zero [5] destptr mem)
+ // cond:
+ // result: (MOVBstore (ADDQconst [4] destptr) (MOVBconst [0]) (MOVLstore destptr (MOVLconst [0]) mem))
+ {
+ if v.AuxInt != 5 {
+ goto end54466baa4eac09020bee720efbb82d0f
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVBstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 4
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVBconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt8()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVLstore, TypeInvalid)
+ v2.AddArg(destptr)
+ v3 := b.NewValue0(v.Line, OpAMD64MOVLconst, TypeInvalid)
+ v3.AuxInt = 0
+ v3.Type = config.fe.TypeUInt32()
+ v2.AddArg(v3)
+ v2.AddArg(mem)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto end54466baa4eac09020bee720efbb82d0f
+ end54466baa4eac09020bee720efbb82d0f:
+ ;
+ // match: (Zero [6] destptr mem)
+ // cond:
+ // result: (MOVWstore (ADDQconst [4] destptr) (MOVWconst [0]) (MOVLstore destptr (MOVLconst [0]) mem))
+ {
+ if v.AuxInt != 6 {
+ goto end3a37ae6095ddc37646d6ad6eeda986e2
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVWstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 4
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVWconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt16()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVLstore, TypeInvalid)
+ v2.AddArg(destptr)
+ v3 := b.NewValue0(v.Line, OpAMD64MOVLconst, TypeInvalid)
+ v3.AuxInt = 0
+ v3.Type = config.fe.TypeUInt32()
+ v2.AddArg(v3)
+ v2.AddArg(mem)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto end3a37ae6095ddc37646d6ad6eeda986e2
+ end3a37ae6095ddc37646d6ad6eeda986e2:
+ ;
+ // match: (Zero [7] destptr mem)
+ // cond:
+ // result: (MOVLstore (ADDQconst [3] destptr) (MOVLconst [0]) (MOVLstore destptr (MOVLconst [0]) mem))
+ {
+ if v.AuxInt != 7 {
+ goto endd53a750fa01c5a5a238ba8fcabb416b2
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVLstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 3
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVLconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt32()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVLstore, TypeInvalid)
+ v2.AddArg(destptr)
+ v3 := b.NewValue0(v.Line, OpAMD64MOVLconst, TypeInvalid)
+ v3.AuxInt = 0
+ v3.Type = config.fe.TypeUInt32()
+ v2.AddArg(v3)
+ v2.AddArg(mem)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto endd53a750fa01c5a5a238ba8fcabb416b2
+ endd53a750fa01c5a5a238ba8fcabb416b2:
+ ;
+ // match: (Zero [size] destptr mem)
+ // cond: size%8 != 0 && size > 8
+ // result: (Zero [size-size%8] (ADDQconst destptr [size%8]) (MOVQstore destptr (MOVQconst [0]) mem))
+ {
+ size := v.AuxInt
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ if !(size%8 != 0 && size > 8) {
+ goto end5efefe1d9cca07e7ad6f4832f774b938
+ }
+ v.Op = OpZero
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = size - size%8
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AddArg(destptr)
+ v0.AuxInt = size % 8
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v1.AddArg(destptr)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v2.AuxInt = 0
+ v2.Type = config.fe.TypeUInt64()
+ v1.AddArg(v2)
+ v1.AddArg(mem)
+ v1.Type = TypeMem
+ v.AddArg(v1)
+ return true
+ }
+ goto end5efefe1d9cca07e7ad6f4832f774b938
+ end5efefe1d9cca07e7ad6f4832f774b938:
+ ;
+ // match: (Zero [16] destptr mem)
+ // cond:
+ // result: (MOVQstore (ADDQconst [8] destptr) (MOVQconst [0]) (MOVQstore destptr (MOVQconst [0]) mem))
+ {
+ if v.AuxInt != 16 {
+ goto endad489c16378959a764292e8b1cb72ba2
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 8
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt64()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v2.AddArg(destptr)
+ v3 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v3.AuxInt = 0
+ v3.Type = config.fe.TypeUInt64()
+ v2.AddArg(v3)
+ v2.AddArg(mem)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto endad489c16378959a764292e8b1cb72ba2
+ endad489c16378959a764292e8b1cb72ba2:
+ ;
+ // match: (Zero [24] destptr mem)
+ // cond:
+ // result: (MOVQstore (ADDQconst [16] destptr) (MOVQconst [0]) (MOVQstore (ADDQconst [8] destptr) (MOVQconst [0]) (MOVQstore destptr (MOVQconst [0]) mem)))
+ {
+ if v.AuxInt != 24 {
+ goto enddc443320a1be0b3c2e213bd6778197dd
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 16
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt64()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v3 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v3.AuxInt = 8
+ v3.AddArg(destptr)
+ v3.Type = config.fe.TypeUInt64()
+ v2.AddArg(v3)
+ v4 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v4.AuxInt = 0
+ v4.Type = config.fe.TypeUInt64()
+ v2.AddArg(v4)
+ v5 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v5.AddArg(destptr)
+ v6 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v6.AuxInt = 0
+ v6.Type = config.fe.TypeUInt64()
+ v5.AddArg(v6)
+ v5.AddArg(mem)
+ v5.Type = TypeMem
+ v2.AddArg(v5)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto enddc443320a1be0b3c2e213bd6778197dd
+ enddc443320a1be0b3c2e213bd6778197dd:
+ ;
+ // match: (Zero [32] destptr mem)
+ // cond:
+ // result: (MOVQstore (ADDQconst [24] destptr) (MOVQconst [0]) (MOVQstore (ADDQconst [16] destptr) (MOVQconst [0]) (MOVQstore (ADDQconst [8] destptr) (MOVQconst [0]) (MOVQstore destptr (MOVQconst [0]) mem))))
+ {
+ if v.AuxInt != 32 {
+ goto end282b5e36693f06e2cd1ac563e0d419b5
+ }
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ v.Op = OpAMD64MOVQstore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = 24
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt64()
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v3 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v3.AuxInt = 16
+ v3.AddArg(destptr)
+ v3.Type = config.fe.TypeUInt64()
+ v2.AddArg(v3)
+ v4 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v4.AuxInt = 0
+ v4.Type = config.fe.TypeUInt64()
+ v2.AddArg(v4)
+ v5 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v6 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v6.AuxInt = 8
+ v6.AddArg(destptr)
+ v6.Type = config.fe.TypeUInt64()
+ v5.AddArg(v6)
+ v7 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v7.AuxInt = 0
+ v7.Type = config.fe.TypeUInt64()
+ v5.AddArg(v7)
+ v8 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
+ v8.AddArg(destptr)
+ v9 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v9.AuxInt = 0
+ v9.Type = config.fe.TypeUInt64()
+ v8.AddArg(v9)
+ v8.AddArg(mem)
+ v8.Type = TypeMem
+ v5.AddArg(v8)
+ v5.Type = TypeMem
+ v2.AddArg(v5)
+ v2.Type = TypeMem
+ v.AddArg(v2)
+ return true
+ }
+ goto end282b5e36693f06e2cd1ac563e0d419b5
+ end282b5e36693f06e2cd1ac563e0d419b5:
+ ;
+ // match: (Zero [size] destptr mem)
- if !(size <= 1024 && size%8 == 0) {
- goto endfae59ebc96f670276efea844c3b302ac
++ // cond: size <= 1024 && size%8 == 0 && size%16 != 0
++ // result: (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
+ {
+ size := v.AuxInt
+ destptr := v.Args[0]
+ mem := v.Args[1]
- v1 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
++ if !(size <= 1024 && size%8 == 0 && size%16 != 0) {
++ goto end240266449c3e493db1c3b38a78682ff0
++ }
++ v.Op = OpZero
++ v.AuxInt = 0
++ v.Aux = nil
++ v.resetArgs()
++ v.AuxInt = size - 8
++ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
++ v0.AuxInt = 8
++ v0.AddArg(destptr)
++ v0.Type = config.fe.TypeUInt64()
++ v.AddArg(v0)
++ v1 := b.NewValue0(v.Line, OpAMD64MOVQstore, TypeInvalid)
++ v1.AddArg(destptr)
++ v2 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
++ v2.AuxInt = 0
++ v2.Type = config.fe.TypeUInt64()
++ v1.AddArg(v2)
++ v1.AddArg(mem)
++ v1.Type = TypeMem
++ v.AddArg(v1)
++ return true
++ }
++ goto end240266449c3e493db1c3b38a78682ff0
++ end240266449c3e493db1c3b38a78682ff0:
++ ;
++ // match: (Zero [size] destptr mem)
++ // cond: size <= 1024 && size%16 == 0
++ // result: (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem)
++ {
++ size := v.AuxInt
++ destptr := v.Args[0]
++ mem := v.Args[1]
++ if !(size <= 1024 && size%16 == 0) {
++ goto endf508bb887eee9119069b22c23dbca138
+ }
+ v.Op = OpAMD64DUFFZERO
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = duffStart(size)
+ v0 := b.NewValue0(v.Line, OpAMD64ADDQconst, TypeInvalid)
+ v0.AuxInt = duffAdj(size)
+ v0.AddArg(destptr)
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
- v1.Type = config.fe.TypeUInt64()
++ v1 := b.NewValue0(v.Line, OpAMD64MOVOconst, TypeInvalid)
+ v1.AuxInt = 0
- goto endfae59ebc96f670276efea844c3b302ac
- endfae59ebc96f670276efea844c3b302ac:
++ v1.Type = config.fe.TypeFloat64()
+ v.AddArg(v1)
+ v.AddArg(mem)
+ return true
+ }
++ goto endf508bb887eee9119069b22c23dbca138
++ endf508bb887eee9119069b22c23dbca138:
+ ;
+ // match: (Zero [size] destptr mem)
+ // cond: size > 1024 && size%8 == 0
+ // result: (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem)
+ {
+ size := v.AuxInt
+ destptr := v.Args[0]
+ mem := v.Args[1]
+ if !(size > 1024 && size%8 == 0) {
+ goto endb9d55d4ba0e70ed918e3ac757727441b
+ }
+ v.Op = OpAMD64REPSTOSQ
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(destptr)
+ v0 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v0.AuxInt = size / 8
+ v0.Type = config.fe.TypeUInt64()
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpAMD64MOVQconst, TypeInvalid)
+ v1.AuxInt = 0
+ v1.Type = config.fe.TypeUInt64()
+ v.AddArg(v1)
+ v.AddArg(mem)
+ return true
+ }
+ goto endb9d55d4ba0e70ed918e3ac757727441b
+ endb9d55d4ba0e70ed918e3ac757727441b:
+ ;
+ case OpZeroExt16to32:
+ // match: (ZeroExt16to32 x)
+ // cond:
+ // result: (MOVWQZX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVWQZX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endbfff79412a2cc96095069c66812844b4
+ endbfff79412a2cc96095069c66812844b4:
+ ;
+ case OpZeroExt16to64:
+ // match: (ZeroExt16to64 x)
+ // cond:
+ // result: (MOVWQZX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVWQZX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end7a40262c5c856101058d2bd518ed0910
+ end7a40262c5c856101058d2bd518ed0910:
+ ;
+ case OpZeroExt32to64:
+ // match: (ZeroExt32to64 x)
+ // cond:
+ // result: (MOVLQZX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVLQZX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto enddf83bdc8cc6c5673a9ef7aca7affe45a
+ enddf83bdc8cc6c5673a9ef7aca7affe45a:
+ ;
+ case OpZeroExt8to16:
+ // match: (ZeroExt8to16 x)
+ // cond:
+ // result: (MOVBQZX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVBQZX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endd03d53d2a585727e4107ae1a3cc55479
+ endd03d53d2a585727e4107ae1a3cc55479:
+ ;
+ case OpZeroExt8to32:
+ // match: (ZeroExt8to32 x)
+ // cond:
+ // result: (MOVBQZX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVBQZX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto endcbd33e965b3dab14fced5ae93d8949de
+ endcbd33e965b3dab14fced5ae93d8949de:
+ ;
+ case OpZeroExt8to64:
+ // match: (ZeroExt8to64 x)
+ // cond:
+ // result: (MOVBQZX x)
+ {
+ x := v.Args[0]
+ v.Op = OpAMD64MOVBQZX
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AddArg(x)
+ return true
+ }
+ goto end63ae7cc15db9d15189b2f1342604b2cb
+ end63ae7cc15db9d15189b2f1342604b2cb:
+ }
+ return false
+}
+func rewriteBlockAMD64(b *Block) bool {
+ switch b.Kind {
+ case BlockAMD64EQ:
+ // match: (EQ (InvertFlags cmp) yes no)
+ // cond:
+ // result: (EQ cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end6b8e9afc73b1c4d528f31a60d2575fae
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64EQ
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end6b8e9afc73b1c4d528f31a60d2575fae
+ end6b8e9afc73b1c4d528f31a60d2575fae:
+ ;
+ case BlockAMD64GE:
+ // match: (GE (InvertFlags cmp) yes no)
+ // cond:
+ // result: (LE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end0610f000a6988ee8310307ec2ea138f8
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64LE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end0610f000a6988ee8310307ec2ea138f8
+ end0610f000a6988ee8310307ec2ea138f8:
+ ;
+ case BlockAMD64GT:
+ // match: (GT (InvertFlags cmp) yes no)
+ // cond:
+ // result: (LT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto endf60c0660b6a8aa9565c97fc87f04eb34
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64LT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endf60c0660b6a8aa9565c97fc87f04eb34
+ endf60c0660b6a8aa9565c97fc87f04eb34:
+ ;
+ case BlockIf:
+ // match: (If (SETL cmp) yes no)
+ // cond:
+ // result: (LT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETL {
+ goto end94277282f4b83f0c035b23711a075801
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64LT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end94277282f4b83f0c035b23711a075801
+ end94277282f4b83f0c035b23711a075801:
+ ;
+ // match: (If (SETLE cmp) yes no)
+ // cond:
+ // result: (LE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETLE {
+ goto enda84798dd797927b54a9a2987421b2ba2
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64LE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto enda84798dd797927b54a9a2987421b2ba2
+ enda84798dd797927b54a9a2987421b2ba2:
+ ;
+ // match: (If (SETG cmp) yes no)
+ // cond:
+ // result: (GT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETG {
+ goto end3434ef985979cbf394455ab5b559567c
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64GT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end3434ef985979cbf394455ab5b559567c
+ end3434ef985979cbf394455ab5b559567c:
+ ;
+ // match: (If (SETGE cmp) yes no)
+ // cond:
+ // result: (GE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETGE {
+ goto endee147d81d8620a5e23cb92bd9f13cf8d
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64GE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endee147d81d8620a5e23cb92bd9f13cf8d
+ endee147d81d8620a5e23cb92bd9f13cf8d:
+ ;
+ // match: (If (SETEQ cmp) yes no)
+ // cond:
+ // result: (EQ cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETEQ {
+ goto ende7d85ccc850fc3963c50a91df096de17
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64EQ
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto ende7d85ccc850fc3963c50a91df096de17
+ ende7d85ccc850fc3963c50a91df096de17:
+ ;
+ // match: (If (SETNE cmp) yes no)
+ // cond:
+ // result: (NE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETNE {
+ goto endba4b54260ecda1b5731b129c0eb493d0
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64NE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endba4b54260ecda1b5731b129c0eb493d0
+ endba4b54260ecda1b5731b129c0eb493d0:
+ ;
+ // match: (If (SETB cmp) yes no)
+ // cond:
+ // result: (ULT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETB {
+ goto endf84eedfcd3f18f5c9c3f3d1045a24330
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64ULT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endf84eedfcd3f18f5c9c3f3d1045a24330
+ endf84eedfcd3f18f5c9c3f3d1045a24330:
+ ;
+ // match: (If (SETBE cmp) yes no)
+ // cond:
+ // result: (ULE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETBE {
+ goto endfe0178f6f4406945ca8966817d04be60
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64ULE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endfe0178f6f4406945ca8966817d04be60
+ endfe0178f6f4406945ca8966817d04be60:
+ ;
+ // match: (If (SETA cmp) yes no)
+ // cond:
+ // result: (UGT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETA {
+ goto end2b5a2d7756bdba01a732bf54d9acdb73
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end2b5a2d7756bdba01a732bf54d9acdb73
+ end2b5a2d7756bdba01a732bf54d9acdb73:
+ ;
+ // match: (If (SETAE cmp) yes no)
+ // cond:
+ // result: (UGE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETAE {
+ goto end9bea9963c3c5dfb97249a5feb8287f94
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end9bea9963c3c5dfb97249a5feb8287f94
+ end9bea9963c3c5dfb97249a5feb8287f94:
+ ;
+ // match: (If (SETGF cmp) yes no)
+ // cond:
+ // result: (UGT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETGF {
+ goto enda72d68674cfa26b5982a43756bca6767
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto enda72d68674cfa26b5982a43756bca6767
+ enda72d68674cfa26b5982a43756bca6767:
+ ;
+ // match: (If (SETGEF cmp) yes no)
+ // cond:
+ // result: (UGE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETGEF {
+ goto endccc171c1d66dd60ac0275d1f78259315
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endccc171c1d66dd60ac0275d1f78259315
+ endccc171c1d66dd60ac0275d1f78259315:
+ ;
+ // match: (If (SETEQF cmp) yes no)
+ // cond:
+ // result: (EQF cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETEQF {
+ goto end58cb74d05266a79003ebdd733afb66fa
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64EQF
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end58cb74d05266a79003ebdd733afb66fa
+ end58cb74d05266a79003ebdd733afb66fa:
+ ;
+ // match: (If (SETNEF cmp) yes no)
+ // cond:
+ // result: (EQF cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64SETNEF {
+ goto endfe25939ca97349543bc2d2ce4f97ba41
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64EQF
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endfe25939ca97349543bc2d2ce4f97ba41
+ endfe25939ca97349543bc2d2ce4f97ba41:
+ ;
+ // match: (If cond yes no)
+ // cond:
+ // result: (NE (TESTB cond cond) yes no)
+ {
+ v := b.Control
+ cond := v
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64NE
+ v0 := b.NewValue0(v.Line, OpAMD64TESTB, TypeInvalid)
+ v0.AddArg(cond)
+ v0.AddArg(cond)
+ v0.Type = TypeFlags
+ b.Control = v0
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end5bdbb8d5ea62ff2a76dccf3f9e89d94d
+ end5bdbb8d5ea62ff2a76dccf3f9e89d94d:
+ ;
+ case BlockAMD64LE:
+ // match: (LE (InvertFlags cmp) yes no)
+ // cond:
+ // result: (GE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end0d49d7d087fe7578e8015cf13dae37e3
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64GE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end0d49d7d087fe7578e8015cf13dae37e3
+ end0d49d7d087fe7578e8015cf13dae37e3:
+ ;
+ case BlockAMD64LT:
+ // match: (LT (InvertFlags cmp) yes no)
+ // cond:
+ // result: (GT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end6a408cde0fee0ae7b7da0443c8d902bf
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64GT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end6a408cde0fee0ae7b7da0443c8d902bf
+ end6a408cde0fee0ae7b7da0443c8d902bf:
+ ;
+ case BlockAMD64NE:
+ // match: (NE (TESTB (SETL cmp)) yes no)
+ // cond:
+ // result: (LT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end0b9ca165d6b395de676eebef94bc62f7
+ }
+ if v.Args[0].Op != OpAMD64SETL {
+ goto end0b9ca165d6b395de676eebef94bc62f7
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64LT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end0b9ca165d6b395de676eebef94bc62f7
+ end0b9ca165d6b395de676eebef94bc62f7:
+ ;
+ // match: (NE (TESTB (SETLE cmp)) yes no)
+ // cond:
+ // result: (LE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto endaaba0ee4d0ff8c66a1c3107d2a14c4bc
+ }
+ if v.Args[0].Op != OpAMD64SETLE {
+ goto endaaba0ee4d0ff8c66a1c3107d2a14c4bc
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64LE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endaaba0ee4d0ff8c66a1c3107d2a14c4bc
+ endaaba0ee4d0ff8c66a1c3107d2a14c4bc:
+ ;
+ // match: (NE (TESTB (SETG cmp)) yes no)
+ // cond:
+ // result: (GT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end1b689463137526b36ba9ceed1e76e512
+ }
+ if v.Args[0].Op != OpAMD64SETG {
+ goto end1b689463137526b36ba9ceed1e76e512
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64GT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end1b689463137526b36ba9ceed1e76e512
+ end1b689463137526b36ba9ceed1e76e512:
+ ;
+ // match: (NE (TESTB (SETGE cmp)) yes no)
+ // cond:
+ // result: (GE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end99eefee595c658b997f41577ed853c2e
+ }
+ if v.Args[0].Op != OpAMD64SETGE {
+ goto end99eefee595c658b997f41577ed853c2e
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64GE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end99eefee595c658b997f41577ed853c2e
+ end99eefee595c658b997f41577ed853c2e:
+ ;
+ // match: (NE (TESTB (SETEQ cmp)) yes no)
+ // cond:
+ // result: (EQ cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end371b67d3d63e9b92d848b09c3324e8b9
+ }
+ if v.Args[0].Op != OpAMD64SETEQ {
+ goto end371b67d3d63e9b92d848b09c3324e8b9
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64EQ
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end371b67d3d63e9b92d848b09c3324e8b9
+ end371b67d3d63e9b92d848b09c3324e8b9:
+ ;
+ // match: (NE (TESTB (SETNE cmp)) yes no)
+ // cond:
+ // result: (NE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto endd245f2aac2191d32e57cd2e321daa453
+ }
+ if v.Args[0].Op != OpAMD64SETNE {
+ goto endd245f2aac2191d32e57cd2e321daa453
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64NE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endd245f2aac2191d32e57cd2e321daa453
+ endd245f2aac2191d32e57cd2e321daa453:
+ ;
+ // match: (NE (TESTB (SETB cmp)) yes no)
+ // cond:
+ // result: (ULT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end90c4bec851e734d37457d611b1a5ff28
+ }
+ if v.Args[0].Op != OpAMD64SETB {
+ goto end90c4bec851e734d37457d611b1a5ff28
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64ULT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end90c4bec851e734d37457d611b1a5ff28
+ end90c4bec851e734d37457d611b1a5ff28:
+ ;
+ // match: (NE (TESTB (SETBE cmp)) yes no)
+ // cond:
+ // result: (ULE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end3a68a28114e9b89ee0708823386bc1ee
+ }
+ if v.Args[0].Op != OpAMD64SETBE {
+ goto end3a68a28114e9b89ee0708823386bc1ee
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64ULE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end3a68a28114e9b89ee0708823386bc1ee
+ end3a68a28114e9b89ee0708823386bc1ee:
+ ;
+ // match: (NE (TESTB (SETA cmp)) yes no)
+ // cond:
+ // result: (UGT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end16496f57185756e960d536b057c776c0
+ }
+ if v.Args[0].Op != OpAMD64SETA {
+ goto end16496f57185756e960d536b057c776c0
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end16496f57185756e960d536b057c776c0
+ end16496f57185756e960d536b057c776c0:
+ ;
+ // match: (NE (TESTB (SETAE cmp)) yes no)
+ // cond:
+ // result: (UGE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto endbd122fd599aeb9e60881a0fa735e2fde
+ }
+ if v.Args[0].Op != OpAMD64SETAE {
+ goto endbd122fd599aeb9e60881a0fa735e2fde
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endbd122fd599aeb9e60881a0fa735e2fde
+ endbd122fd599aeb9e60881a0fa735e2fde:
+ ;
+ // match: (NE (TESTB (SETGF cmp)) yes no)
+ // cond:
+ // result: (UGT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto endb2499521f7f351e24757f8c918c3598e
+ }
+ if v.Args[0].Op != OpAMD64SETGF {
+ goto endb2499521f7f351e24757f8c918c3598e
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endb2499521f7f351e24757f8c918c3598e
+ endb2499521f7f351e24757f8c918c3598e:
+ ;
+ // match: (NE (TESTB (SETGEF cmp)) yes no)
+ // cond:
+ // result: (UGE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end20461774babea665c4ca7c4f790a7209
+ }
+ if v.Args[0].Op != OpAMD64SETGEF {
+ goto end20461774babea665c4ca7c4f790a7209
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end20461774babea665c4ca7c4f790a7209
+ end20461774babea665c4ca7c4f790a7209:
+ ;
+ // match: (NE (TESTB (SETEQF cmp)) yes no)
+ // cond:
+ // result: (EQF cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto end236616ef13d489b78736cda7bcc1d168
+ }
+ if v.Args[0].Op != OpAMD64SETEQF {
+ goto end236616ef13d489b78736cda7bcc1d168
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64EQF
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end236616ef13d489b78736cda7bcc1d168
+ end236616ef13d489b78736cda7bcc1d168:
+ ;
+ // match: (NE (TESTB (SETNEF cmp)) yes no)
+ // cond:
+ // result: (NEF cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64TESTB {
+ goto endc992f3c266b16cb5f6aa98faa8f55600
+ }
+ if v.Args[0].Op != OpAMD64SETNEF {
+ goto endc992f3c266b16cb5f6aa98faa8f55600
+ }
+ cmp := v.Args[0].Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64NEF
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endc992f3c266b16cb5f6aa98faa8f55600
+ endc992f3c266b16cb5f6aa98faa8f55600:
+ ;
+ // match: (NE (InvertFlags cmp) yes no)
+ // cond:
+ // result: (NE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end713001aba794e50b582fbff930e110af
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64NE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end713001aba794e50b582fbff930e110af
+ end713001aba794e50b582fbff930e110af:
+ ;
+ case BlockAMD64UGE:
+ // match: (UGE (InvertFlags cmp) yes no)
+ // cond:
+ // result: (ULE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto ende3e4ddc183ca1a46598b11c2d0d13966
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64ULE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto ende3e4ddc183ca1a46598b11c2d0d13966
+ ende3e4ddc183ca1a46598b11c2d0d13966:
+ ;
+ case BlockAMD64UGT:
+ // match: (UGT (InvertFlags cmp) yes no)
+ // cond:
+ // result: (ULT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end49818853af2e5251175d06c62768cae7
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64ULT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end49818853af2e5251175d06c62768cae7
+ end49818853af2e5251175d06c62768cae7:
+ ;
+ case BlockAMD64ULE:
+ // match: (ULE (InvertFlags cmp) yes no)
+ // cond:
+ // result: (UGE cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto endd6698aac0d67261293b558c95ea17b4f
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGE
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto endd6698aac0d67261293b558c95ea17b4f
+ endd6698aac0d67261293b558c95ea17b4f:
+ ;
+ case BlockAMD64ULT:
+ // match: (ULT (InvertFlags cmp) yes no)
+ // cond:
+ // result: (UGT cmp yes no)
+ {
+ v := b.Control
+ if v.Op != OpAMD64InvertFlags {
+ goto end35105dbc9646f02577167e45ae2f2fd2
+ }
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockAMD64UGT
+ b.Control = cmp
+ b.Succs[0] = yes
+ b.Succs[1] = no
+ return true
+ }
+ goto end35105dbc9646f02577167e45ae2f2fd2
+ end35105dbc9646f02577167e45ae2f2fd2:
+ }
+ return false
+}
}
}
- expected := []struct{
- Id asn1.ObjectIdentifier
+ func TestCriticalFlagInCSRRequestedExtensions(t *testing.T) {
+ // This CSR contains an extension request where the extensions have a
+ // critical flag in them. In the past we failed to handle this.
+ const csrBase64 = "MIICrTCCAZUCAQIwMzEgMB4GA1UEAwwXU0NFUCBDQSBmb3IgRGV2ZWxlciBTcmwxDzANBgNVBAsMBjQzNTk3MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALFMAJ7Zy9YyfgbNlbUWAW0LalNRMPs7aXmLANsCpjhnw3lLlfDPaLeWyKh1nK5I5ojaJOW6KIOSAcJkDUe3rrE0wR0RVt3UxArqs0R/ND3u5Q+bDQY2X1HAFUHzUzcdm5JRAIA355v90teMckaWAIlkRQjDE22Lzc6NAl64KOd1rqOUNj8+PfX6fSo20jm94Pp1+a6mfk3G/RUWVuSm7owO5DZI/Fsi2ijdmb4NUar6K/bDKYTrDFkzcqAyMfP3TitUtBp19Mp3B1yAlHjlbp/r5fSSXfOGHZdgIvp0WkLuK2u5eQrX5l7HMB/5epgUs3HQxKY6ljhh5wAjDwz//LsCAwEAAaA1MDMGCSqGSIb3DQEJDjEmMCQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQEFBQADggEBAAMq3bxJSPQEgzLYR/yaVvgjCDrc3zUbIwdOis6Go06Q4RnjH5yRaSZAqZQTDsPurQcnz2I39VMGEiSkFJFavf4QHIZ7QFLkyXadMtALc87tm17Ej719SbHcBSSZayR9VYJUNXRLayI6HvyUrmqcMKh+iX3WY3ICr59/wlM0tYa8DYN4yzmOa2Onb29gy3YlaF5A2AKAMmk003cRT9gY26mjpv7d21czOSSeNyVIoZ04IR9ee71vWTMdv0hu/af5kSjQ+ZG5/Qgc0+mnECLz/1gtxt1srLYbtYQ/qAY8oX1DCSGFS61tN/vl+4cxGMD/VGcGzADRLRHSlVqy2Qgss6Q="
+
+ csrBytes := fromBase64(csrBase64)
+ csr, err := ParseCertificateRequest(csrBytes)
+ if err != nil {
+ t.Fatalf("failed to parse CSR: %s", err)
+ }
+
++ expected := []struct {
++ Id asn1.ObjectIdentifier
+ Value []byte
+ }{
+ {oidExtensionBasicConstraints, fromBase64("MAYBAf8CAQA=")},
+ {oidExtensionKeyUsage, fromBase64("AwIChA==")},
+ }
+
+ if n := len(csr.Extensions); n != len(expected) {
+ t.Fatalf("expected to find %d extensions but found %d", len(expected), n)
+ }
+
+ for i, extension := range csr.Extensions {
+ if !extension.Id.Equal(expected[i].Id) {
+ t.Fatalf("extension #%d has unexpected type %v (expected %v)", i, extension.Id, expected[i].Id)
+ }
+
+ if !bytes.Equal(extension.Value, expected[i].Value) {
+ t.Fatalf("extension #%d has unexpected contents %x (expected %x)", i, extension.Value, expected[i].Value)
+ }
+ }
+ }
+
func TestMaxPathLen(t *testing.T) {
block, _ := pem.Decode([]byte(pemPrivateKey))
rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
}
var modfSC = [][2]float64{
{Inf(-1), NaN()}, // [2]float64{Copysign(0, -1), Inf(-1)},
- {Inf(1), NaN()}, // [2]float64{0, Inf(1)},
+ {Copysign(0, -1), Copysign(0, -1)},
- {Inf(1), NaN()}, // [2]float64{0, Inf(1)},
++ {Inf(1), NaN()}, // [2]float64{0, Inf(1)},
{NaN(), NaN()},
}