mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-12-21 16:29:31 +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_plp = 40;
|
||||
m_rep = 194;
|
||||
m_ror_a = $6A;
|
||||
m_rtl = 107;
|
||||
m_rts = 96;
|
||||
m_sbc_abs = 237;
|
||||
|
128
Gen.pas
128
Gen.pas
@ -6441,29 +6441,117 @@ procedure GenTree {op: icptr};
|
||||
|
||||
var
|
||||
nd: icptr;
|
||||
val: integer;
|
||||
|
||||
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
|
||||
nd := op^.left;
|
||||
op^.left := op^.right;
|
||||
op^.right := nd;
|
||||
end; {if}
|
||||
GenTree(op^.left);
|
||||
if Complex(op^.right) then begin
|
||||
GenImplied(m_pha);
|
||||
GenTree(op^.right);
|
||||
GenImplied(m_plx);
|
||||
end {if}
|
||||
else
|
||||
LoadX(op^.right);
|
||||
if op^.opcode = pc_mpi then begin
|
||||
GenCall(28);
|
||||
if rangeCheck then
|
||||
GenCall(25);
|
||||
end {if}
|
||||
else {pc_umi}
|
||||
GenCall(94);
|
||||
GenImplied(m_pha);
|
||||
GenTree(op^.right);
|
||||
GenImplied(m_plx);
|
||||
end {if}
|
||||
else
|
||||
LoadX(op^.right);
|
||||
if op^.opcode = pc_mpi then begin
|
||||
GenCall(28);
|
||||
if rangeCheck then
|
||||
GenCall(25);
|
||||
end {if}
|
||||
else {pc_umi}
|
||||
GenCall(94);
|
||||
end; {else}
|
||||
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_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_eor_indl,m_eor_indly,m_ror_a:
|
||||
aRegister.condition := regUnknown;
|
||||
|
||||
m_ldy_absX,m_ldy_dirX,m_ply:
|
||||
|
Loading…
Reference in New Issue
Block a user