github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/cmd/8g/prog.c (about) 1 // Copyright 2013 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 #include <u.h> 6 #include <libc.h> 7 #include "gg.h" 8 #include "opt.h" 9 10 // Matches real RtoB but can be used in global initializer. 11 #define RtoB(r) (1<<((r)-D_AX)) 12 13 enum { 14 AX = RtoB(D_AX), 15 BX = RtoB(D_BX), 16 CX = RtoB(D_CX), 17 DX = RtoB(D_DX), 18 DI = RtoB(D_DI), 19 SI = RtoB(D_SI), 20 21 LeftRdwr = LeftRead | LeftWrite, 22 RightRdwr = RightRead | RightWrite, 23 }; 24 25 #undef RtoB 26 27 // This table gives the basic information about instruction 28 // generated by the compiler and processed in the optimizer. 29 // See opt.h for bit definitions. 30 // 31 // Instructions not generated need not be listed. 32 // As an exception to that rule, we typically write down all the 33 // size variants of an operation even if we just use a subset. 34 // 35 // The table is formatted for 8-space tabs. 36 static ProgInfo progtable[ALAST] = { 37 [ATYPE]= {Pseudo | Skip}, 38 [ATEXT]= {Pseudo}, 39 [AFUNCDATA]= {Pseudo}, 40 [APCDATA]= {Pseudo}, 41 [AUNDEF]= {Break}, 42 [AUSEFIELD]= {OK}, 43 [ACHECKNIL]= {LeftRead}, 44 [AVARDEF]= {Pseudo | RightWrite}, 45 [AVARKILL]= {Pseudo | RightWrite}, 46 47 // NOP is an internal no-op that also stands 48 // for USED and SET annotations, not the Intel opcode. 49 [ANOP]= {LeftRead | RightWrite}, 50 51 [AADCL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry}, 52 [AADCW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry}, 53 54 [AADDB]= {SizeB | LeftRead | RightRdwr | SetCarry}, 55 [AADDL]= {SizeL | LeftRead | RightRdwr | SetCarry}, 56 [AADDW]= {SizeW | LeftRead | RightRdwr | SetCarry}, 57 58 [AADDSD]= {SizeD | LeftRead | RightRdwr}, 59 [AADDSS]= {SizeF | LeftRead | RightRdwr}, 60 61 [AANDB]= {SizeB | LeftRead | RightRdwr | SetCarry}, 62 [AANDL]= {SizeL | LeftRead | RightRdwr | SetCarry}, 63 [AANDW]= {SizeW | LeftRead | RightRdwr | SetCarry}, 64 65 [ACALL]= {RightAddr | Call | KillCarry}, 66 67 [ACDQ]= {OK, AX, AX | DX}, 68 [ACWD]= {OK, AX, AX | DX}, 69 70 [ACLD]= {OK}, 71 [ASTD]= {OK}, 72 73 [ACMPB]= {SizeB | LeftRead | RightRead | SetCarry}, 74 [ACMPL]= {SizeL | LeftRead | RightRead | SetCarry}, 75 [ACMPW]= {SizeW | LeftRead | RightRead | SetCarry}, 76 77 [ACOMISD]= {SizeD | LeftRead | RightRead | SetCarry}, 78 [ACOMISS]= {SizeF | LeftRead | RightRead | SetCarry}, 79 80 [ACVTSD2SL]= {SizeL | LeftRead | RightWrite | Conv}, 81 [ACVTSD2SS]= {SizeF | LeftRead | RightWrite | Conv}, 82 [ACVTSL2SD]= {SizeD | LeftRead | RightWrite | Conv}, 83 [ACVTSL2SS]= {SizeF | LeftRead | RightWrite | Conv}, 84 [ACVTSS2SD]= {SizeD | LeftRead | RightWrite | Conv}, 85 [ACVTSS2SL]= {SizeL | LeftRead | RightWrite | Conv}, 86 [ACVTTSD2SL]= {SizeL | LeftRead | RightWrite | Conv}, 87 [ACVTTSS2SL]= {SizeL | LeftRead | RightWrite | Conv}, 88 89 [ADECB]= {SizeB | RightRdwr}, 90 [ADECL]= {SizeL | RightRdwr}, 91 [ADECW]= {SizeW | RightRdwr}, 92 93 [ADIVB]= {SizeB | LeftRead | SetCarry, AX, AX}, 94 [ADIVL]= {SizeL | LeftRead | SetCarry, AX|DX, AX|DX}, 95 [ADIVW]= {SizeW | LeftRead | SetCarry, AX|DX, AX|DX}, 96 97 [ADIVSD]= {SizeD | LeftRead | RightRdwr}, 98 [ADIVSS]= {SizeF | LeftRead | RightRdwr}, 99 100 [AFLDCW]= {SizeW | LeftAddr}, 101 [AFSTCW]= {SizeW | RightAddr}, 102 103 [AFSTSW]= {SizeW | RightAddr | RightWrite}, 104 105 [AFADDD]= {SizeD | LeftAddr | RightRdwr}, 106 [AFADDDP]= {SizeD | LeftAddr | RightRdwr}, 107 [AFADDF]= {SizeF | LeftAddr | RightRdwr}, 108 109 [AFCOMD]= {SizeD | LeftAddr | RightRead}, 110 [AFCOMDP]= {SizeD | LeftAddr | RightRead}, 111 [AFCOMDPP]= {SizeD | LeftAddr | RightRead}, 112 [AFCOMF]= {SizeF | LeftAddr | RightRead}, 113 [AFCOMFP]= {SizeF | LeftAddr | RightRead}, 114 [AFUCOMIP]= {SizeF | LeftAddr | RightRead}, 115 116 [AFCHS]= {SizeD | RightRdwr}, // also SizeF 117 118 [AFDIVDP]= {SizeD | LeftAddr | RightRdwr}, 119 [AFDIVF]= {SizeF | LeftAddr | RightRdwr}, 120 [AFDIVD]= {SizeD | LeftAddr | RightRdwr}, 121 122 [AFDIVRDP]= {SizeD | LeftAddr | RightRdwr}, 123 [AFDIVRF]= {SizeF | LeftAddr | RightRdwr}, 124 [AFDIVRD]= {SizeD | LeftAddr | RightRdwr}, 125 126 [AFXCHD]= {SizeD | LeftRdwr | RightRdwr}, 127 128 [AFSUBD]= {SizeD | LeftAddr | RightRdwr}, 129 [AFSUBDP]= {SizeD | LeftAddr | RightRdwr}, 130 [AFSUBF]= {SizeF | LeftAddr | RightRdwr}, 131 [AFSUBRD]= {SizeD | LeftAddr | RightRdwr}, 132 [AFSUBRDP]= {SizeD | LeftAddr | RightRdwr}, 133 [AFSUBRF]= {SizeF | LeftAddr | RightRdwr}, 134 135 [AFMOVD]= {SizeD | LeftAddr | RightWrite}, 136 [AFMOVF]= {SizeF | LeftAddr | RightWrite}, 137 [AFMOVL]= {SizeL | LeftAddr | RightWrite}, 138 [AFMOVW]= {SizeW | LeftAddr | RightWrite}, 139 [AFMOVV]= {SizeQ | LeftAddr | RightWrite}, 140 141 // These instructions are marked as RightAddr 142 // so that the register optimizer does not try to replace the 143 // memory references with integer register references. 144 // But they do not use the previous value at the address, so 145 // we also mark them RightWrite. 146 [AFMOVDP]= {SizeD | LeftRead | RightWrite | RightAddr}, 147 [AFMOVFP]= {SizeF | LeftRead | RightWrite | RightAddr}, 148 [AFMOVLP]= {SizeL | LeftRead | RightWrite | RightAddr}, 149 [AFMOVWP]= {SizeW | LeftRead | RightWrite | RightAddr}, 150 [AFMOVVP]= {SizeQ | LeftRead | RightWrite | RightAddr}, 151 152 [AFMULD]= {SizeD | LeftAddr | RightRdwr}, 153 [AFMULDP]= {SizeD | LeftAddr | RightRdwr}, 154 [AFMULF]= {SizeF | LeftAddr | RightRdwr}, 155 156 [AIDIVB]= {SizeB | LeftRead | SetCarry, AX, AX}, 157 [AIDIVL]= {SizeL | LeftRead | SetCarry, AX|DX, AX|DX}, 158 [AIDIVW]= {SizeW | LeftRead | SetCarry, AX|DX, AX|DX}, 159 160 [AIMULB]= {SizeB | LeftRead | SetCarry, AX, AX}, 161 [AIMULL]= {SizeL | LeftRead | ImulAXDX | SetCarry}, 162 [AIMULW]= {SizeW | LeftRead | ImulAXDX | SetCarry}, 163 164 [AINCB]= {SizeB | RightRdwr}, 165 [AINCL]= {SizeL | RightRdwr}, 166 [AINCW]= {SizeW | RightRdwr}, 167 168 [AJCC]= {Cjmp | UseCarry}, 169 [AJCS]= {Cjmp | UseCarry}, 170 [AJEQ]= {Cjmp | UseCarry}, 171 [AJGE]= {Cjmp | UseCarry}, 172 [AJGT]= {Cjmp | UseCarry}, 173 [AJHI]= {Cjmp | UseCarry}, 174 [AJLE]= {Cjmp | UseCarry}, 175 [AJLS]= {Cjmp | UseCarry}, 176 [AJLT]= {Cjmp | UseCarry}, 177 [AJMI]= {Cjmp | UseCarry}, 178 [AJNE]= {Cjmp | UseCarry}, 179 [AJOC]= {Cjmp | UseCarry}, 180 [AJOS]= {Cjmp | UseCarry}, 181 [AJPC]= {Cjmp | UseCarry}, 182 [AJPL]= {Cjmp | UseCarry}, 183 [AJPS]= {Cjmp | UseCarry}, 184 185 [AJMP]= {Jump | Break | KillCarry}, 186 187 [ALEAL]= {LeftAddr | RightWrite}, 188 189 [AMOVBLSX]= {SizeL | LeftRead | RightWrite | Conv}, 190 [AMOVBLZX]= {SizeL | LeftRead | RightWrite | Conv}, 191 [AMOVBWSX]= {SizeW | LeftRead | RightWrite | Conv}, 192 [AMOVBWZX]= {SizeW | LeftRead | RightWrite | Conv}, 193 [AMOVWLSX]= {SizeL | LeftRead | RightWrite | Conv}, 194 [AMOVWLZX]= {SizeL | LeftRead | RightWrite | Conv}, 195 196 [AMOVB]= {SizeB | LeftRead | RightWrite | Move}, 197 [AMOVL]= {SizeL | LeftRead | RightWrite | Move}, 198 [AMOVW]= {SizeW | LeftRead | RightWrite | Move}, 199 200 [AMOVSB]= {OK, DI|SI, DI|SI}, 201 [AMOVSL]= {OK, DI|SI, DI|SI}, 202 [AMOVSW]= {OK, DI|SI, DI|SI}, 203 [ADUFFCOPY]= {OK, DI|SI, DI|SI|CX}, 204 205 [AMOVSD]= {SizeD | LeftRead | RightWrite | Move}, 206 [AMOVSS]= {SizeF | LeftRead | RightWrite | Move}, 207 208 // We use MOVAPD as a faster synonym for MOVSD. 209 [AMOVAPD]= {SizeD | LeftRead | RightWrite | Move}, 210 211 [AMULB]= {SizeB | LeftRead | SetCarry, AX, AX}, 212 [AMULL]= {SizeL | LeftRead | SetCarry, AX, AX|DX}, 213 [AMULW]= {SizeW | LeftRead | SetCarry, AX, AX|DX}, 214 215 [AMULSD]= {SizeD | LeftRead | RightRdwr}, 216 [AMULSS]= {SizeF | LeftRead | RightRdwr}, 217 218 [ANEGB]= {SizeB | RightRdwr | SetCarry}, 219 [ANEGL]= {SizeL | RightRdwr | SetCarry}, 220 [ANEGW]= {SizeW | RightRdwr | SetCarry}, 221 222 [ANOTB]= {SizeB | RightRdwr}, 223 [ANOTL]= {SizeL | RightRdwr}, 224 [ANOTW]= {SizeW | RightRdwr}, 225 226 [AORB]= {SizeB | LeftRead | RightRdwr | SetCarry}, 227 [AORL]= {SizeL | LeftRead | RightRdwr | SetCarry}, 228 [AORW]= {SizeW | LeftRead | RightRdwr | SetCarry}, 229 230 [APOPL]= {SizeL | RightWrite}, 231 [APUSHL]= {SizeL | LeftRead}, 232 233 [ARCLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry}, 234 [ARCLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry}, 235 [ARCLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry}, 236 237 [ARCRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry}, 238 [ARCRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry}, 239 [ARCRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry}, 240 241 [AREP]= {OK, CX, CX}, 242 [AREPN]= {OK, CX, CX}, 243 244 [ARET]= {Break | KillCarry}, 245 246 [AROLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry}, 247 [AROLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry}, 248 [AROLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry}, 249 250 [ARORB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry}, 251 [ARORL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry}, 252 [ARORW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry}, 253 254 [ASAHF]= {OK, AX, AX}, 255 256 [ASALB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry}, 257 [ASALL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry}, 258 [ASALW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry}, 259 260 [ASARB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry}, 261 [ASARL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry}, 262 [ASARW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry}, 263 264 [ASBBB]= {SizeB | LeftRead | RightRdwr | SetCarry | UseCarry}, 265 [ASBBL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry}, 266 [ASBBW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry}, 267 268 [ASETCC]= {SizeB | RightRdwr | UseCarry}, 269 [ASETCS]= {SizeB | RightRdwr | UseCarry}, 270 [ASETEQ]= {SizeB | RightRdwr | UseCarry}, 271 [ASETGE]= {SizeB | RightRdwr | UseCarry}, 272 [ASETGT]= {SizeB | RightRdwr | UseCarry}, 273 [ASETHI]= {SizeB | RightRdwr | UseCarry}, 274 [ASETLE]= {SizeB | RightRdwr | UseCarry}, 275 [ASETLS]= {SizeB | RightRdwr | UseCarry}, 276 [ASETLT]= {SizeB | RightRdwr | UseCarry}, 277 [ASETMI]= {SizeB | RightRdwr | UseCarry}, 278 [ASETNE]= {SizeB | RightRdwr | UseCarry}, 279 [ASETOC]= {SizeB | RightRdwr | UseCarry}, 280 [ASETOS]= {SizeB | RightRdwr | UseCarry}, 281 [ASETPC]= {SizeB | RightRdwr | UseCarry}, 282 [ASETPL]= {SizeB | RightRdwr | UseCarry}, 283 [ASETPS]= {SizeB | RightRdwr | UseCarry}, 284 285 [ASHLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry}, 286 [ASHLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry}, 287 [ASHLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry}, 288 289 [ASHRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry}, 290 [ASHRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry}, 291 [ASHRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry}, 292 293 [ASTOSB]= {OK, AX|DI, DI}, 294 [ASTOSL]= {OK, AX|DI, DI}, 295 [ASTOSW]= {OK, AX|DI, DI}, 296 [ADUFFZERO]= {OK, AX|DI, DI}, 297 298 [ASUBB]= {SizeB | LeftRead | RightRdwr | SetCarry}, 299 [ASUBL]= {SizeL | LeftRead | RightRdwr | SetCarry}, 300 [ASUBW]= {SizeW | LeftRead | RightRdwr | SetCarry}, 301 302 [ASUBSD]= {SizeD | LeftRead | RightRdwr}, 303 [ASUBSS]= {SizeF | LeftRead | RightRdwr}, 304 305 [ATESTB]= {SizeB | LeftRead | RightRead | SetCarry}, 306 [ATESTL]= {SizeL | LeftRead | RightRead | SetCarry}, 307 [ATESTW]= {SizeW | LeftRead | RightRead | SetCarry}, 308 309 [AUCOMISD]= {SizeD | LeftRead | RightRead}, 310 [AUCOMISS]= {SizeF | LeftRead | RightRead}, 311 312 [AXCHGB]= {SizeB | LeftRdwr | RightRdwr}, 313 [AXCHGL]= {SizeL | LeftRdwr | RightRdwr}, 314 [AXCHGW]= {SizeW | LeftRdwr | RightRdwr}, 315 316 [AXORB]= {SizeB | LeftRead | RightRdwr | SetCarry}, 317 [AXORL]= {SizeL | LeftRead | RightRdwr | SetCarry}, 318 [AXORW]= {SizeW | LeftRead | RightRdwr | SetCarry}, 319 }; 320 321 void 322 proginfo(ProgInfo *info, Prog *p) 323 { 324 *info = progtable[p->as]; 325 if(info->flags == 0) 326 fatal("unknown instruction %P", p); 327 328 if((info->flags & ShiftCX) && p->from.type != D_CONST) 329 info->reguse |= CX; 330 331 if(info->flags & ImulAXDX) { 332 if(p->to.type == D_NONE) { 333 info->reguse |= AX; 334 info->regset |= AX | DX; 335 } else { 336 info->flags |= RightRdwr; 337 } 338 } 339 340 // Addressing makes some registers used. 341 if(p->from.type >= D_INDIR) 342 info->regindex |= RtoB(p->from.type-D_INDIR); 343 if(p->from.index != D_NONE) 344 info->regindex |= RtoB(p->from.index); 345 if(p->to.type >= D_INDIR) 346 info->regindex |= RtoB(p->to.type-D_INDIR); 347 if(p->to.index != D_NONE) 348 info->regindex |= RtoB(p->to.index); 349 }