From 19683706ccf2f59dc984de1e012fbee66cf06da2 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Wed, 12 Oct 2022 22:03:37 -0500 Subject: [PATCH] Do not optimize code from asm statements. Previously, the assembly-level optimizations applied to code in asm statements. In many cases, this was fine (and could even do useful optimizations), but occasionally the optimizations could be invalid. This was especially the case if the assembly involved tricky things like self-modifying code. To avoid these problems, this patch makes the assembly optimizers ignore code from asm statements, so it is always emitted as-is, without any changes. This fixes #34. --- CGI.pas | 2 ++ Gen.pas | 14 +++++++++----- Native.asm | 6 ++++-- Native.pas | 5 +++-- cc.notes | 4 ++++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/CGI.pas b/CGI.pas index 7ed8546..674227c 100644 --- a/CGI.pas +++ b/CGI.pas @@ -207,6 +207,8 @@ const d_cns = 263; max_opcode = 263; + + asmFlag = $8000; {or'd with opcode to indicate asm code} {Code Generation} {---------------} diff --git a/Gen.pas b/Gen.pas index 50710bd..ccabb39 100644 --- a/Gen.pas +++ b/Gen.pas @@ -6725,30 +6725,34 @@ procedure GenTree {op: icptr}; mode: addressingmode; {work var for addressing mode} pval: longint; {temp pointer} val: longint; {constant operand} + opcode: integer; {opcode} begin {GenNat} val := op^.opnd; flags := op^.q; pval := op^.llab; mode := addressingMode(op^.r); + opcode := op^.s; + if opcode < 256 then + opcode := opcode | asmFlag; if op^.slab <> 0 then val := val+LabelToDisp(op^.slab); if mode in [relative,longrelative] then - GenNative(op^.s, mode, op^.llab, op^.lab, op^.q) + GenNative(opcode, mode, op^.llab, op^.lab, op^.q) else if (mode = longabsolute) and (op^.llab <> 0) then - GenNative(op^.s, mode, long(val).lsw, pointer(pval), + GenNative(opcode, mode, long(val).lsw, pointer(pval), flags | localLab) else if (mode = longabsolute) and (op^.llab = 0) and (op^.lab = nil) then - GenNative(op^.s, mode, 0, pointer(val), flags | constantOpnd) + GenNative(opcode, mode, 0, pointer(val), flags | constantOpnd) else begin if (mode = absolute) and (op^.llab = 0) then flags := flags | constantOpnd; if op^.llab <> 0 then - GenNative(op^.s, mode, long(val).lsw, pointer(pval), + GenNative(opcode, mode, long(val).lsw, pointer(pval), flags | localLab) else - GenNative(op^.s, mode, long(val).lsw, op^.lab, flags); + GenNative(opcode, mode, long(val).lsw, op^.lab, flags); end; {else} end; {GenNat} diff --git a/Native.asm b/Native.asm index afe45cd..32f99cf 100644 --- a/Native.asm +++ b/Native.asm @@ -87,7 +87,8 @@ lb1 lda nPeep+peep_opcode,X if npeep[i].opcode = d_lab then inc fn bra lab1 goto 1; lb2 anop end; - lda nPeep+peep_opcode,X len := len+size[npeep[i].mode]; + lda nPeep+peep_opcode,X len := len+size[npeep[i].opcode & ~asmFlag]; + and #$7FFF tay lda size,Y and #$00FF @@ -123,7 +124,8 @@ lb4 lda i while i < nnextspot do begin inc fn bra lab1 goto 1; lb5 anop end; - lda nPeep+peep_opcode,X len := len+size[npeep[i].mode]; + lda nPeep+peep_opcode,X len := len+size[npeep[i].opcode & ~asmFlag]; + and #$7FFF tay lda size,Y and #$00FF diff --git a/Native.pas b/Native.pas index 68e5de1..82c0d6a 100644 --- a/Native.pas +++ b/Native.pas @@ -494,6 +494,7 @@ case mode of if not longA then if operand = 255 then goto 1; + opcode := opcode & ~asmFlag; CnOut(opcode); if opcode = m_pea then GenImmediate2 @@ -525,7 +526,7 @@ case mode of longabs: begin CnOut(opcode); - isJSL := opcode = m_jsl; {allow for dynamic segs} + isJSL := (opcode & ~asmFlag) = m_jsl; {allow for dynamic segs} if name = nil then if odd(flags div toolcall) then begin CnOut2(0); @@ -721,7 +722,7 @@ case mode of end; genAddress: begin - if opcode < 256 then + if opcode < 256 then {includes opcodes with asmFlag} CnOut(opcode); if (flags & stringReference) <> 0 then begin Purge; diff --git a/cc.notes b/cc.notes index eded887..a079122 100644 --- a/cc.notes +++ b/cc.notes @@ -1903,6 +1903,10 @@ int foo(int[42]); 207. If a struct or union type with a tag T has been declared within an outer scope, a declaration "struct T;" or "union T;" within an inner scope should declare a separate type, distinct from the one in the outer scope. +208. The native code peephole optimizer and register optimizer could alter the assembly code in asm statements, occasionally causing it not be behave as intended. Now, code from asm statements will not be altered by the optimizers. + +(Dave Tribby) + -- Bugs from C 2.1.0 that have been fixed ----------------------------------- 1. In some situations, fread() reread the first 1K or so of the file.