From c0727315e06d459832f0485e085ac22b2037e277 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 5 Mar 2021 21:59:18 -0600 Subject: [PATCH] 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. --- CGI.Comments | 8 ++++++++ CGI.Debug | 1 + CGI.pas | 2 +- DAG.pas | 21 +++++++++++++++++---- Gen.pas | 13 ++++++++++++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CGI.Comments b/CGI.Comments index 7142d91..b2dd33f 100644 --- a/CGI.Comments +++ b/CGI.Comments @@ -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) } diff --git a/CGI.Debug b/CGI.Debug index fc52fe6..d8a31b7 100644 --- a/CGI.Debug +++ b/CGI.Debug @@ -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} diff --git a/CGI.pas b/CGI.pas index 4ca07ef..912d4f7 100644 --- a/CGI.pas +++ b/CGI.pas @@ -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} {-----------------} diff --git a/DAG.pas b/DAG.pas index 7613c4a..bfe0458 100644 --- a/DAG.pas +++ b/DAG.pas @@ -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); diff --git a/Gen.pas b/Gen.pas index c027e31..32ac1c7 100644 --- a/Gen.pas +++ b/Gen.pas @@ -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);