github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/cmd/5g/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 enum 11 { 12 RightRdwr = RightRead | RightWrite, 13 }; 14 15 // This table gives the basic information about instruction 16 // generated by the compiler and processed in the optimizer. 17 // See opt.h for bit definitions. 18 // 19 // Instructions not generated need not be listed. 20 // As an exception to that rule, we typically write down all the 21 // size variants of an operation even if we just use a subset. 22 // 23 // The table is formatted for 8-space tabs. 24 static ProgInfo progtable[ALAST] = { 25 [ATYPE]= {Pseudo | Skip}, 26 [ATEXT]= {Pseudo}, 27 [AFUNCDATA]= {Pseudo}, 28 [APCDATA]= {Pseudo}, 29 [AUNDEF]= {Break}, 30 [AUSEFIELD]= {OK}, 31 [ACHECKNIL]= {LeftRead}, 32 [AVARDEF]= {Pseudo | RightWrite}, 33 [AVARKILL]= {Pseudo | RightWrite}, 34 35 // NOP is an internal no-op that also stands 36 // for USED and SET annotations, not the Intel opcode. 37 [ANOP]= {LeftRead | RightWrite}, 38 39 // Integer. 40 [AADC]= {SizeL | LeftRead | RegRead | RightWrite}, 41 [AADD]= {SizeL | LeftRead | RegRead | RightWrite}, 42 [AAND]= {SizeL | LeftRead | RegRead | RightWrite}, 43 [ABIC]= {SizeL | LeftRead | RegRead | RightWrite}, 44 [ACMN]= {SizeL | LeftRead | RightRead}, 45 [ACMP]= {SizeL | LeftRead | RightRead}, 46 [ADIVU]= {SizeL | LeftRead | RegRead | RightWrite}, 47 [ADIV]= {SizeL | LeftRead | RegRead | RightWrite}, 48 [AEOR]= {SizeL | LeftRead | RegRead | RightWrite}, 49 [AMODU]= {SizeL | LeftRead | RegRead | RightWrite}, 50 [AMOD]= {SizeL | LeftRead | RegRead | RightWrite}, 51 [AMULALU]= {SizeL | LeftRead | RegRead | RightRdwr}, 52 [AMULAL]= {SizeL | LeftRead | RegRead | RightRdwr}, 53 [AMULA]= {SizeL | LeftRead | RegRead | RightRdwr}, 54 [AMULU]= {SizeL | LeftRead | RegRead | RightWrite}, 55 [AMUL]= {SizeL | LeftRead | RegRead | RightWrite}, 56 [AMULL]= {SizeL | LeftRead | RegRead | RightWrite}, 57 [AMULLU]= {SizeL | LeftRead | RegRead | RightWrite}, 58 [AMVN]= {SizeL | LeftRead | RightWrite}, 59 [AORR]= {SizeL | LeftRead | RegRead | RightWrite}, 60 [ARSB]= {SizeL | LeftRead | RegRead | RightWrite}, 61 [ARSC]= {SizeL | LeftRead | RegRead | RightWrite}, 62 [ASBC]= {SizeL | LeftRead | RegRead | RightWrite}, 63 [ASLL]= {SizeL | LeftRead | RegRead | RightWrite}, 64 [ASRA]= {SizeL | LeftRead | RegRead | RightWrite}, 65 [ASRL]= {SizeL | LeftRead | RegRead | RightWrite}, 66 [ASUB]= {SizeL | LeftRead | RegRead | RightWrite}, 67 [ATEQ]= {SizeL | LeftRead | RightRead}, 68 [ATST]= {SizeL | LeftRead | RightRead}, 69 70 // Floating point. 71 [AADDD]= {SizeD | LeftRead | RightRdwr}, 72 [AADDF]= {SizeF | LeftRead | RightRdwr}, 73 [ACMPD]= {SizeD | LeftRead | RightRead}, 74 [ACMPF]= {SizeF | LeftRead | RightRead}, 75 [ADIVD]= {SizeD | LeftRead | RightRdwr}, 76 [ADIVF]= {SizeF | LeftRead | RightRdwr}, 77 [AMULD]= {SizeD | LeftRead | RightRdwr}, 78 [AMULF]= {SizeF | LeftRead | RightRdwr}, 79 [ASUBD]= {SizeD | LeftRead | RightRdwr}, 80 [ASUBF]= {SizeF | LeftRead | RightRdwr}, 81 82 // Conversions. 83 [AMOVWD]= {SizeD | LeftRead | RightWrite | Conv}, 84 [AMOVWF]= {SizeF | LeftRead | RightWrite | Conv}, 85 [AMOVDF]= {SizeF | LeftRead | RightWrite | Conv}, 86 [AMOVDW]= {SizeL | LeftRead | RightWrite | Conv}, 87 [AMOVFD]= {SizeD | LeftRead | RightWrite | Conv}, 88 [AMOVFW]= {SizeL | LeftRead | RightWrite | Conv}, 89 90 // Moves. 91 [AMOVB]= {SizeB | LeftRead | RightWrite | Move}, 92 [AMOVD]= {SizeD | LeftRead | RightWrite | Move}, 93 [AMOVF]= {SizeF | LeftRead | RightWrite | Move}, 94 [AMOVH]= {SizeW | LeftRead | RightWrite | Move}, 95 [AMOVW]= {SizeL | LeftRead | RightWrite | Move}, 96 // In addtion, duffzero reads R0,R1 and writes R1. This fact is 97 // encoded in peep.c 98 [ADUFFZERO]= {Call}, 99 // In addtion, duffcopy reads R1,R2 and writes R0,R1,R2. This fact is 100 // encoded in peep.c 101 [ADUFFCOPY]= {Call}, 102 103 // These should be split into the two different conversions instead 104 // of overloading the one. 105 [AMOVBS]= {SizeB | LeftRead | RightWrite | Conv}, 106 [AMOVBU]= {SizeB | LeftRead | RightWrite | Conv}, 107 [AMOVHS]= {SizeW | LeftRead | RightWrite | Conv}, 108 [AMOVHU]= {SizeW | LeftRead | RightWrite | Conv}, 109 110 // Jumps. 111 [AB]= {Jump | Break}, 112 [ABL]= {Call}, 113 [ABEQ]= {Cjmp}, 114 [ABNE]= {Cjmp}, 115 [ABCS]= {Cjmp}, 116 [ABHS]= {Cjmp}, 117 [ABCC]= {Cjmp}, 118 [ABLO]= {Cjmp}, 119 [ABMI]= {Cjmp}, 120 [ABPL]= {Cjmp}, 121 [ABVS]= {Cjmp}, 122 [ABVC]= {Cjmp}, 123 [ABHI]= {Cjmp}, 124 [ABLS]= {Cjmp}, 125 [ABGE]= {Cjmp}, 126 [ABLT]= {Cjmp}, 127 [ABGT]= {Cjmp}, 128 [ABLE]= {Cjmp}, 129 [ARET]= {Break}, 130 }; 131 132 void 133 proginfo(ProgInfo *info, Prog *p) 134 { 135 *info = progtable[p->as]; 136 if(info->flags == 0) 137 fatal("unknown instruction %P", p); 138 139 if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) { 140 info->flags &= ~LeftRead; 141 info->flags |= LeftAddr; 142 } 143 144 if((info->flags & RegRead) && p->reg == NREG) { 145 info->flags &= ~RegRead; 146 info->flags |= CanRegRead | RightRead; 147 } 148 149 if(((p->scond & C_SCOND) != C_SCOND_NONE) && (info->flags & RightWrite)) 150 info->flags |= RightRead; 151 }