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; d_cns = 263;
max_opcode = 263; max_opcode = 263;
asmFlag = $8000; {or'd with opcode to indicate asm code}
{Code Generation} {Code Generation}
{---------------} {---------------}

14
Gen.pas
View File

@ -6725,30 +6725,34 @@ procedure GenTree {op: icptr};
mode: addressingmode; {work var for addressing mode} mode: addressingmode; {work var for addressing mode}
pval: longint; {temp pointer} pval: longint; {temp pointer}
val: longint; {constant operand} val: longint; {constant operand}
opcode: integer; {opcode}
begin {GenNat} begin {GenNat}
val := op^.opnd; val := op^.opnd;
flags := op^.q; flags := op^.q;
pval := op^.llab; pval := op^.llab;
mode := addressingMode(op^.r); mode := addressingMode(op^.r);
opcode := op^.s;
if opcode < 256 then
opcode := opcode | asmFlag;
if op^.slab <> 0 then if op^.slab <> 0 then
val := val+LabelToDisp(op^.slab); val := val+LabelToDisp(op^.slab);
if mode in [relative,longrelative] then 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 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) flags | localLab)
else if (mode = longabsolute) and (op^.llab = 0) else if (mode = longabsolute) and (op^.llab = 0)
and (op^.lab = nil) then and (op^.lab = nil) then
GenNative(op^.s, mode, 0, pointer(val), flags | constantOpnd) GenNative(opcode, mode, 0, pointer(val), flags | constantOpnd)
else begin else begin
if (mode = absolute) and (op^.llab = 0) then if (mode = absolute) and (op^.llab = 0) then
flags := flags | constantOpnd; flags := flags | constantOpnd;
if op^.llab <> 0 then if op^.llab <> 0 then
GenNative(op^.s, mode, long(val).lsw, pointer(pval), GenNative(opcode, mode, long(val).lsw, pointer(pval),
flags | localLab) flags | localLab)
else else
GenNative(op^.s, mode, long(val).lsw, op^.lab, flags); GenNative(opcode, mode, long(val).lsw, op^.lab, flags);
end; {else} end; {else}
end; {GenNat} end; {GenNat}

View File

@ -87,7 +87,8 @@ lb1 lda nPeep+peep_opcode,X if npeep[i].opcode = d_lab then
inc fn inc fn
bra lab1 goto 1; bra lab1 goto 1;
lb2 anop end; 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 tay
lda size,Y lda size,Y
and #$00FF and #$00FF
@ -123,7 +124,8 @@ lb4 lda i while i < nnextspot do begin
inc fn inc fn
bra lab1 goto 1; bra lab1 goto 1;
lb5 anop end; 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 tay
lda size,Y lda size,Y
and #$00FF and #$00FF

View File

@ -494,6 +494,7 @@ case mode of
if not longA then if not longA then
if operand = 255 then if operand = 255 then
goto 1; goto 1;
opcode := opcode & ~asmFlag;
CnOut(opcode); CnOut(opcode);
if opcode = m_pea then if opcode = m_pea then
GenImmediate2 GenImmediate2
@ -525,7 +526,7 @@ case mode of
longabs: begin longabs: begin
CnOut(opcode); CnOut(opcode);
isJSL := opcode = m_jsl; {allow for dynamic segs} isJSL := (opcode & ~asmFlag) = m_jsl; {allow for dynamic segs}
if name = nil then if name = nil then
if odd(flags div toolcall) then begin if odd(flags div toolcall) then begin
CnOut2(0); CnOut2(0);
@ -721,7 +722,7 @@ case mode of
end; end;
genAddress: begin genAddress: begin
if opcode < 256 then if opcode < 256 then {includes opcodes with asmFlag}
CnOut(opcode); CnOut(opcode);
if (flags & stringReference) <> 0 then begin if (flags & stringReference) <> 0 then begin
Purge; 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. 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 ----------------------------------- -- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file. 1. In some situations, fread() reread the first 1K or so of the file.