mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-18 03:29:49 +00:00
Improve code generation for comparisons.
This converts comparisons like x > N (with constant N) to instead be evaluated as x >= N+1, since >= comparisons generate better code. This is possible as long as N is not the maximum value in the type, but in that case the comparison is always false. There are also a few other tweaks to the generated code in some cases.
This commit is contained in:
parent
7b0dda5a5e
commit
9b31e7f72a
1
CGI.pas
1
CGI.pas
@ -148,6 +148,7 @@ const
|
||||
m_ply = 122;
|
||||
m_plp = 40;
|
||||
m_rep = 194;
|
||||
m_rol_a = $2A;
|
||||
m_ror_a = $6A;
|
||||
m_rtl = 107;
|
||||
m_rts = 96;
|
||||
|
143
Gen.pas
143
Gen.pas
@ -1017,6 +1017,7 @@ var
|
||||
lab1,lab2,lab3,lab4: integer; {label numbers}
|
||||
num: integer; {constant to compare to}
|
||||
simple: boolean; {is this a simple case?}
|
||||
alwaysFalse: boolean; {is the comparison always false?}
|
||||
|
||||
|
||||
procedure Switch;
|
||||
@ -1067,36 +1068,38 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||
(op^.right^.opcode = pc_ldc) then begin
|
||||
GenTree(op^.left);
|
||||
num := op^.right^.q;
|
||||
{Convert x > N comparisons to x >= N+1, unless N is max value }
|
||||
{(in which case x > N is always false). }
|
||||
alwaysFalse := false;
|
||||
if op^.opcode = pc_grt then begin
|
||||
if ((op^.optype in [cgByte,cgWord]) and (num = 32767))
|
||||
or ((op^.optype in [cgUByte,cgUWord]) and (num = -1)) then
|
||||
alwaysFalse := true
|
||||
else begin
|
||||
op^.opcode := pc_geq;
|
||||
num := num+1;
|
||||
end; {else}
|
||||
end; {if}
|
||||
lab1 := GenLabel;
|
||||
if rOpcode = pc_fjp then begin
|
||||
if op^.optype in [cgByte,cgWord] then begin
|
||||
if alwaysFalse then
|
||||
GenNative(m_brl, longrelative, lb, nil, 0)
|
||||
else if op^.optype in [cgByte,cgWord] then begin
|
||||
if NeedsCondition(op^.left^.opcode) then
|
||||
GenImpliedForFlags(m_tax);
|
||||
if (num >= 0) and (num < 4) then begin
|
||||
if op^.opcode = pc_geq then begin
|
||||
if num <> 0 then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
end; {if}
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
if num <> 0 then
|
||||
GenLab(lab2);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if}
|
||||
else {if opcode = pc_grt then} begin
|
||||
if (num >= 0) and (num < 3) then begin
|
||||
if num <> 0 then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
for i := 0 to num do
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
if num <> 0 then
|
||||
GenLab(lab2);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else if}
|
||||
end {if (num >= 0) and (num < 4)}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if (num >= 0) and (num < 3)}
|
||||
else begin
|
||||
lab2 := GenLabel;
|
||||
if num > 0 then
|
||||
@ -1104,14 +1107,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||
else
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
GenLab(lab3);
|
||||
end
|
||||
else
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if num > 0 then begin
|
||||
GenLab(lab1);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
@ -1124,49 +1120,30 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||
end; {else if}
|
||||
end {if}
|
||||
else {if optype in [cgUByte,cgUWord] then} begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
if num <> 0 then begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab2);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end {if rOpcode = pc_fjp}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
if op^.optype in [cgByte,cgWord] then begin
|
||||
if alwaysFalse then
|
||||
{nothing to generate}
|
||||
else if op^.optype in [cgByte,cgWord] then begin
|
||||
if NeedsCondition(op^.left^.opcode) then
|
||||
GenImpliedForFlags(m_tax);
|
||||
if (num >= 0) and (num < 4) then begin
|
||||
lab2 := GenLabel;
|
||||
if op^.opcode = pc_geq then begin
|
||||
if (num >= 0) and (num < 3) then begin
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
if num > 0 then begin
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
if num > 0 then begin
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
end {if}
|
||||
else {if op^.opcode = pc_grt then} begin
|
||||
if num > 0 then begin
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
for i := 0 to num do
|
||||
GenImplied(m_dea);
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
end; {else}
|
||||
GenLab(lab2);
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if (num >= 0) and (num < 4)}
|
||||
end {if (num >= 0) and (num < 3)}
|
||||
else begin
|
||||
lab2 := GenLabel;
|
||||
if num > 0 then
|
||||
@ -1174,10 +1151,6 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||
else
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcc, relative, lab2, nil, 0);
|
||||
if num > 0 then begin
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
@ -1189,51 +1162,37 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end; {else}
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
end; {else}
|
||||
end {if}
|
||||
else {if optype in [cgUByte,cgUWord] then} begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
if num <> 0 then begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab2);
|
||||
GenLab(lab1);
|
||||
if num <> 0 then
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end {if rOpcode = pc_tjp}
|
||||
else if alwaysFalse then
|
||||
GenNative(m_lda_imm, immediate, 0, nil, 0)
|
||||
else if op^.optype in [cgByte,cgWord] then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_ldx_imm, immediate, 1, nil, 0);
|
||||
GenImplied(m_sec);
|
||||
GenNative(m_sbc_imm, immediate, num, nil, 0);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bvs, relative, lab1, nil, 0);
|
||||
GenNative(m_eor_imm, immediate, $8000, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_txa);
|
||||
end {else if}
|
||||
else begin
|
||||
GenNative(m_ldx_imm, immediate, 0, nil, 0);
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenImplied(m_inx);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_txa);
|
||||
GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||
GenImplied(m_rol_a);
|
||||
end; {else if}
|
||||
end {if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||
(op^.right^.opcode = pc_ldc)}
|
||||
|
@ -793,7 +793,7 @@ label 1,2,3;
|
||||
m_ina,m_lda_abs,m_lda_absx,m_lda_dir,m_lda_dirx,m_lda_imm,m_lda_indl,
|
||||
m_lda_indly,m_lda_long,m_lda_longx,m_lda_s,m_lsr_a,m_ora_abs,m_ora_dir,
|
||||
m_ora_dirX,m_ora_imm,m_ora_long,m_ora_longX,m_ora_s,m_ora_indl,
|
||||
m_ora_indly,m_pla,m_ror_a,m_sbc_abs,m_sbc_dir,m_sbc_imm,m_sbc_s,
|
||||
m_ora_indly,m_pla,m_rol_a,m_ror_a,m_sbc_abs,m_sbc_dir,m_sbc_imm,m_sbc_s,
|
||||
m_sbc_indl,m_sbc_indly,m_tax,m_tay,m_tcd,m_tdc,m_txa,m_tya];
|
||||
end; {NZMatchA}
|
||||
|
||||
@ -805,7 +805,7 @@ case p_opcode of
|
||||
m_ora_dir,m_ora_dirX,m_ora_imm,m_ora_long,m_ora_longX,m_ora_s,m_pla,
|
||||
m_sbc_abs,m_sbc_dir,m_sbc_imm,m_sbc_s,m_tdc,m_tsc,m_adc_indl,m_adc_indly,
|
||||
m_and_indl,m_and_indly,m_ora_indl,m_ora_indly,m_sbc_indl,m_sbc_indly,
|
||||
m_eor_indl,m_eor_indly,m_ror_a:
|
||||
m_eor_indl,m_eor_indly,m_rol_a,m_ror_a:
|
||||
aRegister.condition := regUnknown;
|
||||
|
||||
m_ldy_absX,m_ldy_dirX,m_ply:
|
||||
|
Loading…
x
Reference in New Issue
Block a user