github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/compile/internal/arm/ssa.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package arm
     6  
     7  import (
     8  	"cmd/compile/internal/gc"
     9  	"cmd/compile/internal/ssa"
    10  	"cmd/internal/obj"
    11  	"cmd/internal/obj/arm"
    12  )
    13  
    14  var ssaRegToReg = []int16{
    15  	arm.REG_R0,
    16  	arm.REG_R1,
    17  	arm.REG_R2,
    18  	arm.REG_R3,
    19  	arm.REGSP, // aka R13
    20  }
    21  
    22  func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
    23  	s.SetLineno(v.Line)
    24  	switch v.Op {
    25  	case ssa.OpInitMem:
    26  		// memory arg needs no code
    27  	case ssa.OpArg:
    28  		// input args need no code
    29  	case ssa.OpSP, ssa.OpSB:
    30  		// nothing to do
    31  	case ssa.OpCopy:
    32  	case ssa.OpLoadReg:
    33  		// TODO: by type
    34  		p := gc.Prog(arm.AMOVW)
    35  		n, off := gc.AutoVar(v.Args[0])
    36  		p.From.Type = obj.TYPE_MEM
    37  		p.From.Node = n
    38  		p.From.Sym = gc.Linksym(n.Sym)
    39  		p.From.Offset = off
    40  		if n.Class == gc.PPARAM || n.Class == gc.PPARAMOUT {
    41  			p.From.Name = obj.NAME_PARAM
    42  			p.From.Offset += n.Xoffset
    43  		} else {
    44  			p.From.Name = obj.NAME_AUTO
    45  		}
    46  		p.To.Type = obj.TYPE_REG
    47  		p.To.Reg = gc.SSARegNum(v)
    48  
    49  	case ssa.OpStoreReg:
    50  		// TODO: by type
    51  		p := gc.Prog(arm.AMOVW)
    52  		p.From.Type = obj.TYPE_REG
    53  		p.From.Reg = gc.SSARegNum(v.Args[0])
    54  		n, off := gc.AutoVar(v)
    55  		p.To.Type = obj.TYPE_MEM
    56  		p.To.Node = n
    57  		p.To.Sym = gc.Linksym(n.Sym)
    58  		p.To.Offset = off
    59  		if n.Class == gc.PPARAM || n.Class == gc.PPARAMOUT {
    60  			p.To.Name = obj.NAME_PARAM
    61  			p.To.Offset += n.Xoffset
    62  		} else {
    63  			p.To.Name = obj.NAME_AUTO
    64  		}
    65  	case ssa.OpARMADD:
    66  		r := gc.SSARegNum(v)
    67  		r1 := gc.SSARegNum(v.Args[0])
    68  		r2 := gc.SSARegNum(v.Args[1])
    69  		p := gc.Prog(v.Op.Asm())
    70  		p.From.Type = obj.TYPE_REG
    71  		p.From.Reg = r1
    72  		p.Reg = r2
    73  		p.To.Type = obj.TYPE_REG
    74  		p.To.Reg = r
    75  	case ssa.OpARMADDconst:
    76  		p := gc.Prog(v.Op.Asm())
    77  		p.From.Type = obj.TYPE_CONST
    78  		p.From.Offset = v.AuxInt
    79  		if v.Aux != nil {
    80  			panic("can't handle symbolic constant yet")
    81  		}
    82  		p.Reg = gc.SSARegNum(v.Args[0])
    83  		p.To.Type = obj.TYPE_REG
    84  		p.To.Reg = gc.SSARegNum(v)
    85  	case ssa.OpARMMOVWconst:
    86  		p := gc.Prog(v.Op.Asm())
    87  		p.From.Type = obj.TYPE_CONST
    88  		p.From.Offset = v.AuxInt
    89  		p.To.Type = obj.TYPE_REG
    90  		p.To.Reg = gc.SSARegNum(v)
    91  	case ssa.OpARMCMP:
    92  		p := gc.Prog(v.Op.Asm())
    93  		p.From.Type = obj.TYPE_REG
    94  		p.From.Reg = gc.SSARegNum(v.Args[0])
    95  		p.Reg = gc.SSARegNum(v.Args[1])
    96  	case ssa.OpARMMOVWload:
    97  		p := gc.Prog(v.Op.Asm())
    98  		p.From.Type = obj.TYPE_MEM
    99  		p.From.Reg = gc.SSARegNum(v.Args[0])
   100  		gc.AddAux(&p.From, v)
   101  		p.To.Type = obj.TYPE_REG
   102  		p.To.Reg = gc.SSARegNum(v)
   103  	case ssa.OpARMMOVWstore:
   104  		p := gc.Prog(v.Op.Asm())
   105  		p.From.Type = obj.TYPE_REG
   106  		p.From.Reg = gc.SSARegNum(v.Args[1])
   107  		p.To.Type = obj.TYPE_MEM
   108  		p.To.Reg = gc.SSARegNum(v.Args[0])
   109  		gc.AddAux(&p.To, v)
   110  	case ssa.OpARMCALLstatic:
   111  		// TODO: deferreturn
   112  		p := gc.Prog(obj.ACALL)
   113  		p.To.Type = obj.TYPE_MEM
   114  		p.To.Name = obj.NAME_EXTERN
   115  		p.To.Sym = gc.Linksym(v.Aux.(*gc.Sym))
   116  		if gc.Maxarg < v.AuxInt {
   117  			gc.Maxarg = v.AuxInt
   118  		}
   119  	case ssa.OpVarDef:
   120  		gc.Gvardef(v.Aux.(*gc.Node))
   121  	case ssa.OpVarKill:
   122  		gc.Gvarkill(v.Aux.(*gc.Node))
   123  	case ssa.OpVarLive:
   124  		gc.Gvarlive(v.Aux.(*gc.Node))
   125  	case ssa.OpARMLessThan:
   126  		v.Fatalf("pseudo-op made it to output: %s", v.LongString())
   127  	default:
   128  		v.Unimplementedf("genValue not implemented: %s", v.LongString())
   129  	}
   130  }
   131  
   132  func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
   133  	s.SetLineno(b.Line)
   134  
   135  	switch b.Kind {
   136  	case ssa.BlockCall:
   137  		if b.Succs[0] != next {
   138  			p := gc.Prog(obj.AJMP)
   139  			p.To.Type = obj.TYPE_BRANCH
   140  			s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
   141  		}
   142  	case ssa.BlockRet:
   143  		gc.Prog(obj.ARET)
   144  	case ssa.BlockARMLT:
   145  		p := gc.Prog(arm.ABGE)
   146  		p.To.Type = obj.TYPE_BRANCH
   147  		s.Branches = append(s.Branches, gc.Branch{p, b.Succs[0]})
   148  		p = gc.Prog(obj.AJMP)
   149  		p.To.Type = obj.TYPE_BRANCH
   150  		s.Branches = append(s.Branches, gc.Branch{p, b.Succs[1]})
   151  	}
   152  }