github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/cmd/compile/internal/s390x/prog.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 s390x 6 7 import ( 8 "cmd/compile/internal/gc" 9 "cmd/internal/obj" 10 "cmd/internal/obj/s390x" 11 ) 12 13 // This table gives the basic information about instruction 14 // generated by the compiler and processed in the optimizer. 15 // See opt.h for bit definitions. 16 // 17 // Instructions not generated need not be listed. 18 // As an exception to that rule, we typically write down all the 19 // size variants of an operation even if we just use a subset. 20 var progtable = [s390x.ALAST & obj.AMask]obj.ProgInfo{ 21 obj.ATYPE & obj.AMask: {Flags: gc.Pseudo | gc.Skip}, 22 obj.ATEXT & obj.AMask: {Flags: gc.Pseudo}, 23 obj.AFUNCDATA & obj.AMask: {Flags: gc.Pseudo}, 24 obj.APCDATA & obj.AMask: {Flags: gc.Pseudo}, 25 obj.AUNDEF & obj.AMask: {Flags: gc.Break}, 26 obj.AUSEFIELD & obj.AMask: {Flags: gc.OK}, 27 obj.ACHECKNIL & obj.AMask: {Flags: gc.LeftRead}, 28 obj.AVARDEF & obj.AMask: {Flags: gc.Pseudo | gc.RightWrite}, 29 obj.AVARKILL & obj.AMask: {Flags: gc.Pseudo | gc.RightWrite}, 30 obj.AVARLIVE & obj.AMask: {Flags: gc.Pseudo | gc.LeftRead}, 31 32 // NOP is an internal no-op that also stands 33 // for USED and SET annotations. 34 obj.ANOP & obj.AMask: {Flags: gc.LeftRead | gc.RightWrite}, 35 36 // Integer 37 s390x.AADD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 38 s390x.ASUB & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 39 s390x.ANEG & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 40 s390x.AAND & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 41 s390x.AOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 42 s390x.AXOR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 43 s390x.AMULLD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 44 s390x.AMULLW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 45 s390x.AMULHD & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 46 s390x.AMULHDU & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 47 s390x.ADIVD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 48 s390x.ADIVDU & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 49 s390x.ASLD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 50 s390x.ASRD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 51 s390x.ASRAD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 52 s390x.ARLL & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite}, 53 s390x.ARLLG & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite}, 54 s390x.ACMP & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead}, 55 s390x.ACMPU & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead}, 56 57 // Floating point. 58 s390x.AFADD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 59 s390x.AFADDS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 60 s390x.AFSUB & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 61 s390x.AFSUBS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 62 s390x.AFMUL & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 63 s390x.AFMULS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 64 s390x.AFDIV & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RegRead | gc.RightWrite}, 65 s390x.AFDIVS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite}, 66 s390x.AFCMPU & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead}, 67 s390x.ACEBR & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightRead}, 68 s390x.ALEDBR & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 69 s390x.ALDEBR & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 70 s390x.AFSQRT & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite}, 71 72 // Conversions 73 s390x.ACEFBRA & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 74 s390x.ACDFBRA & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 75 s390x.ACEGBRA & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 76 s390x.ACDGBRA & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 77 s390x.ACFEBRA & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 78 s390x.ACFDBRA & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 79 s390x.ACGEBRA & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 80 s390x.ACGDBRA & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 81 s390x.ACELFBR & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 82 s390x.ACDLFBR & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 83 s390x.ACELGBR & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv}, 84 s390x.ACDLGBR & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv}, 85 s390x.ACLFEBR & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 86 s390x.ACLFDBR & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv}, 87 s390x.ACLGEBR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 88 s390x.ACLGDBR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv}, 89 90 // Moves 91 s390x.AMOVB & obj.AMask: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 92 s390x.AMOVBZ & obj.AMask: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 93 s390x.AMOVH & obj.AMask: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 94 s390x.AMOVHZ & obj.AMask: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 95 s390x.AMOVW & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 96 s390x.AMOVWZ & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 97 s390x.AMOVD & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move}, 98 s390x.AFMOVS & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv}, 99 s390x.AFMOVD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move}, 100 101 // Storage operations 102 s390x.AMVC & obj.AMask: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr}, 103 s390x.ACLC & obj.AMask: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightRead | gc.RightAddr}, 104 s390x.AXC & obj.AMask: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr}, 105 s390x.AOC & obj.AMask: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr}, 106 s390x.ANC & obj.AMask: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr}, 107 108 // Jumps 109 s390x.ABR & obj.AMask: {Flags: gc.Jump | gc.Break}, 110 s390x.ABL & obj.AMask: {Flags: gc.Call}, 111 s390x.ABEQ & obj.AMask: {Flags: gc.Cjmp}, 112 s390x.ABNE & obj.AMask: {Flags: gc.Cjmp}, 113 s390x.ABGE & obj.AMask: {Flags: gc.Cjmp}, 114 s390x.ABLT & obj.AMask: {Flags: gc.Cjmp}, 115 s390x.ABGT & obj.AMask: {Flags: gc.Cjmp}, 116 s390x.ABLE & obj.AMask: {Flags: gc.Cjmp}, 117 s390x.ACMPBEQ & obj.AMask: {Flags: gc.Cjmp}, 118 s390x.ACMPBNE & obj.AMask: {Flags: gc.Cjmp}, 119 s390x.ACMPBGE & obj.AMask: {Flags: gc.Cjmp}, 120 s390x.ACMPBLT & obj.AMask: {Flags: gc.Cjmp}, 121 s390x.ACMPBGT & obj.AMask: {Flags: gc.Cjmp}, 122 s390x.ACMPBLE & obj.AMask: {Flags: gc.Cjmp}, 123 s390x.ACMPUBEQ & obj.AMask: {Flags: gc.Cjmp}, 124 s390x.ACMPUBNE & obj.AMask: {Flags: gc.Cjmp}, 125 s390x.ACMPUBGE & obj.AMask: {Flags: gc.Cjmp}, 126 s390x.ACMPUBLT & obj.AMask: {Flags: gc.Cjmp}, 127 s390x.ACMPUBGT & obj.AMask: {Flags: gc.Cjmp}, 128 s390x.ACMPUBLE & obj.AMask: {Flags: gc.Cjmp}, 129 130 // Macros 131 s390x.ACLEAR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightAddr | gc.RightWrite}, 132 133 // Load/store multiple 134 s390x.ASTMG & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightAddr | gc.RightWrite}, 135 s390x.ASTMY & obj.AMask: {Flags: gc.SizeL | gc.LeftRead | gc.RightAddr | gc.RightWrite}, 136 s390x.ALMG & obj.AMask: {Flags: gc.SizeQ | gc.LeftAddr | gc.LeftRead | gc.RightWrite}, 137 s390x.ALMY & obj.AMask: {Flags: gc.SizeL | gc.LeftAddr | gc.LeftRead | gc.RightWrite}, 138 139 obj.ARET & obj.AMask: {Flags: gc.Break}, 140 } 141 142 func proginfo(p *obj.Prog) { 143 info := &p.Info 144 *info = progtable[p.As&obj.AMask] 145 if info.Flags == 0 { 146 gc.Fatalf("proginfo: unknown instruction %v", p) 147 } 148 149 if (info.Flags&gc.RegRead != 0) && p.Reg == 0 { 150 info.Flags &^= gc.RegRead 151 info.Flags |= gc.RightRead /*CanRegRead |*/ 152 } 153 154 if (p.From.Type == obj.TYPE_MEM || p.From.Type == obj.TYPE_ADDR) && p.From.Reg != 0 { 155 info.Regindex |= RtoB(int(p.From.Reg)) 156 } 157 158 if (p.To.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_ADDR) && p.To.Reg != 0 { 159 info.Regindex |= RtoB(int(p.To.Reg)) 160 } 161 162 if p.From.Type == obj.TYPE_ADDR && p.From.Sym != nil && (info.Flags&gc.LeftRead != 0) { 163 info.Flags &^= gc.LeftRead 164 info.Flags |= gc.LeftAddr 165 } 166 167 switch p.As { 168 // load multiple sets a range of registers 169 case s390x.ALMG, s390x.ALMY: 170 for r := p.Reg; r <= p.To.Reg; r++ { 171 info.Regset |= RtoB(int(r)) 172 } 173 // store multiple reads a range of registers 174 case s390x.ASTMG, s390x.ASTMY: 175 for r := p.From.Reg; r <= p.Reg; r++ { 176 info.Reguse |= RtoB(int(r)) 177 } 178 } 179 }