mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 17:30:50 +00:00
Almost fixed Issue #169. The only denominator not working right now is -2147483648.
This commit is contained in:
parent
82c8bd6e2b
commit
e98fe04cc2
@ -1479,48 +1479,9 @@ void g_scale (unsigned flags, long val)
|
|||||||
|
|
||||||
/* Scale down */
|
/* Scale down */
|
||||||
val = -val;
|
val = -val;
|
||||||
if ((p2 = PowerOf2 (val)) > 0 && p2 <= 4) {
|
|
||||||
|
|
||||||
/* Factor is 2, 4, 8 and 16 use special function */
|
/* g_div will use asr if feasible */
|
||||||
switch (flags & CF_TYPEMASK) {
|
if (val != 1) {
|
||||||
|
|
||||||
case CF_CHAR:
|
|
||||||
if (flags & CF_FORCECHAR) {
|
|
||||||
if (flags & CF_UNSIGNED) {
|
|
||||||
while (p2--) {
|
|
||||||
AddCodeLine ("lsr a");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} else if (p2 <= 2) {
|
|
||||||
AddCodeLine ("cmp #$80");
|
|
||||||
AddCodeLine ("ror a");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
case CF_INT:
|
|
||||||
if (flags & CF_UNSIGNED) {
|
|
||||||
AddCodeLine ("jsr lsrax%d", p2);
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr asrax%d", p2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CF_LONG:
|
|
||||||
if (flags & CF_UNSIGNED) {
|
|
||||||
AddCodeLine ("jsr lsreax%d", p2);
|
|
||||||
} else {
|
|
||||||
AddCodeLine ("jsr asreax%d", p2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
typeerror (flags);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (val != 1) {
|
|
||||||
|
|
||||||
/* Use a division instead */
|
/* Use a division instead */
|
||||||
g_div (flags | CF_CONST, val);
|
g_div (flags | CF_CONST, val);
|
||||||
@ -2668,11 +2629,52 @@ void g_div (unsigned flags, unsigned long val)
|
|||||||
"tosdivax", "tosudivax", "tosdiveax", "tosudiveax"
|
"tosdivax", "tosudivax", "tosdiveax", "tosudiveax"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned DoShiftLabel, EndLabel;
|
||||||
|
|
||||||
/* Do strength reduction if the value is constant and a power of two */
|
/* Do strength reduction if the value is constant and a power of two */
|
||||||
int p2;
|
int p2;
|
||||||
if ((flags & CF_CONST) && (p2 = PowerOf2 (val)) >= 0) {
|
if ((flags & CF_CONST) && (p2 = PowerOf2 (val)) >= 0) {
|
||||||
/* Generate a shift instead */
|
/* Generate a shift instead */
|
||||||
g_asr (flags, p2);
|
if (flags & CF_UNSIGNED) {
|
||||||
|
g_asr (flags, p2);
|
||||||
|
} else if (p2 > 0) {
|
||||||
|
/* GitHub #169 - if abs(expr) < abs(val), the result is always 0 */
|
||||||
|
DoShiftLabel = GetLocalLabel ();
|
||||||
|
EndLabel = GetLocalLabel ();
|
||||||
|
switch (flags & CF_TYPEMASK) {
|
||||||
|
case CF_CHAR:
|
||||||
|
if (flags & CF_FORCECHAR) {
|
||||||
|
AddCodeLine ("cmp #$00");
|
||||||
|
AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case CF_INT:
|
||||||
|
AddCodeLine ("cpx #$00");
|
||||||
|
AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CF_LONG:
|
||||||
|
AddCodeLine ("ldy sreg+1");
|
||||||
|
AddCodeLine ("bpl %s", LocalLabelName (DoShiftLabel));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
typeerror (flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_save (flags);
|
||||||
|
g_le (flags, (unsigned long)-(signed long)val);
|
||||||
|
AddCodeLine ("lsr a");
|
||||||
|
g_restore (flags);
|
||||||
|
AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel));
|
||||||
|
g_getimmed (flags | CF_ABSOLUTE, 0, 0);
|
||||||
|
g_jump (EndLabel);
|
||||||
|
g_defcodelabel (DoShiftLabel);
|
||||||
|
g_asr (flags, p2);
|
||||||
|
g_defcodelabel (EndLabel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Generate a division */
|
/* Generate a division */
|
||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
@ -2956,6 +2958,22 @@ void g_asr (unsigned flags, unsigned long val)
|
|||||||
switch (flags & CF_TYPEMASK) {
|
switch (flags & CF_TYPEMASK) {
|
||||||
|
|
||||||
case CF_CHAR:
|
case CF_CHAR:
|
||||||
|
if (flags & CF_FORCECHAR) {
|
||||||
|
if ((flags & CF_UNSIGNED) != 0 && val <= 4) {
|
||||||
|
while (val--) {
|
||||||
|
AddCodeLine ("lsr a");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (val <= 2) {
|
||||||
|
while (val--) {
|
||||||
|
AddCodeLine ("cmp #$80");
|
||||||
|
AddCodeLine ("ror a");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case CF_INT:
|
case CF_INT:
|
||||||
val &= 0x0F;
|
val &= 0x0F;
|
||||||
if (val >= 8) {
|
if (val >= 8) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user