Recognize byte swapping and generate an xba instruction for it.

Specifically, this recognizes the pattern "(exp << 8) | (exp >> 8)", where exp has an unsigned 16-bit type and does not have side effects.
This commit is contained in:
Stephen Heumann 2021-03-05 21:59:18 -06:00
parent 95f5182442
commit c0727315e0
5 changed files with 39 additions and 6 deletions

View File

@ -551,6 +551,14 @@
{ source address onto the stack. }
{ }
{ }
{ pc_rbo - reverse byte order }
{ }
{ Gen0(pc_rbo) cgWord,cgUWord }
{ }
{ The value on the top of the evaluation stack is removed, has }
{ the order of its constituent bytes reversed, and is replaced.}
{ }
{ }
{ pc_sbf - save bit field }
{ }
{ Gen2t(pc_sbf, disp, size, type) }

View File

@ -127,6 +127,7 @@ opt[pc_dvq] := 'dvq';
opt[pc_udq] := 'udq';
opt[pc_mdq] := 'mdq';
opt[pc_uqm] := 'uqm';
opt[pc_rbo] := 'rbo';
end; {InitWriteCode}

View File

@ -242,7 +242,7 @@ type
pc_gli,pc_gdl,pc_gld,pc_cpi,pc_tri,pc_lbu,pc_lbf,pc_sbf,pc_cbf,dc_cns,
dc_prm,pc_nat,pc_bno,pc_nop,pc_psh,pc_ili,pc_iil,pc_ild,pc_idl,
pc_bqr,pc_bqx,pc_baq,pc_bnq,pc_ngq,pc_adq,pc_sbq,pc_mpq,pc_umq,pc_dvq,
pc_udq,pc_mdq,pc_uqm,pc_slq,pc_sqr,pc_wsr);
pc_udq,pc_mdq,pc_uqm,pc_slq,pc_sqr,pc_wsr,pc_rbo);
{intermediate code}
{-----------------}

21
DAG.pas
View File

@ -1100,7 +1100,20 @@ case op^.opcode of {check for optimizations of this node}
end {if}
else if op^.right^.q = 0 then
opv := op^.left;
end; {else if}
end {else if}
else if ((op^.left^.opcode = pc_shl) and (op^.right^.opcode = pc_usr))
or ((op^.left^.opcode = pc_usr) and (op^.right^.opcode = pc_shl)) then
if op^.left^.right^.opcode = pc_ldc then
if op^.right^.right^.opcode = pc_ldc then
if op^.left^.right^.q = 8 then
if op^.right^.right^.q = 8 then
if CodesMatch(op^.left^.left, op^.right^.left, false) then
if not SideEffects(op^.left^.left) then begin
op^.opcode := pc_rbo;
op^.left := op^.left^.left;
op^.right := nil;
end; {if}
end; {case pc_bor}
pc_bxr: begin {pc_bxr}
@ -2733,7 +2746,7 @@ case op^.opcode of
pc_neq, pc_ior, pc_lor, pc_mod, pc_mpi, pc_sbi, pc_shl, pc_shr:
TypeOf := cgWord;
pc_udi, pc_uim, pc_umi, pc_usr:
pc_udi, pc_uim, pc_umi, pc_usr, pc_rbo:
TypeOf := cgUWord;
pc_bnl, pc_ngl, pc_adl, pc_bal, pc_blr, pc_blx, pc_dvl, pc_mdl,
@ -4544,7 +4557,7 @@ var
pc_ngl,pc_ngr,pc_not,pc_pop,pc_sbi,pc_sbl,pc_sbr,
pc_shl,pc_sll,pc_shr,pc_usr,pc_slr,pc_vsr,pc_tri,
pc_bqr,pc_bqx,pc_baq,pc_bnq,pc_ngq,pc_adq,pc_sbq,
pc_mpq,pc_umq,pc_dvq,pc_udq,pc_mdq,pc_uqm]
pc_mpq,pc_umq,pc_dvq,pc_udq,pc_mdq,pc_uqm,pc_rbo]
then begin
op^.parents := icount;
icount := icount+1;
@ -5412,7 +5425,7 @@ case code^.opcode of
pc_bnt, pc_bnl, pc_cnv, pc_dec, pc_inc, pc_ind, pc_lbf, pc_lbu,
pc_ngi, pc_ngl, pc_ngr, pc_not, pc_stk, pc_cop, pc_cpo, pc_tl1,
pc_sro, pc_str, pc_fjp, pc_tjp, pc_xjp, pc_cup, pc_pop, pc_iil,
pc_ili, pc_idl, pc_ild, pc_bnq, pc_ngq:
pc_ili, pc_idl, pc_ild, pc_bnq, pc_ngq, pc_rbo:
begin
code^.left := Pop;
Push(code);

13
Gen.pas
View File

@ -621,7 +621,7 @@ NeedsCondition := opcode in
[pc_and,pc_ior,pc_cui,pc_cup,pc_lor,pc_lnd,pc_ldl,pc_lil,pc_lld,
pc_lli,pc_gil,pc_gli,pc_gdl,pc_gld,pc_iil,pc_ili,pc_idl,pc_ild,
pc_cop,pc_cpo,pc_cpi,pc_dvi,pc_mpi,pc_adi,pc_sbi,pc_mod,pc_bno,
pc_udi,pc_uim,pc_umi,pc_cnv];
pc_udi,pc_uim,pc_umi,pc_cnv,pc_rbo];
end; {NeedsCondition}
@ -6589,6 +6589,16 @@ procedure GenTree {op: icptr};
end; {GenPsh}
procedure GenRbo (op: icptr);
{ Generate code for a pc_rbo }
begin {GenRbo}
GenTree(op^.left);
GenImplied(m_xba);
end; {GenRbo}
procedure GenRealBinOp (op: icptr);
{ Generate code for a pc_adr, pc_dvr, pc_mpr or pc_sbr }
@ -7168,6 +7178,7 @@ case op^.opcode of
pc_nop: ;
pc_pop: GenPop(op);
pc_psh: GenPsh(op);
pc_rbo: GenRbo(op);
pc_ret: GenRet(op);
pc_sbf,pc_cbf: GenSbfCbf(op);
pc_sbi: GenSbi(op);