github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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 // Special layout in ARM assembly 95 // Comparing to x86, the operands of ARM's CMP are reversed. 96 p.From.Reg = gc.SSARegNum(v.Args[1]) 97 p.Reg = gc.SSARegNum(v.Args[0]) 98 case ssa.OpARMMOVWload: 99 p := gc.Prog(v.Op.Asm()) 100 p.From.Type = obj.TYPE_MEM 101 p.From.Reg = gc.SSARegNum(v.Args[0]) 102 gc.AddAux(&p.From, v) 103 p.To.Type = obj.TYPE_REG 104 p.To.Reg = gc.SSARegNum(v) 105 case ssa.OpARMMOVWstore: 106 p := gc.Prog(v.Op.Asm()) 107 p.From.Type = obj.TYPE_REG 108 p.From.Reg = gc.SSARegNum(v.Args[1]) 109 p.To.Type = obj.TYPE_MEM 110 p.To.Reg = gc.SSARegNum(v.Args[0]) 111 gc.AddAux(&p.To, v) 112 case ssa.OpARMCALLstatic: 113 // TODO: deferreturn 114 p := gc.Prog(obj.ACALL) 115 p.To.Type = obj.TYPE_MEM 116 p.To.Name = obj.NAME_EXTERN 117 p.To.Sym = gc.Linksym(v.Aux.(*gc.Sym)) 118 if gc.Maxarg < v.AuxInt { 119 gc.Maxarg = v.AuxInt 120 } 121 case ssa.OpVarDef: 122 gc.Gvardef(v.Aux.(*gc.Node)) 123 case ssa.OpVarKill: 124 gc.Gvarkill(v.Aux.(*gc.Node)) 125 case ssa.OpVarLive: 126 gc.Gvarlive(v.Aux.(*gc.Node)) 127 case ssa.OpARMLessThan: 128 v.Fatalf("pseudo-op made it to output: %s", v.LongString()) 129 default: 130 v.Unimplementedf("genValue not implemented: %s", v.LongString()) 131 } 132 } 133 134 func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) { 135 s.SetLineno(b.Line) 136 137 switch b.Kind { 138 case ssa.BlockCall: 139 if b.Succs[0].Block() != next { 140 p := gc.Prog(obj.AJMP) 141 p.To.Type = obj.TYPE_BRANCH 142 s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()}) 143 } 144 case ssa.BlockRet: 145 gc.Prog(obj.ARET) 146 case ssa.BlockARMLT: 147 p := gc.Prog(arm.ABLT) 148 p.To.Type = obj.TYPE_BRANCH 149 s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()}) 150 p = gc.Prog(obj.AJMP) 151 p.To.Type = obj.TYPE_BRANCH 152 s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()}) 153 } 154 }