mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 02:30:44 +00:00
g_asr, g_asl: Use ROL/ROR for char shifts by >= 6
Instead of `val` right (left) shifts, we can also do `9 - val` left (right) rotates and a mask. This saves 3 bytes and 8 cycles for `val == 7` and 1 byte and 4 cycles for `val == 6`.
This commit is contained in:
parent
ef258bdc19
commit
e0c12c90cd
@ -3114,9 +3114,26 @@ 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_FORCECHAR) {
|
||||||
if ((flags & CF_UNSIGNED) != 0 && val < 8) {
|
val &= 7;
|
||||||
while (val--) {
|
if ((flags & CF_UNSIGNED) != 0) {
|
||||||
AddCodeLine ("lsr a");
|
/* Instead of `val` right shifts, we can also do `9 - val` left rotates
|
||||||
|
** and a mask. This saves 3 bytes and 8 cycles for `val == 7` and
|
||||||
|
** 1 byte and 4 cycles for `val == 6`.
|
||||||
|
*/
|
||||||
|
if (val < 6) {
|
||||||
|
while (val--) {
|
||||||
|
AddCodeLine ("lsr a"); /* 1 byte, 2 cycles */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned i;
|
||||||
|
/* The first ROL shifts in garbage and sets carry to the high bit.
|
||||||
|
** The garbage is cleaned up by the mask.
|
||||||
|
*/
|
||||||
|
for (i = val; i < 9; ++i) {
|
||||||
|
AddCodeLine ("rol a"); /* 1 byte, 2 cycles */
|
||||||
|
}
|
||||||
|
/* 2 bytes, 2 cycles */
|
||||||
|
AddCodeLine ("and #$%02X", 0xFF >> val);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (val <= 2) {
|
} else if (val <= 2) {
|
||||||
@ -3270,9 +3287,21 @@ void g_asl (unsigned flags, unsigned long val)
|
|||||||
if (flags & CF_CONST) {
|
if (flags & CF_CONST) {
|
||||||
switch (flags & CF_TYPEMASK) {
|
switch (flags & CF_TYPEMASK) {
|
||||||
case CF_CHAR:
|
case CF_CHAR:
|
||||||
if ((flags & CF_FORCECHAR) != 0 && val <= 6) {
|
if ((flags & CF_FORCECHAR) != 0) {
|
||||||
while (val--) {
|
val &= 7;
|
||||||
AddCodeLine ("asl a");
|
/* Large shifts are faster and smaller with ROR. See g_asr for detailed
|
||||||
|
** byte and cycle counts.
|
||||||
|
*/
|
||||||
|
if (val < 6) {
|
||||||
|
while (val--) {
|
||||||
|
AddCodeLine ("asl a");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned i;
|
||||||
|
for (i = val; i < 9; ++i) {
|
||||||
|
AddCodeLine ("ror a");
|
||||||
|
}
|
||||||
|
AddCodeLine ("and #$%02X", (~0U << val) & 0xFF);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user