1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-05 21:29:03 +00:00

Improved code for shifts.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4077 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-08-29 20:16:52 +00:00
parent b4855e017b
commit b0a89ff421

View File

@ -2941,44 +2941,55 @@ void g_asr (unsigned flags, unsigned long val)
case CF_CHAR: case CF_CHAR:
case CF_INT: case CF_INT:
if (val >= 8 && (flags & CF_UNSIGNED)) { val &= 0x0F;
AddCodeLine ("txa"); if (val >= 8) {
ldxconst (0); if (flags & CF_UNSIGNED) {
AddCodeLine ("txa");
ldxconst (0);
} else {
unsigned L = GetLocalLabel();
AddCodeLine ("cpx #$80"); /* Sign bit into carry */
AddCodeLine ("txa");
AddCodeLine ("ldx #$00");
AddCodeLine ("bcc %s", LocalLabelName (L));
AddCodeLine ("dex"); /* Make $FF */
g_defcodelabel (L);
}
val -= 8; val -= 8;
} }
if (val == 0) { if (val >= 4) {
/* Done */ if (flags & CF_UNSIGNED) {
return; AddCodeLine ("jsr shrax4");
} else if (val >= 1 && val <= 4) { } else {
AddCodeLine ("jsr asrax4");
}
val -= 4;
}
if (val > 0) {
if (flags & CF_UNSIGNED) { if (flags & CF_UNSIGNED) {
AddCodeLine ("jsr shrax%ld", val); AddCodeLine ("jsr shrax%ld", val);
} else { } else {
AddCodeLine ("jsr asrax%ld", val); AddCodeLine ("jsr asrax%ld", val);
} }
return;
} }
break; return;
case CF_LONG: case CF_LONG:
if (val == 0) { val &= 0x1F;
/* Nothing to do */ if (val >= 24) {
return; AddCodeLine ("ldx #$00");
} else if (val >= 1 && val <= 4) { AddCodeLine ("lda sreg+1");
if (flags & CF_UNSIGNED) { if ((flags & CF_UNSIGNED) == 0) {
AddCodeLine ("jsr shreax%ld", val); unsigned L = GetLocalLabel();
} else { AddCodeLine ("bpl %s", LocalLabelName (L));
AddCodeLine ("jsr asreax%ld", val); AddCodeLine ("dex");
g_defcodelabel (L);
} }
return; AddCodeLine ("stx sreg");
} else if (val == 8 && (flags & CF_UNSIGNED)) { AddCodeLine ("stx sreg+1");
AddCodeLine ("txa"); val -= 24;
AddCodeLine ("ldx sreg"); }
AddCodeLine ("ldy sreg+1"); if (val >= 16) {
AddCodeLine ("sty sreg");
AddCodeLine ("ldy #$00");
AddCodeLine ("sty sreg+1");
return;
} else if (val == 16) {
AddCodeLine ("ldy #$00"); AddCodeLine ("ldy #$00");
AddCodeLine ("ldx sreg+1"); AddCodeLine ("ldx sreg+1");
if ((flags & CF_UNSIGNED) == 0) { if ((flags & CF_UNSIGNED) == 0) {
@ -2990,9 +3001,42 @@ void g_asr (unsigned flags, unsigned long val)
AddCodeLine ("lda sreg"); AddCodeLine ("lda sreg");
AddCodeLine ("sty sreg+1"); AddCodeLine ("sty sreg+1");
AddCodeLine ("sty sreg"); AddCodeLine ("sty sreg");
return; val -= 16;
} }
break; if (val >= 8) {
AddCodeLine ("txa");
AddCodeLine ("ldx sreg");
AddCodeLine ("ldy sreg+1");
AddCodeLine ("sty sreg");
if ((flags & CF_UNSIGNED) == 0) {
unsigned L = GetLocalLabel();
AddCodeLine ("cpy #$80");
AddCodeLine ("ldy #$00");
AddCodeLine ("bcc %s", LocalLabelName (L));
AddCodeLine ("dey");
g_defcodelabel (L);
} else {
AddCodeLine ("ldy #$00");
}
AddCodeLine ("sty sreg+1");
val -= 8;
}
if (val >= 4) {
if (flags & CF_UNSIGNED) {
AddCodeLine ("jsr shreax4");
} else {
AddCodeLine ("jsr asreax4");
}
val -= 4;
}
if (val > 0) {
if (flags & CF_UNSIGNED) {
AddCodeLine ("jsr shreax%ld", val);
} else {
AddCodeLine ("jsr asreax%ld", val);
}
}
return;
default: default:
typeerror (flags); typeerror (flags);
@ -3029,50 +3073,69 @@ void g_asl (unsigned flags, unsigned long val)
case CF_CHAR: case CF_CHAR:
case CF_INT: case CF_INT:
val &= 0x0F;
if (val >= 8) { if (val >= 8) {
AddCodeLine ("tax"); AddCodeLine ("tax");
AddCodeLine ("lda #$00"); AddCodeLine ("lda #$00");
val -= 8; val -= 8;
} }
if (val == 0) { if (val >= 4) {
/* Done */ if (flags & CF_UNSIGNED) {
return; AddCodeLine ("jsr shlax4");
} else if (val >= 1 && val <= 4) { } else {
AddCodeLine ("jsr aslax4");
}
val -= 4;
}
if (val > 0) {
if (flags & CF_UNSIGNED) { if (flags & CF_UNSIGNED) {
AddCodeLine ("jsr shlax%ld", val); AddCodeLine ("jsr shlax%ld", val);
} else { } else {
AddCodeLine ("jsr aslax%ld", val); AddCodeLine ("jsr aslax%ld", val);
} }
return;
} }
break; return;
case CF_LONG: case CF_LONG:
if (val == 0) { val &= 0x1F;
/* Nothing to do */ if (val >= 24) {
return; AddCodeLine ("sta sreg+1");
} else if (val >= 1 && val <= 4) { AddCodeLine ("lda #$00");
if (flags & CF_UNSIGNED) { AddCodeLine ("tax");
AddCodeLine ("jsr shleax%ld", val); AddCodeLine ("sta sreg");
} else { val -= 24;
AddCodeLine ("jsr asleax%ld", val); }
} if (val >= 16) {
return; AddCodeLine ("stx sreg+1");
} else if (val == 8) { AddCodeLine ("sta sreg");
AddCodeLine ("lda #$00");
AddCodeLine ("tax");
val -= 16;
}
if (val >= 8) {
AddCodeLine ("ldy sreg"); AddCodeLine ("ldy sreg");
AddCodeLine ("sty sreg+1"); AddCodeLine ("sty sreg+1");
AddCodeLine ("stx sreg"); AddCodeLine ("stx sreg");
AddCodeLine ("tax"); AddCodeLine ("tax");
AddCodeLine ("lda #$00"); AddCodeLine ("lda #$00");
return; val -= 8;
} else if (val == 16) {
AddCodeLine ("stx sreg+1");
AddCodeLine ("sta sreg");
AddCodeLine ("lda #$00");
AddCodeLine ("tax");
return;
} }
break; if (val > 4) {
if (flags & CF_UNSIGNED) {
AddCodeLine ("jsr shleax4");
} else {
AddCodeLine ("jsr asleax4");
}
val -= 4;
}
if (val > 0) {
if (flags & CF_UNSIGNED) {
AddCodeLine ("jsr shleax%ld", val);
} else {
AddCodeLine ("jsr asleax%ld", val);
}
}
return;
default: default:
typeerror (flags); typeerror (flags);