From 74cec68dacff0810ad9c79210aece48f4fbfa473 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 2 Apr 2023 19:39:03 -0500 Subject: [PATCH] Generate better code for some floating-point and long long constants. We now recognize cases where the same value needs to be pushed for several consecutive words, so it is more efficient to load it into a register and push that rather than just using PEA instructions. --- Gen.pas | 70 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/Gen.pas b/Gen.pas index fa9d938..6229af6 100644 --- a/Gen.pas +++ b/Gen.pas @@ -6162,17 +6162,50 @@ procedure GenTree {op: icptr}; { Generate code for a pc_ldc } type - kind = (vint, vbyte); {kinds of equivalenced data} - - var - i: integer; {loop/index variable} - rec: realrec; {conversion record} - switch: packed record {used for type conversion} - case rkind: kind of - vint: (i: integer); - vbyte: (b1, b2, b3, b4, b5, b6, b7, b8: byte); + kind = (vreal, vlonglong, vwords); {kinds of equivalenced data} + switchRec = packed record + case kind of + vreal: (theReal: extended); + vlonglong: (theLonglong: longlong); + vwords: (words: packed array[1..5] of integer); end; - + + var + switch: switchRec; {used for type conversion} + + + procedure PushWords (switch: switchRec; count: integer); + + { Generate code to push words from the switch record } + { } + { parameters } + { switch - the switch record } + { count - number of words to push } + + var + val: integer; {word value to push} + + begin {PushWords} + repeat + val := switch.words[count]; + if (count >= 3) + and (switch.words[count-1] = val) + and (switch.words[count-2] = val) + then begin + GenNative(m_lda_imm, immediate, val, nil, 0); + repeat + GenImplied(m_pha); + count := count - 1; + until (count = 0) or (switch.words[count] <> val); + end {if} + else begin + GenNative(m_pea, immediate, val, nil, 0); + count := count - 1; + end; {else} + until count = 0; + end; {PushWords} + + begin {GenLdc} case op^.optype of cgByte: begin @@ -6185,15 +6218,8 @@ procedure GenTree {op: icptr}; GenNative(m_lda_imm, immediate, op^.q, nil, 0); cgReal, cgDouble, cgComp, cgExtended: begin - rec.itsReal := op^.rval; - CnvSX(rec); - i := 9; - while i >= 0 do begin - switch.b1 := rec.inSANE[i]; - switch.b2 := rec.inSANE[i+1]; - GenNative(m_pea, immediate, switch.i, nil, 0); - i := i-2; - end; {while} + switch.theReal := op^.rval; + PushWords(switch, 5); end; cgLong, cgULong: @@ -6214,10 +6240,8 @@ procedure GenTree {op: icptr}; cgQuad,cgUQuad: begin if gQuad.preference = onStack then begin - GenNative(m_pea, immediate, long(op^.qval.hi).msw, nil, 0); - GenNative(m_pea, immediate, long(op^.qval.hi).lsw, nil, 0); - GenNative(m_pea, immediate, long(op^.qval.lo).msw, nil, 0); - GenNative(m_pea, immediate, long(op^.qval.lo).lsw, nil, 0); + switch.theLonglong := op^.qval; + PushWords(switch, 4); end {if} else begin GenNative(m_lda_imm, immediate, long(op^.qval.hi).msw, nil, 0);