mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-12-22 07:30:54 +00:00
Optimize 16-bit multiplication by various constants.
This optimizes most multiplications by a power of 2 or the sum of two powers of 2, converting them to equivalent operations using shifts which should be faster than the general-purpose multiplication routine.
This commit is contained in:
parent
497e5c036b
commit
393b7304a0
1
CGI.pas
1
CGI.pas
@ -147,6 +147,7 @@ const
|
|||||||
m_ply = 122;
|
m_ply = 122;
|
||||||
m_plp = 40;
|
m_plp = 40;
|
||||||
m_rep = 194;
|
m_rep = 194;
|
||||||
|
m_ror_a = $6A;
|
||||||
m_rtl = 107;
|
m_rtl = 107;
|
||||||
m_rts = 96;
|
m_rts = 96;
|
||||||
m_sbc_abs = 237;
|
m_sbc_abs = 237;
|
||||||
|
128
Gen.pas
128
Gen.pas
@ -6441,29 +6441,117 @@ procedure GenTree {op: icptr};
|
|||||||
|
|
||||||
var
|
var
|
||||||
nd: icptr;
|
nd: icptr;
|
||||||
|
val: integer;
|
||||||
|
|
||||||
begin {GenMpi}
|
begin {GenMpi}
|
||||||
if not Complex(op^.left) then
|
if ((op^.left^.opcode = pc_ldc) or (op^.right^.opcode = pc_ldc))
|
||||||
|
and ((op^.opcode = pc_umi) or (not rangeCheck)) then begin
|
||||||
|
if op^.left^.opcode = pc_ldc then begin
|
||||||
|
val := op^.left^.q;
|
||||||
|
nd := op^.right;
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
val := op^.right^.q;
|
||||||
|
nd := op^.left;
|
||||||
|
end; {else}
|
||||||
|
if nd^.opcode = pc_ldc then
|
||||||
|
GenNative(m_lda_imm, immediate, long(ord4(val) * nd^.q).lsw, nil, 0)
|
||||||
|
else begin
|
||||||
|
GenTree(nd);
|
||||||
|
case val of
|
||||||
|
0: GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||||
|
|
||||||
|
1,2,4,8,16,32,64,128:
|
||||||
|
while not odd(val) do begin
|
||||||
|
GenImplied(m_asl_a);
|
||||||
|
val := val >> 1;
|
||||||
|
end; {while}
|
||||||
|
|
||||||
|
256,512,1024,2048,4096,8192,16384: begin
|
||||||
|
GenNative(m_and_imm, immediate, $00FF, nil, 0);
|
||||||
|
GenImplied(m_xba);
|
||||||
|
val := val >> 8;
|
||||||
|
while not odd(val) do begin
|
||||||
|
GenImplied(m_asl_a);
|
||||||
|
val := val >> 1;
|
||||||
|
end; {while}
|
||||||
|
end;
|
||||||
|
|
||||||
|
3,5,6,9,10,12,17,18,20,24,33,34,36,40,48,65,66,68,72,80,96: begin
|
||||||
|
if odd(val) then {prevent lda+pha -> pei optimization}
|
||||||
|
GenLab(GenLabel);
|
||||||
|
while not odd(val) do begin
|
||||||
|
GenImplied(m_asl_a);
|
||||||
|
val := val >> 1;
|
||||||
|
end; {while}
|
||||||
|
GenImplied(m_pha);
|
||||||
|
val := val - 1;
|
||||||
|
while not odd(val) do begin
|
||||||
|
GenImplied(m_asl_a);
|
||||||
|
val := val >> 1;
|
||||||
|
end; {while}
|
||||||
|
GenImplied(m_clc);
|
||||||
|
GenNative(m_adc_s, direct, 1, nil, 0);
|
||||||
|
GenImplied(m_plx);
|
||||||
|
end;
|
||||||
|
|
||||||
|
-1,-2,-4,-8,-16,-32,-64,-128: begin
|
||||||
|
GenNative(m_eor_imm, immediate, -1, nil, 0);
|
||||||
|
GenImplied(m_ina);
|
||||||
|
val := -val;
|
||||||
|
while not odd(val) do begin
|
||||||
|
GenImplied(m_asl_a);
|
||||||
|
val := val >> 1;
|
||||||
|
end; {while}
|
||||||
|
end;
|
||||||
|
|
||||||
|
-256: begin
|
||||||
|
GenNative(m_eor_imm, immediate, -1, nil, 0);
|
||||||
|
GenImplied(m_ina);
|
||||||
|
GenNative(m_and_imm, immediate, $00FF, nil, 0);
|
||||||
|
GenImplied(m_xba);
|
||||||
|
end;
|
||||||
|
|
||||||
|
otherwise: begin
|
||||||
|
if val = $8000 then begin
|
||||||
|
GenImplied(m_lsr_a);
|
||||||
|
GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||||
|
GenImplied(m_ror_a);
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
GenNative(m_ldx_imm, immediate, val, nil, 0);
|
||||||
|
if op^.opcode = pc_mpi then
|
||||||
|
GenCall(28)
|
||||||
|
else {pc_umi}
|
||||||
|
GenCall(94);
|
||||||
|
end; {else}
|
||||||
|
end;
|
||||||
|
end; {case}
|
||||||
|
end; {else}
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
if not Complex(op^.left) then
|
||||||
|
if Complex(op^.right) then begin
|
||||||
|
nd := op^.left;
|
||||||
|
op^.left := op^.right;
|
||||||
|
op^.right := nd;
|
||||||
|
end; {if}
|
||||||
|
GenTree(op^.left);
|
||||||
if Complex(op^.right) then begin
|
if Complex(op^.right) then begin
|
||||||
nd := op^.left;
|
GenImplied(m_pha);
|
||||||
op^.left := op^.right;
|
GenTree(op^.right);
|
||||||
op^.right := nd;
|
GenImplied(m_plx);
|
||||||
end; {if}
|
end {if}
|
||||||
GenTree(op^.left);
|
else
|
||||||
if Complex(op^.right) then begin
|
LoadX(op^.right);
|
||||||
GenImplied(m_pha);
|
if op^.opcode = pc_mpi then begin
|
||||||
GenTree(op^.right);
|
GenCall(28);
|
||||||
GenImplied(m_plx);
|
if rangeCheck then
|
||||||
end {if}
|
GenCall(25);
|
||||||
else
|
end {if}
|
||||||
LoadX(op^.right);
|
else {pc_umi}
|
||||||
if op^.opcode = pc_mpi then begin
|
GenCall(94);
|
||||||
GenCall(28);
|
end; {else}
|
||||||
if rangeCheck then
|
|
||||||
GenCall(25);
|
|
||||||
end {if}
|
|
||||||
else {pc_umi}
|
|
||||||
GenCall(94);
|
|
||||||
end; {GenMpi}
|
end; {GenMpi}
|
||||||
|
|
||||||
|
|
||||||
|
@ -775,7 +775,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_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_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_and_indl,m_and_indly,m_ora_indl,m_ora_indly,m_sbc_indl,m_sbc_indly,
|
||||||
m_eor_indl,m_eor_indly:
|
m_eor_indl,m_eor_indly,m_ror_a:
|
||||||
aRegister.condition := regUnknown;
|
aRegister.condition := regUnknown;
|
||||||
|
|
||||||
m_ldy_absX,m_ldy_dirX,m_ply:
|
m_ldy_absX,m_ldy_dirX,m_ply:
|
||||||
|
Loading…
Reference in New Issue
Block a user