From a5eafe56af306a7be50745a5555c6b3e4b33a15f Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sat, 18 Mar 2023 20:05:56 -0500 Subject: [PATCH] Generate more efficient code for 16-bit signed comparisons. The new code is smaller and (in the common case where the subtraction does not overflow) faster. It takes advantage of the fact that in overflow cases the carry flag always gets set to the opposite of the sign bit of the result. --- CGI.pas | 1 + Gen.pas | 24 ++++++++++++------------ Native.pas | 10 +++++----- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/CGI.pas b/CGI.pas index df52da2..00470b0 100644 --- a/CGI.pas +++ b/CGI.pas @@ -71,6 +71,7 @@ const m_bpl = $10; m_bra = $80; m_brl = $82; + m_bvc = $50; m_bvs = $70; m_clc = $18; m_cmp_abs = $CD; diff --git a/Gen.pas b/Gen.pas index 9ad9e16..c92566b 100644 --- a/Gen.pas +++ b/Gen.pas @@ -1212,10 +1212,10 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and GenNative(m_ldx_imm, immediate, 1, nil, 0); GenImplied(m_sec); GenNative(m_sbc_imm, immediate, num, nil, 0); - GenNative(m_bvs, relative, lab1, nil, 0); - GenNative(m_eor_imm, immediate, $8000, nil, 0); + GenNative(m_bvc, relative, lab1, nil, 0); + GenImplied(m_ror_a); GenLab(lab1); - GenNative(m_bmi, relative, lab2, nil, 0); + GenNative(m_bpl, relative, lab2, nil, 0); GenImplied(m_dex); GenLab(lab2); GenImplied(m_txa); @@ -1279,10 +1279,10 @@ else end; {if} if op^.optype in [cgByte,cgWord] then begin lab1 := GenLabel; - GenNative(m_bvs, relative, lab1, nil, 0); - GenNative(m_eor_imm, immediate, $8000, nil, 0); + GenNative(m_bvc, relative, lab1, nil, 0); + GenImplied(m_ror_a); GenLab(lab1); - GenNative(m_bmi, relative, lab2, nil, 0); + GenNative(m_bpl, relative, lab2, nil, 0); end {if} else GenNative(m_bcs, relative, lab2, nil, 0); @@ -1299,10 +1299,10 @@ else end; {if} if op^.optype in [cgByte,cgWord] then begin lab1 := GenLabel; - GenNative(m_bvs, relative, lab1, nil, 0); - GenNative(m_eor_imm, immediate, $8000, nil, 0); + GenNative(m_bvc, relative, lab1, nil, 0); + GenImplied(m_ror_a); GenLab(lab1); - GenNative(m_bpl, relative, lab2, nil, 0); + GenNative(m_bmi, relative, lab2, nil, 0); end {if} else GenNative(m_bcc, relative, lab2, nil, 0); @@ -1319,10 +1319,10 @@ else end; {if} if op^.optype in [cgByte,cgWord] then begin lab1 := GenLabel; - GenNative(m_bvs, relative, lab1, nil, 0); - GenNative(m_eor_imm, immediate, $8000, nil, 0); + GenNative(m_bvc, relative, lab1, nil, 0); + GenImplied(m_ror_a); GenLab(lab1); - GenNative(m_bmi, relative, lab2, nil, 0); + GenNative(m_bpl, relative, lab2, nil, 0); end {if} else GenNative(m_bcs, relative, lab2, nil, 0); diff --git a/Native.pas b/Native.pas index 54a4cdc..51ed072 100644 --- a/Native.pas +++ b/Native.pas @@ -849,7 +849,7 @@ case p_opcode of m_plx: xRegister.condition := regUnknown; - m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvs, + m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvc,m_bvs, m_pha,m_phb,m_phd,m_php,m_phx,m_phy,m_pei_dir,m_tcs: goto 3; @@ -1558,7 +1558,7 @@ var for i := ns to nnextSpot-1 do begin opcode := npeep[i].opcode; if opcode in - [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bra,m_brl,m_bvs,m_jml, + [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bra,m_brl,m_bvc,m_bvs,m_jml, m_jmp_indX,m_jsl,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_pla,m_rtl,m_rts,m_tdc,m_txa,m_tya,m_tsc,d_end,d_bmov, @@ -1881,14 +1881,14 @@ var if operand = npeep[ns+1].operand then if name = npeep[ns+1].name then if not (npeep[ns+2].opcode in - [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvs]) then + [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvc,m_bvs]) then Remove(ns+1); m_sta_dir: if npeep[ns+1].opcode = m_lda_dir then if operand = npeep[ns+1].operand then if not (npeep[ns+2].opcode in - [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvs]) then + [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvc,m_bvs]) then Remove(ns+1); m_plb: @@ -1913,7 +1913,7 @@ var end {if} else if npeep[ns+1].opcode = m_txa then begin if not (npeep[ns+2].opcode in - [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvs]) then begin + [m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_bvc,m_bvs]) then begin Remove(ns); Remove(ns); end; {if}