comparison lwasm/insn_indexed.c @ 373:8f9d72cfb897

Bugfixes for indexed addressing modes
author lost@starbug
date Thu, 22 Apr 2010 18:30:30 -0600
parents 9c24d9d485b9
children eacdae8a1575
comparison
equal deleted inserted replaced
372:90de73ba0cac 373:8f9d72cfb897
290 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force) 290 void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force)
291 { 291 {
292 // here, we have an expression which needs to be 292 // here, we have an expression which needs to be
293 // resolved; the post byte is determined here as well 293 // resolved; the post byte is determined here as well
294 lw_expr_t e; 294 lw_expr_t e;
295 295 int pb = -1;
296 int v;
296 e = lwasm_fetch_expr(l, 0); 297 e = lwasm_fetch_expr(l, 0);
297 if (lw_expr_istype(e, lw_expr_type_int)) 298 if (lw_expr_istype(e, lw_expr_type_int))
298 { 299 {
299 // we know how big it is 300 // we know how big it is
300 int v;
301 v = lw_expr_intval(e); 301 v = lw_expr_intval(e);
302 if (v < -128 || v > 127) 302 if (v < -128 || v > 127)
303 { 303 {
304 do16bit:
304 l -> lint = 2; 305 l -> lint = 2;
305 switch (l -> pb & 0x07) 306 switch (l -> pb & 0x07)
306 { 307 {
307 case 0: 308 case 0:
308 case 1: 309 case 1:
309 case 2: 310 case 2:
310 case 3: 311 case 3:
311 v = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); 312 pb = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
312 break; 313 break;
313 314
314 case 4: // W 315 case 4: // W
315 v = (l -> pb & 0x80) ? 0xD0 : 0xCF; 316 pb = (l -> pb & 0x80) ? 0xD0 : 0xCF;
316 break; 317 break;
317 318
318 case 5: // PCR 319 case 5: // PCR
319 case 6: // PC 320 case 6: // PC
320 v = (l -> pb & 0x80) ? 0x9D : 0x8D; 321 pb = (l -> pb & 0x80) ? 0x9D : 0x8D;
321 break; 322 break;
322 } 323 }
323 324
325 l -> pb = pb;
324 return; 326 return;
325 } 327 }
326 else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15) 328 else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15)
327 { 329 {
328 // if not a 5 bit value, is indirect, or is not X,Y,U,S 330 // if not a 5 bit value, is indirect, or is not X,Y,U,S
331 { 333 {
332 case 0: 334 case 0:
333 case 1: 335 case 1:
334 case 2: 336 case 2:
335 case 3: 337 case 3:
336 v = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); 338 pb = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
337 break; 339 break;
338 340
339 case 4: // W 341 case 4: // W
340 // use 16 bit because W doesn't have 8 bit, unless 0 342 // use 16 bit because W doesn't have 8 bit, unless 0
341 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) 343 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
342 { 344 {
343 v = (l -> pb & 0x80) ? 0x90 : 0x8F; 345 pb = (l -> pb & 0x80) ? 0x90 : 0x8F;
344 l -> lint = 0; 346 l -> lint = 0;
345 } 347 }
346 else 348 else
347 { 349 {
348 v = (l -> pb & 0x80) ? 0xD0 : 0xCF; 350 pb = (l -> pb & 0x80) ? 0xD0 : 0xCF;
349 l -> lint = 2; 351 l -> lint = 2;
350 } 352 }
351 break; 353 break;
352 354
353 case 5: // PCR 355 case 5: // PCR
354 case 6: // PC 356 case 6: // PC
355 v = (l -> pb & 0x80) ? 0x9C : 0x8C; 357 pb = (l -> pb & 0x80) ? 0x9C : 0x8C;
356 break; 358 break;
357 } 359 }
358 360
361 l -> pb = pb;
359 return; 362 return;
360 } 363 }
361 else 364 else
362 { 365 {
363 // we have X,Y,U,S and a possible 15 bit here 366 // we have X,Y,U,S and a possible 15 bit here
364 l -> lint = 0; 367 l -> lint = 0;
365 368
366 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) 369 if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
367 { 370 {
368 v = (l -> pb & 0x03) << 5 | v & 0x1F; 371 pb = (l -> pb & 0x03) << 5 | v & 0x1F;
369 } 372 }
370 else 373 else
371 v = (l -> pb & 0x03) << 5 | 0x84; 374 pb = (l -> pb & 0x03) << 5 | 0x84;
375 l -> pb = pb;
372 return; 376 return;
373 } 377 }
374 } 378 }
375 else 379 else
376 { 380 {
377 // we don't know how big it is 381 // we don't know how big it is
378 if (!force) 382 if (!force)
379 return; 383 return;
380 // force 16 bit if we don't know 384 // force 16 bit if we don't know
381 l -> lint = 2; 385 l -> lint = 2;
386 goto do16bit;
382 } 387 }
383 } 388 }
384 389
385 RESOLVEFUNC(insn_resolve_indexed) 390 RESOLVEFUNC(insn_resolve_indexed)
386 { 391 {