Mercurial > hg-old > index.cgi
comparison lwasm/insn_indexed.c @ 382:eacdae8a1575
Various bugfixes
author | lost@starbug |
---|---|
date | Sat, 15 May 2010 13:39:21 -0600 |
parents | 8f9d72cfb897 |
children | 2d7255509130 |
comparison
equal
deleted
inserted
replaced
381:1624a36f12a3 | 382:eacdae8a1575 |
---|---|
169 if (!e || **p != ']') | 169 if (!e || **p != ']') |
170 { | 170 { |
171 lwasm_register_error(as, l, "Bad operand"); | 171 lwasm_register_error(as, l, "Bad operand"); |
172 return; | 172 return; |
173 } | 173 } |
174 lwasm_save_expr(l, 0, e); | |
174 | 175 |
175 (*p)++; | 176 (*p)++; |
176 l -> lint = 2; | 177 l -> lint = 2; |
177 return; | 178 return; |
178 } | 179 } |
285 { | 286 { |
286 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; | 287 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; |
287 } | 288 } |
288 } | 289 } |
289 | 290 |
290 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force) | 291 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen) |
291 { | 292 { |
292 // here, we have an expression which needs to be | 293 // here, we have an expression which needs to be |
293 // resolved; the post byte is determined here as well | 294 // resolved; the post byte is determined here as well |
294 lw_expr_t e; | 295 lw_expr_t e, e2, e3; |
295 int pb = -1; | 296 int pb = -1; |
296 int v; | 297 int v; |
298 | |
299 if (l -> len != -1) | |
300 return; | |
301 | |
297 e = lwasm_fetch_expr(l, 0); | 302 e = lwasm_fetch_expr(l, 0); |
303 if (!lw_expr_istype(e, lw_expr_type_int)) | |
304 { | |
305 // temporarily set the instruction length to see if we get a | |
306 // constant for our expression; if so, we can select an instruction | |
307 // size | |
308 e2 = lw_expr_copy(e); | |
309 // magic 2 for 8 bit (post byte + offset) | |
310 l -> len = OPLEN(instab[l -> insn].ops[0]) + elen + 2; | |
311 lwasm_reduce_expr(as, e2); | |
312 // l -> len += 1; | |
313 // e3 = lw_expr_copy(e); | |
314 // lwasm_reduce_expr(as, e3); | |
315 l -> len = -1; | |
316 if (lw_expr_istype(e2, lw_expr_type_int)) | |
317 { | |
318 v = lw_expr_intval(e2); | |
319 // we have a reducible expression here which depends on | |
320 // the size of this instruction | |
321 if (v < -128 || v > 127) | |
322 { | |
323 l -> lint = 2; | |
324 switch (l -> pb & 0x07) | |
325 { | |
326 case 0: | |
327 case 1: | |
328 case 2: | |
329 case 3: | |
330 pb = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); | |
331 break; | |
332 | |
333 case 4: // W | |
334 pb = (l -> pb & 0x80) ? 0xD0 : 0xCF; | |
335 break; | |
336 | |
337 case 5: // PCR | |
338 case 6: // PC | |
339 pb = (l -> pb & 0x80) ? 0x9D : 0x8D; | |
340 break; | |
341 } | |
342 | |
343 l -> pb = pb; | |
344 lw_expr_destroy(e2); | |
345 // lw_expr_destroy(e3); | |
346 return; | |
347 } | |
348 else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15) | |
349 { | |
350 // if not a 5 bit value, is indirect, or is not X,Y,U,S | |
351 l -> lint = 1; | |
352 switch (l -> pb & 0x07) | |
353 { | |
354 case 0: | |
355 case 1: | |
356 case 2: | |
357 case 3: | |
358 pb = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); | |
359 break; | |
360 | |
361 case 4: // W | |
362 // use 16 bit because W doesn't have 8 bit, unless 0 | |
363 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) | |
364 { | |
365 pb = (l -> pb & 0x80) ? 0x90 : 0x8F; | |
366 l -> lint = 0; | |
367 } | |
368 else | |
369 { | |
370 pb = (l -> pb & 0x80) ? 0xD0 : 0xCF; | |
371 l -> lint = 2; | |
372 } | |
373 break; | |
374 | |
375 case 5: // PCR | |
376 case 6: // PC | |
377 pb = (l -> pb & 0x80) ? 0x9C : 0x8C; | |
378 break; | |
379 } | |
380 | |
381 l -> pb = pb; | |
382 return; | |
383 } | |
384 else | |
385 { | |
386 // we have X,Y,U,S and a possible 16 bit here | |
387 l -> lint = 0; | |
388 | |
389 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) | |
390 { | |
391 pb = (l -> pb & 0x03) << 5 | 0x84; | |
392 } | |
393 else | |
394 { | |
395 pb = (l -> pb & 0x03) << 5 | v & 0x1F; | |
396 } | |
397 l -> pb = pb; | |
398 return; | |
399 } | |
400 } | |
401 } | |
402 | |
298 if (lw_expr_istype(e, lw_expr_type_int)) | 403 if (lw_expr_istype(e, lw_expr_type_int)) |
299 { | 404 { |
300 // we know how big it is | 405 // we know how big it is |
301 v = lw_expr_intval(e); | 406 v = lw_expr_intval(e); |
302 if (v < -128 || v > 127) | 407 if (v < -128 || v > 127) |
361 l -> pb = pb; | 466 l -> pb = pb; |
362 return; | 467 return; |
363 } | 468 } |
364 else | 469 else |
365 { | 470 { |
366 // we have X,Y,U,S and a possible 15 bit here | 471 // we have X,Y,U,S and a possible 16 bit here |
367 l -> lint = 0; | 472 l -> lint = 0; |
368 | 473 |
369 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) | 474 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) |
370 { | 475 { |
476 pb = (l -> pb & 0x03) << 5 | 0x84; | |
477 } | |
478 else | |
479 { | |
371 pb = (l -> pb & 0x03) << 5 | v & 0x1F; | 480 pb = (l -> pb & 0x03) << 5 | v & 0x1F; |
372 } | 481 } |
373 else | |
374 pb = (l -> pb & 0x03) << 5 | 0x84; | |
375 l -> pb = pb; | 482 l -> pb = pb; |
376 return; | 483 return; |
377 } | 484 } |
378 } | 485 } |
379 else | 486 else |
388 } | 495 } |
389 | 496 |
390 RESOLVEFUNC(insn_resolve_indexed) | 497 RESOLVEFUNC(insn_resolve_indexed) |
391 { | 498 { |
392 if (l -> lint == -1) | 499 if (l -> lint == -1) |
393 insn_resolve_indexed_aux(as, l, force); | 500 insn_resolve_indexed_aux(as, l, force, 0); |
394 | 501 |
395 if (l -> lint != -1 && l -> pb != -1) | 502 if (l -> lint != -1 && l -> pb != -1) |
396 { | 503 { |
397 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; | 504 l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1; |
398 } | 505 } |