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.
This commit is contained in:
Stephen Heumann 2022-10-12 22:03:37 -05:00
parent 12a2e14b6d
commit 19683706cc
5 changed files with 22 additions and 9 deletions

View File

@ -207,6 +207,8 @@ const
d_cns = 263;
max_opcode = 263;
asmFlag = $8000; {or'd with opcode to indicate asm code}
{Code Generation}
{---------------}

14
Gen.pas
View File

@ -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}

View File

@ -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

View File

@ -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;

View File

@ -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.