1 #include "gc.h" 2 3 void 4 noretval(int n) 5 { 6 7 if(n & 1) { 8 gins(ANOP, Z, Z); 9 p->to.type = D_REG; 10 p->to.reg = REGRET; 11 } 12 if(n & 2) { 13 gins(ANOP, Z, Z); 14 p->to.type = D_FREG; 15 p->to.reg = FREGRET; 16 } 17 } 18 19 /* 20 * calculate addressability as follows 21 * CONST ==> 20 $value 22 * NAME ==> 10 name 23 * REGISTER ==> 11 register 24 * INDREG ==> 12 *[(reg)+offset] 25 * &10 ==> 2 $name 26 * ADD(2, 20) ==> 2 $name+offset 27 * ADD(3, 20) ==> 3 $(reg)+offset 28 * &12 ==> 3 $(reg)+offset 29 * *11 ==> 11 ?? 30 * *2 ==> 10 name 31 * *3 ==> 12 *(reg)+offset 32 * calculate complexity (number of registers) 33 */ 34 void 35 xcom(Node *n) 36 { 37 Node *l, *r; 38 int v; 39 40 if(n == Z) 41 return; 42 l = n->left; 43 r = n->right; 44 n->addable = 0; 45 n->complex = 0; 46 switch(n->op) { 47 case OCONST: 48 n->addable = 20; 49 return; 50 51 case OREGISTER: 52 n->addable = 11; 53 return; 54 55 case OINDREG: 56 n->addable = 12; 57 return; 58 59 case ONAME: 60 n->addable = 10; 61 return; 62 63 case OADDR: 64 xcom(l); 65 if(l->addable == 10) 66 n->addable = 2; 67 if(l->addable == 12) 68 n->addable = 3; 69 break; 70 71 case OIND: 72 xcom(l); 73 if(l->addable == 11) 74 n->addable = 12; 75 if(l->addable == 3) 76 n->addable = 12; 77 if(l->addable == 2) 78 n->addable = 10; 79 break; 80 81 case OADD: 82 xcom(l); 83 xcom(r); 84 if(l->addable == 20) { 85 if(r->addable == 2) 86 n->addable = 2; 87 if(r->addable == 3) 88 n->addable = 3; 89 } 90 if(r->addable == 20) { 91 if(l->addable == 2) 92 n->addable = 2; 93 if(l->addable == 3) 94 n->addable = 3; 95 } 96 break; 97 98 case OASMUL: 99 case OASLMUL: 100 xcom(l); 101 xcom(r); 102 v = vlog(r); 103 if(v >= 0) { 104 n->op = OASASHL; 105 r->vconst = v; 106 r->type = types[TINT]; 107 } 108 break; 109 110 case OMUL: 111 case OLMUL: 112 xcom(l); 113 xcom(r); 114 v = vlog(r); 115 if(v >= 0) { 116 n->op = OASHL; 117 r->vconst = v; 118 r->type = types[TINT]; 119 } 120 v = vlog(l); 121 if(v >= 0) { 122 n->op = OASHL; 123 n->left = r; 124 n->right = l; 125 r = l; 126 l = n->left; 127 r->vconst = v; 128 r->type = types[TINT]; 129 } 130 break; 131 132 case OASLDIV: 133 xcom(l); 134 xcom(r); 135 v = vlog(r); 136 if(v >= 0) { 137 n->op = OASLSHR; 138 r->vconst = v; 139 r->type = types[TINT]; 140 } 141 break; 142 143 case OLDIV: 144 xcom(l); 145 xcom(r); 146 v = vlog(r); 147 if(v >= 0) { 148 n->op = OLSHR; 149 r->vconst = v; 150 r->type = types[TINT]; 151 } 152 break; 153 154 case OASLMOD: 155 xcom(l); 156 xcom(r); 157 v = vlog(r); 158 if(v >= 0) { 159 n->op = OASAND; 160 r->vconst--; 161 } 162 break; 163 164 case OLMOD: 165 xcom(l); 166 xcom(r); 167 v = vlog(r); 168 if(v >= 0) { 169 n->op = OAND; 170 r->vconst--; 171 } 172 break; 173 174 default: 175 if(l != Z) 176 xcom(l); 177 if(r != Z) 178 xcom(r); 179 break; 180 } 181 if(n->addable >= 10) 182 return; 183 if(l != Z) 184 n->complex = l->complex; 185 if(r != Z) { 186 if(r->complex == n->complex) 187 n->complex = r->complex+1; 188 else 189 if(r->complex > n->complex) 190 n->complex = r->complex; 191 } 192 if(n->complex == 0) 193 n->complex++; 194 195 if(com64(n)) 196 return; 197 198 switch(n->op) { 199 200 case OFUNC: 201 n->complex = FNX; 202 break; 203 204 case OEQ: 205 case ONE: 206 case OLE: 207 case OLT: 208 case OGE: 209 case OGT: 210 case OHI: 211 case OHS: 212 case OLO: 213 case OLS: 214 /* 215 * immediate operators, make const on right 216 */ 217 if(l->op == OCONST) { 218 n->left = r; 219 n->right = l; 220 n->op = invrel[relindex(n->op)]; 221 } 222 break; 223 224 case OADD: 225 case OXOR: 226 case OAND: 227 case OOR: 228 /* 229 * immediate operators, make const on right 230 */ 231 if(l->op == OCONST) { 232 n->left = r; 233 n->right = l; 234 } 235 break; 236 } 237 } 238 239