ins.c (4579B)
1 #include <stdlib.h> 2 3 #include <scc/mach.h> 4 #include <scc/scc.h> 5 6 #include "../../as.h" 7 #include "proc.h" 8 9 /* 10 * This code is derived from PowerISA_V2.06B_V2_PUBLIC document. 11 * All the names used in the specification are preserved in 12 * this code. 13 */ 14 15 static int 16 getclass(Node *np) 17 { 18 if (np->addr != AREG) 19 return 0; 20 21 switch (np->sym->value) { 22 case AREG_R0: 23 case AREG_R1: 24 case AREG_R2: 25 case AREG_R3: 26 case AREG_R4: 27 case AREG_R5: 28 case AREG_R6: 29 case AREG_R7: 30 case AREG_R8: 31 case AREG_R9: 32 case AREG_R10: 33 case AREG_R11: 34 case AREG_R12: 35 case AREG_R13: 36 case AREG_R14: 37 case AREG_R15: 38 case AREG_R16: 39 case AREG_R17: 40 case AREG_R18: 41 case AREG_R19: 42 case AREG_R20: 43 case AREG_R21: 44 case AREG_R22: 45 case AREG_R23: 46 case AREG_R24: 47 case AREG_R25: 48 case AREG_R26: 49 case AREG_R27: 50 case AREG_R29: 51 case AREG_R30: 52 case AREG_R31: 53 return GPRSCLASS; 54 default: 55 abort(); 56 } 57 } 58 59 int 60 match(Op *op, Node **args) 61 { 62 unsigned char *p; 63 int arg, class, rep, opt; 64 Node *np; 65 66 if (!op->args) 67 return args == NULL; 68 69 opt = rep = 0; 70 for (p = op->args; arg = *p; ++p) { 71 if (rep) 72 --p; 73 if ((np = *args++) == NULL) 74 return (rep|opt) != 0; 75 76 switch (arg) { 77 case AOPT: 78 opt = 1; 79 break; 80 case AREP: 81 rep = 1; 82 break; 83 case AREG_GPRSCLASS: 84 class = GPRSCLASS; 85 check_class: 86 if ((getclass(np) & class) == 0) 87 return 0; 88 break; 89 case AIMM2: 90 case AIMM5: 91 case AIMM8: 92 case AIMM16: 93 case AIMM32: 94 case AIMM64: 95 if (np->addr != AIMM) 96 return 0; 97 if (toobig(np, arg)) 98 error("overflow in immediate operand"); 99 break; 100 case ASYM: 101 if (np->op != IDEN) 102 return 0; 103 break; 104 case ADIRECT: 105 case ASTR: 106 if (np->addr != arg) 107 return 0; 108 break; 109 default: 110 abort(); 111 } 112 } 113 114 return *args == NULL; 115 } 116 117 Node * 118 moperand(void) 119 { 120 abort(); 121 } 122 123 static void 124 emit_packed(unsigned long ins) 125 { 126 char buff[4]; 127 128 if (endian == BIG_ENDIAN) { 129 buff[0] = ins >> 24; 130 buff[1] = ins >> 16; 131 buff[2] = ins >> 8; 132 buff[3] = ins; 133 } else { 134 buff[0] = ins; 135 buff[1] = ins >> 8; 136 buff[2] = ins >> 16; 137 buff[3] = ins >> 24; 138 } 139 140 emit(buff, 4); 141 } 142 143 void 144 i_form(Op *op, Node **args) 145 { 146 unsigned long ins, opcd, li, aa, lk; 147 long long dst; 148 long long max = 1l << 23; 149 long long min = -(1l << 23); 150 151 opcd = op->bytes[0]; 152 aa = op->bytes[1]; 153 lk = op->bytes[2]; 154 155 dst = args[0]->sym->value; 156 if (dst & 0x3) 157 error("unaligned branch"); 158 if (aa) 159 dst -= getpc() - 4; 160 if (dst < min || dst > max) 161 error("out of range branch"); 162 163 li = dst; 164 li >>= 2; 165 ins = opcd<<26 | li<<2 | aa<<1 | lk; 166 emit_packed(ins); 167 } 168 169 void 170 b_form(Op *op, Node **args) 171 { 172 unsigned long ins, opcd, bo, bi, bd, aa, lk; 173 long long dst; 174 long long max = 1l << 13; 175 long long min = -(1l << 13); 176 177 opcd = op->bytes[0]; 178 aa = op->bytes[1]; 179 lk = op->bytes[2]; 180 181 bo = args[0]->sym->value; 182 bi = args[1]->sym->value; 183 184 dst = args[2]->sym->value; 185 if (dst & 0x3) 186 error("unaligned branch"); 187 if (aa) 188 dst -= getpc() - 4; 189 190 if (dst < min || dst > max) 191 error("out of range branch"); 192 bd = dst; 193 bd >>= 2; 194 195 ins = opcd<<26 | bo<<21 | bi<<16 | bd<<11 | aa<<1 | lk; 196 emit_packed(ins); 197 } 198 199 void 200 sc_form(Op *op, Node **args) 201 { 202 abort(); 203 } 204 205 void 206 d_form(Op *op, Node **args) 207 { 208 abort(); 209 } 210 211 void 212 ds_form(Op *op, Node **args) 213 { 214 abort(); 215 } 216 217 void 218 dq_form(Op *op, Node **args) 219 { 220 abort(); 221 } 222 223 void 224 x_form(Op *op, Node **args) 225 { 226 abort(); 227 } 228 229 void 230 xl_form(Op *op, Node **args) 231 { 232 unsigned long ins, bo, bi, bh, lk; 233 unsigned long opcd1, opcd2; 234 long long dst; 235 236 opcd1 = op->bytes[0]; 237 opcd2 = op->bytes[1]<<8 | op->bytes[2]; 238 lk = op->bytes[3]; 239 240 bo = args[0]->sym->value; 241 bi = args[1]->sym->value; 242 bh = args[2]->sym->value; 243 244 ins = opcd1<<26 | bo<<21 | bi<<16 | bh<<11 | opcd2<<1 | lk; 245 emit_packed(ins); 246 } 247 248 void 249 xfx_form(Op *op, Node **args) 250 { 251 abort(); 252 } 253 254 void 255 xlfdorm_form(Op *op, Node **args) 256 { 257 abort(); 258 } 259 260 void 261 xx1_form(Op *op, Node **args) 262 { 263 abort(); 264 } 265 266 void 267 xx2_form(Op *op, Node **args) 268 { 269 abort(); 270 } 271 272 void 273 xx3_form(Op *op, Node **args) 274 { 275 abort(); 276 } 277 278 void 279 xx4_form(Op *op, Node **args) 280 { 281 abort(); 282 } 283 284 void 285 xs_form(Op *op, Node **args) 286 { 287 abort(); 288 } 289 290 void 291 xo_form(Op *op, Node **args) 292 { 293 abort(); 294 } 295 296 void 297 a_form(Op *op, Node **args) 298 { 299 abort(); 300 } 301 302 void 303 m_form(Op *op, Node **args) 304 { 305 abort(); 306 } 307 308 void 309 md_form(Op *op, Node **args) 310 { 311 abort(); 312 } 313 314 void 315 mds_form(Op *op, Node **args) 316 { 317 abort(); 318 } 319 320 void 321 va_form(Op *op, Node **args) 322 { 323 abort(); 324 } 325 326 void 327 vc_form(Op *op, Node **args) 328 { 329 abort(); 330 } 331 332 void 333 vx_form(Op *op, Node **args) 334 { 335 abort(); 336 } 337 338 void 339 evs_form(Op *op, Node **args) 340 { 341 abort(); 342 } 343 344 void 345 z22_form(Op *op, Node **args) 346 { 347 abort(); 348 } 349 350 void 351 z23_form(Op *op, Node **args) 352 { 353 abort(); 354 }