Compare commits
12 Commits
75a928e273
...
83537fd3c7
Author | SHA1 | Date |
---|---|---|
Stephen Heumann | 83537fd3c7 | |
Stephen Heumann | 81934109fc | |
Stephen Heumann | 72234a4f2b | |
Stephen Heumann | 36f766a662 | |
Stephen Heumann | 4c402fc883 | |
Stephen Heumann | ca0147507b | |
Stephen Heumann | 24c6e72a83 | |
Stephen Heumann | 0f18fa63b5 | |
Stephen Heumann | 8f07ca5d6c | |
Stephen Heumann | 60b472a99e | |
Stephen Heumann | 995885540b | |
Stephen Heumann | 34c5be5cab |
14
C.Read.Me
14
C.Read.Me
|
@ -1,18 +1,20 @@
|
|||
Welcome to ORCA/C 2.2.0! This is a release containing updates from
|
||||
Welcome to ORCA/C 2.2.1! This is a release containing updates from
|
||||
community members (Stephen Heumann and Kelvin Sherlock).
|
||||
|
||||
ORCA/C 2.2.0 adds support for almost all of the new language and library
|
||||
ORCA/C 2.2 adds support for almost all of the new language and library
|
||||
features required by the C17 standard. It also has several other new
|
||||
features, such as additional lint checks to help identify bugs and
|
||||
portability problems. In addition to these new features, ORCA/C 2.2.0
|
||||
portability problems. In addition to these new features, ORCA/C 2.2
|
||||
includes hundreds of bug fixes in the compiler and libraries.
|
||||
|
||||
The ORCA/C manual has been fully updated to cover ORCA/C 2.2.0, so new
|
||||
ORCA/C 2.2.1 includes additional bug fixes to ORCA/C 2.2.0.
|
||||
|
||||
The ORCA/C manual has been fully updated to cover ORCA/C 2.2, so new
|
||||
users should simply refer to that. Users familiar with older versions
|
||||
of ORCA/C can refer to the cc.notes file in the Release.Notes directory
|
||||
for a description of the changes between ORCA/C 2.0 and ORCA/C 2.2.0.
|
||||
for a description of the changes between ORCA/C 2.0 and ORCA/C 2.2.1.
|
||||
|
||||
ORCA/C 2.2.0 requires a real or emulated Apple IIGS with at least the
|
||||
ORCA/C 2.2.1 requires a real or emulated Apple IIGS with at least the
|
||||
following specifications:
|
||||
|
||||
* 2 MB of RAM (3 MB or more recommended)
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
This is an update package that can be used to update ORCA/C 2.1.0 to
|
||||
ORCA/C 2.2.0. You must have an existing copy of ORCA/C 2.1.0 in order
|
||||
to use this update. If you do not already have a copy, you can get it
|
||||
as part of Opus ][: The Software, a collection of Byte Works software
|
||||
which is sold by Juiced.GS:
|
||||
This is an update package that can be used to update ORCA/C 2.1.0 or
|
||||
2.2.0 to ORCA/C 2.2.1. You must have an existing copy of ORCA/C 2.1.0
|
||||
or 2.2.0 in order to use this update. If you do not already have a
|
||||
copy, you can get it as part of Opus ][: The Software, a collection of
|
||||
Byte Works software which is sold by Juiced.GS:
|
||||
https://juiced.gs/store/opus-ii-software/
|
||||
|
||||
This update must be applied to an existing ORCA installation containing
|
||||
ORCA/C 2.1.0 or an ORCA/C 2.2.0 beta (including the one provided on
|
||||
Opus ][: The Software). To apply the update, you just need to copy
|
||||
the files from this distribution into the corresponding locations in
|
||||
your ORCA installation, replacing any older versions.
|
||||
ORCA/C 2.1.0 or ORCA/C 2.2.0 (including the one provided on Opus ][:
|
||||
The Software). To apply the update, you just need to copy the files
|
||||
from this distribution into the corresponding locations in your ORCA
|
||||
installation, replacing any older versions.
|
||||
|
||||
If you received this update as a SHK file, you can simply extract the
|
||||
the files from it directly on top of your ORCA installation.
|
||||
files from it directly on top of your ORCA installation.
|
||||
|
||||
If you received this update as a disk image, you can apply the update
|
||||
by copying the files into place using the Finder, or by running the
|
||||
following command within the root directory of your ORCA installation
|
||||
using the text-based ORCA shell:
|
||||
|
||||
COPY -C :ORCAC.220:=
|
||||
COPY -C :ORCAC.221:=
|
||||
|
||||
In addition to the ORCA shell environment, this update can also be
|
||||
used under other environments that are compatible with ORCA/C, such as
|
||||
|
|
|
@ -139,7 +139,7 @@ opt[pc_ckn] := 'ckn';
|
|||
end; {InitWriteCode}
|
||||
|
||||
|
||||
procedure PrintDAG (tag: stringPtr; code: icptr);
|
||||
procedure PrintDAG {tag: stringPtr; code: icptr};
|
||||
|
||||
{ print a DAG }
|
||||
{ }
|
||||
|
|
108
CGI.pas
108
CGI.pas
|
@ -48,6 +48,7 @@ const
|
|||
forFlags = 256; {instruction used for effect on flags only}
|
||||
subtract1 = 512; {subtract 1 from address operand}
|
||||
shiftLeft8 = 1024; {shift operand left 8 bits}
|
||||
labelUsedOnce = 2048; {only one branch targets this label}
|
||||
|
||||
m_adc_abs = $6D; {op code #s for 65816 instructions}
|
||||
m_adc_dir = $65;
|
||||
|
@ -292,6 +293,8 @@ type
|
|||
ccPointer : (pval: longint; pstr: longStringPtr);
|
||||
end;
|
||||
|
||||
codeRef = icptr; {reference to a code location}
|
||||
|
||||
{basic blocks}
|
||||
{------------}
|
||||
iclist = ^iclistRecord; {used to form lists of records}
|
||||
|
@ -657,6 +660,21 @@ procedure GenTool (fop: pcodes; fp1, fp2: integer; dispatcher: longint);
|
|||
{ dispatcher - tool entry point }
|
||||
|
||||
|
||||
function GetCodeLocation: codeRef;
|
||||
|
||||
{ Get a reference to the current location in the generated }
|
||||
{ code, suitable to be passed to RemoveCode. }
|
||||
|
||||
|
||||
procedure InsertCode (theCode: codeRef);
|
||||
|
||||
{ Insert a section of already-generated code that was }
|
||||
{ previously removed with RemoveCode. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ theCode - code removed (returned from RemoveCode) }
|
||||
|
||||
|
||||
{procedure PrintBlocks (tag: stringPtr; bp: blockPtr); {debug}
|
||||
|
||||
{ print a series of basic blocks }
|
||||
|
@ -666,6 +684,28 @@ procedure GenTool (fop: pcodes; fp1, fp2: integer; dispatcher: longint);
|
|||
{ bp - first block to print }
|
||||
|
||||
|
||||
{procedure PrintDAG (tag: stringPtr; code: icptr); {debug}
|
||||
|
||||
{ print a DAG }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ tag - label for lines }
|
||||
{ code - first node in DAG }
|
||||
|
||||
|
||||
function RemoveCode (start: codeRef): codeRef;
|
||||
|
||||
{ Remove a section of already-generated code, from immediately }
|
||||
{ after start up to the latest code generated. Returns the }
|
||||
{ code removed, so it may be re-inserted later. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ start - location to start removing from }
|
||||
{ }
|
||||
{ Note: start must be a top-level pcode (not a subexpression). }
|
||||
{ Note: The region removed must not include a dc_enp. }
|
||||
|
||||
|
||||
function TypeSize (tp: baseTypeEnum): integer;
|
||||
|
||||
{ Find the size, in bytes, of a variable }
|
||||
|
@ -1430,6 +1470,74 @@ if codeGeneration then begin
|
|||
end; {GenLdcReal}
|
||||
|
||||
|
||||
function GetCodeLocation{: codeRef};
|
||||
|
||||
{ Get a reference to the current location in the generated }
|
||||
{ code, suitable to be passed to RemoveCode. }
|
||||
|
||||
begin {GetCodeLocation}
|
||||
GetCodeLocation := DAGhead;
|
||||
end {GetCodeLocation};
|
||||
|
||||
|
||||
procedure InsertCode {theCode: codeRef};
|
||||
|
||||
{ Insert a section of already-generated code that was }
|
||||
{ previously removed with RemoveCode. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ theCode - code removed (returned from RemoveCode) }
|
||||
|
||||
var
|
||||
lcode: icptr;
|
||||
|
||||
begin {InsertCode}
|
||||
if theCode <> nil then
|
||||
if codeGeneration then begin
|
||||
lcode := theCode;
|
||||
{ PrintDAG(@'Inserting: ', lcode); {debug}
|
||||
while lcode^.next <> nil do
|
||||
lcode := lcode^.next;
|
||||
lcode^.next := DAGhead;
|
||||
DAGhead := theCode;
|
||||
end; {if}
|
||||
end; {InsertCode}
|
||||
|
||||
|
||||
function RemoveCode {start: codeRef): codeRef};
|
||||
|
||||
{ Remove a section of already-generated code, from immediately }
|
||||
{ after start up to the latest code generated. Returns the }
|
||||
{ code removed, so it may be re-inserted later. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ start - location to start removing from }
|
||||
{ }
|
||||
{ Note: start must be a top-level pcode (not a subexpression). }
|
||||
{ Note: The region removed must not include a dc_enp. }
|
||||
|
||||
var
|
||||
lcode: icptr;
|
||||
|
||||
begin {RemoveCode}
|
||||
if start = DAGhead then
|
||||
RemoveCode := nil
|
||||
else begin
|
||||
RemoveCode := DAGhead;
|
||||
if codeGeneration then begin
|
||||
lcode := DAGhead;
|
||||
while (lcode^.next <> start) and (lcode^.next <> nil) do
|
||||
lcode := lcode^.next;
|
||||
if lcode^.next = nil then
|
||||
Error(cge1);
|
||||
lcode^.next := nil;
|
||||
{ PrintDAG(@'Removing: ', DAGhead); {debug}
|
||||
DAGhead := start;
|
||||
end; {if}
|
||||
end; {else}
|
||||
end; {RemoveCode}
|
||||
|
||||
|
||||
function TypeSize {tp: baseTypeEnum): integer};
|
||||
|
||||
{ Find the size, in bytes, of a variable }
|
||||
|
|
419
Gen.pas
419
Gen.pas
|
@ -618,7 +618,7 @@ function NeedsCondition (opcode: pcodes): boolean;
|
|||
|
||||
begin {NeedsCondition}
|
||||
NeedsCondition := opcode in
|
||||
[pc_and,pc_ior,pc_cui,pc_cup,pc_lor,pc_lnd,pc_ldl,pc_lil,pc_lld,
|
||||
[pc_and,pc_ior,pc_cui,pc_cup,pc_ldl,pc_lil,pc_lld,
|
||||
pc_lli,pc_gil,pc_gli,pc_gdl,pc_gld,pc_iil,pc_ili,pc_idl,pc_ild,
|
||||
pc_cop,pc_cpo,pc_cpi,pc_dvi,pc_mpi,pc_adi,pc_sbi,pc_mod,pc_bno,
|
||||
pc_udi,pc_uim,pc_umi,pc_cnv,pc_rbo,pc_shl,pc_shr,pc_usr,pc_lbf,
|
||||
|
@ -1068,8 +1068,22 @@ var
|
|||
end; {ReverseConditional}
|
||||
|
||||
|
||||
function SimpleLongOp(op: icptr): boolean;
|
||||
|
||||
{ Is op an operation on cg(U)Long that can be done using the }
|
||||
{ addressing modes of CPX? }
|
||||
|
||||
begin {SimpleLongOp}
|
||||
SimpleLongOp :=
|
||||
(op^.opcode = pc_ldc)
|
||||
or (op^.opcode = pc_lao)
|
||||
or ((op^.opcode = pc_lod) and (LabelToDisp(op^.r) + op^.q <= 253))
|
||||
or ((op^.opcode = pc_ldo) and smallMemoryModel);
|
||||
end; {SimpleLongOp}
|
||||
|
||||
|
||||
begin {GenCmp}
|
||||
{To reduct the number of possibilities that must be handled, pc_les }
|
||||
{To reduce the number of possibilities that must be handled, pc_les }
|
||||
{and pc_leq compares are reduced to their equivalent pc_grt and }
|
||||
{pc_geq instructions. }
|
||||
if op^.opcode = pc_les then begin
|
||||
|
@ -1113,15 +1127,16 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
if NeedsCondition(op^.left^.opcode) then
|
||||
GenImpliedForFlags(m_tax);
|
||||
if (num >= 0) and (num < 3) then begin
|
||||
if num <> 0 then begin
|
||||
if num = 0 then
|
||||
GenNative(m_bpl, relative, lab1, nil, 0)
|
||||
else begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
end; {if}
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
if num <> 0 then
|
||||
GenLab(lab2);
|
||||
if num = 2 then
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenLabUsedOnce(lab2);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if (num >= 0) and (num < 3)}
|
||||
|
@ -1134,7 +1149,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if num > 0 then begin
|
||||
GenLab(lab1);
|
||||
GenLabUsedOnce(lab1);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
|
@ -1147,8 +1162,17 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
end {if}
|
||||
else {if optype in [cgUByte,cgUWord] then} begin
|
||||
if num <> 0 then begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
||||
if num in [1,2] then begin
|
||||
if num = 1 then
|
||||
GenImpliedForFlags(m_tax)
|
||||
else
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
|
@ -1163,9 +1187,9 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
if (num >= 0) and (num < 3) then begin
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
if num > 0 then begin
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
if num = 2 then
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
|
@ -1184,7 +1208,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
GenLab(lab1);
|
||||
end {if}
|
||||
else begin
|
||||
GenLab(lab1);
|
||||
GenLabUsedOnce(lab1);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end; {else}
|
||||
|
@ -1192,8 +1216,17 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
end {if}
|
||||
else {if optype in [cgUByte,cgUWord] then} begin
|
||||
if num <> 0 then begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
if num in [1,2] then begin
|
||||
if num = 1 then
|
||||
GenImpliedForFlags(m_tax)
|
||||
else
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
end; {else}
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
if num <> 0 then
|
||||
|
@ -1282,7 +1315,7 @@ else
|
|||
else
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenLabUsedOnce(lab3);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
|
@ -1330,50 +1363,134 @@ else
|
|||
end; {case optype of cgByte,cgUByte,cgWord,cgUWord}
|
||||
|
||||
cgULong: begin
|
||||
gLong.preference := onStack;
|
||||
GenTree(op^.right);
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_ply);
|
||||
GenImplied(m_pla);
|
||||
lab1 := GenLabel;
|
||||
lab2 := GenLabel;
|
||||
simple := false;
|
||||
if SimpleLongOp(op^.right) then
|
||||
simple := true
|
||||
else if rOpcode in [pc_fjp,pc_tjp] then
|
||||
if SimpleLongOp(op^.left) then begin
|
||||
ReverseConditional;
|
||||
simple := true;
|
||||
end; {if}
|
||||
if simple then begin
|
||||
if op^.opcode = pc_grt then begin
|
||||
if SimpleLongOp(op^.left) then
|
||||
ReverseConditional;
|
||||
if op^.opcode = pc_grt then
|
||||
if op^.right^.opcode = pc_ldc then
|
||||
if op^.right^.lval <> $ffffffff then begin
|
||||
op^.right^.lval := op^.right^.lval + 1;
|
||||
op^.opcode := pc_geq;
|
||||
end; {if}
|
||||
end; {if}
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_plx);
|
||||
end; {if}
|
||||
if op^.opcode = pc_grt then
|
||||
if not (rOpcode in [pc_fjp,pc_tjp]) then
|
||||
GenNative(m_ldy_imm, immediate, 0, nil, 0);
|
||||
with op^.right^ do
|
||||
case opcode of
|
||||
pc_ldc:
|
||||
GenNative(m_cpx_imm, immediate, long(lval).msw, nil, 0);
|
||||
pc_lao:
|
||||
GenNative(m_cpx_imm, immediate, q, lab, shift16);
|
||||
pc_lod:
|
||||
GenNative(m_cpx_dir, direct, LabelToDisp(r)+q+2, nil, 0);
|
||||
pc_ldo:
|
||||
GenNative(m_cpx_abs, absolute, q+2, lab, 0);
|
||||
end; {case}
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
with op^.right^ do
|
||||
case opcode of
|
||||
pc_ldc:
|
||||
GenNative(m_cmp_imm, immediate, long(lval).lsw, nil, 0);
|
||||
pc_lao:
|
||||
GenNative(m_cmp_imm, immediate, q, lab, 0);
|
||||
pc_lod:
|
||||
GenNative(m_cmp_dir, direct, LabelToDisp(r)+q, nil, 0);
|
||||
pc_ldo:
|
||||
GenNative(m_cmp_abs, absolute, q, lab, 0);
|
||||
end; {case}
|
||||
GenLab(lab1);
|
||||
if rOpcode = pc_fjp then begin
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLabUsedOnce(lab3);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
if op^.opcode = pc_grt then
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenNative(m_bcc, relative, lab2, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {else if}
|
||||
else if op^.opcode = pc_geq then begin
|
||||
GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||
GenImplied(m_rol_a);
|
||||
end {else if}
|
||||
else {if op^.opcode = pc_grt then} begin
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenNative(m_bcc, relative, lab2, nil, 0);
|
||||
GenImplied(m_iny);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_tya);
|
||||
end; {else}
|
||||
end {if}
|
||||
else begin
|
||||
GenImplied(m_tay);
|
||||
gLong.preference := onStack;
|
||||
GenTree(op^.right);
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_ply);
|
||||
GenImplied(m_pla);
|
||||
end {if}
|
||||
else begin
|
||||
GenImplied(m_tay);
|
||||
GenImplied(m_txa);
|
||||
end; {else}
|
||||
GenNative(m_ldx_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_cmp_s, direct, 3, nil, 0);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_tya);
|
||||
GenNative(m_cmp_s, direct, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_txa);
|
||||
if rOpcode = pc_fjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_bne, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end {if}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_beq, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end; {else if}
|
||||
end; {else}
|
||||
lab1 := GenLabel;
|
||||
GenNative(m_ldx_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_cmp_s, direct, 3, nil, 0);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_tya);
|
||||
GenNative(m_cmp_s, direct, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
lab2 := GenLabel;
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_txa);
|
||||
if rOpcode = pc_fjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_bne, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end {if}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_beq, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end; {else if}
|
||||
end;
|
||||
|
||||
cgReal,cgDouble,cgComp,cgExtended: begin
|
||||
|
@ -2135,10 +2252,14 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
num := op^.right^.q;
|
||||
lab1 := GenLabel;
|
||||
if opcode in [pc_fjp,pc_tjp] then begin
|
||||
if num <> 0 then
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0)
|
||||
else if NeedsCondition(leftOp) then
|
||||
GenImpliedForFlags(m_tay);
|
||||
if num = 0 then begin
|
||||
if NeedsCondition(leftOp) then
|
||||
GenImpliedForFlags(m_tay);
|
||||
end {if}
|
||||
else if num = 1 then
|
||||
GenImplied(m_dea)
|
||||
else
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
if opcode = pc_fjp then
|
||||
GenNative(beq, relative, lab1, nil, 0)
|
||||
else
|
||||
|
@ -2147,12 +2268,20 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
GenLab(lab1);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_ldx_imm, immediate, 0, nil, 0);
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_inx);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_txa);
|
||||
if num <> 0 then
|
||||
GenNative(m_eor_imm, immediate, num, nil, 0)
|
||||
else if NeedsCondition(leftOp) then
|
||||
GenImpliedForFlags(m_tax);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end {if}
|
||||
else if (op^.optype in [cgLong,cgULong]) and (leftOp in [pc_ldo,pc_lod])
|
||||
|
@ -2167,24 +2296,20 @@ else if (op^.optype in [cgLong,cgULong]) and (leftOp in [pc_ldo,pc_lod])
|
|||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if}
|
||||
else if op^.opcode = pc_equ then begin
|
||||
lab1 := GenLabel;
|
||||
lab2 := GenLabel;
|
||||
DoOr(op^.left);
|
||||
GenNative(bne, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_bra, relative, lab2, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {else if}
|
||||
else {if op^.opcode = pc_neq then} begin
|
||||
else begin
|
||||
lab1 := GenLabel;
|
||||
DoOr(op^.left);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else if}
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end {else if}
|
||||
else if (op^.optype in [cgLong,cgULong]) and (rightOp in [pc_ldo,pc_lod]) then begin
|
||||
gLong.preference := A_X;
|
||||
|
@ -2229,8 +2354,7 @@ else
|
|||
if Complex(op^.right) or (not (opcode in [pc_fjp,pc_tjp])) then begin
|
||||
GenImplied(m_pha);
|
||||
GenTree(op^.right);
|
||||
GenImplied(m_sec);
|
||||
GenNative(m_sbc_s, direct, 1, nil, 0);
|
||||
GenNative(m_eor_s, direct, 1, nil, 0);
|
||||
GenImplied(m_plx);
|
||||
GenImplied(m_tax);
|
||||
if opcode in [pc_fjp,pc_tjp] then begin
|
||||
|
@ -2245,10 +2369,15 @@ else
|
|||
else begin
|
||||
lab1 := GenLabel;
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
if op^.opcode = pc_equ then
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end {if}
|
||||
else begin
|
||||
|
@ -2392,10 +2521,15 @@ else
|
|||
else begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab3);
|
||||
if op^.opcode = pc_equ then
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab3);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab3);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end; {case optype of cgQuad,cgUQuad}
|
||||
|
||||
|
@ -3617,11 +3751,17 @@ else begin
|
|||
else begin
|
||||
if op^.left^.opcode = pc_lao then begin
|
||||
GenTree(op^.right);
|
||||
if signed then
|
||||
GenImplied(m_tay);
|
||||
GenNative(m_ldx_imm, immediate, op^.left^.q, op^.left^.lab, shift16);
|
||||
if signed then begin
|
||||
GenImpliedForFlags(m_tay);
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_bpl, relative, lab2, nil, 0);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
signed := false;
|
||||
end; {if}
|
||||
GenImplied(m_clc);
|
||||
GenNative(m_adc_imm, immediate, op^.left^.q, op^.left^.lab, 0);
|
||||
GenNative(m_ldx_imm, immediate, op^.left^.q, op^.left^.lab, shift16);
|
||||
end {if}
|
||||
else begin
|
||||
gLong.preference := onStack;
|
||||
|
@ -3696,7 +3836,7 @@ var
|
|||
GenNative(m_inc_dirx, direct, 2, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if}
|
||||
else {if op in [pc_gdl,pc_gld] then} begin
|
||||
else {if op in [pc_ldl,pc_lld] then} begin
|
||||
lab1 := GenLabel;
|
||||
if p = 1 then begin
|
||||
GenNative(m_lda_dirx, direct, 0, nil, 0);
|
||||
|
@ -5493,10 +5633,11 @@ procedure GenTree {op: icptr};
|
|||
lab1: integer;
|
||||
operandIsBoolean: boolean;
|
||||
|
||||
begin {GenntNgiNot}
|
||||
begin {GenBntNgiNot}
|
||||
if op^.opcode = pc_not then
|
||||
operandIsBoolean := op^.left^.opcode in
|
||||
[pc_and,pc_ior,pc_neq,pc_equ,pc_geq,pc_leq,pc_les,pc_grt,pc_not];
|
||||
[pc_and,pc_ior,pc_lnd,pc_lor,pc_not,pc_neq,pc_equ,pc_geq,pc_leq,
|
||||
pc_les,pc_grt];
|
||||
GenTree(op^.left);
|
||||
case op^.opcode of
|
||||
pc_bnt:
|
||||
|
@ -5507,16 +5648,17 @@ procedure GenTree {op: icptr};
|
|||
GenImplied(m_ina);
|
||||
end; {case pc_ngi}
|
||||
|
||||
pc_not: begin
|
||||
pc_not:
|
||||
if not operandIsBoolean then begin
|
||||
lab1 := GenLabel;
|
||||
GenImpliedForFlags(m_tax);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
end; {if}
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
end; {case}
|
||||
end; {GenBntNgiNot}
|
||||
|
||||
|
@ -6504,49 +6646,50 @@ procedure GenTree {op: icptr};
|
|||
{ Generate code for a pc_lor or pc_lnd }
|
||||
|
||||
var
|
||||
lab1,lab2: integer; {label}
|
||||
opc: pcodes; {operation code}
|
||||
|
||||
|
||||
procedure DoOra;
|
||||
|
||||
{ do some common oring operations to reduce space }
|
||||
|
||||
begin {DoOra}
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_pla);
|
||||
GenNative(m_sta_dir, direct, dworkLoc, nil, 0);
|
||||
GenImplied(m_pla);
|
||||
end {if}
|
||||
else
|
||||
GenNative(m_stx_dir, direct, dworkLoc, nil, 0);
|
||||
GenNative(m_ora_dir, direct, dworkLoc, nil, 0);
|
||||
end; {DoOra}
|
||||
|
||||
lab1,lab2,lab3,lab4: integer; {labels}
|
||||
|
||||
begin {GenLorLnd}
|
||||
opc := op^.opcode;
|
||||
lab1 := GenLabel;
|
||||
lab3 := GenLabel;
|
||||
lab4 := GenLabel;
|
||||
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
DoOra;
|
||||
|
||||
lab2 := GenLabel;
|
||||
if opc = pc_lnd then
|
||||
GenNative(m_bne, relative, lab2, nil, 0)
|
||||
if glong.where = A_X then
|
||||
GenImpliedForFlags(m_tay)
|
||||
else begin
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenImplied(m_plx);
|
||||
GenImplied(m_pla);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lab1, nil, 0);
|
||||
GenLab(lab2);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_txa);
|
||||
if op^.opcode = pc_lor then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenLabUsedOnce(lab1);
|
||||
GenNative(m_brl, longrelative, lab3, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenNative(m_brl, longrelative, lab4, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.right);
|
||||
DoOra;
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
if glong.where = A_X then
|
||||
GenImpliedForFlags(m_tay)
|
||||
else begin
|
||||
GenImplied(m_plx);
|
||||
GenImplied(m_pla);
|
||||
end; {else}
|
||||
GenNative(m_bne, relative, lab3, nil, 0);
|
||||
GenImplied(m_txa);
|
||||
GenNative(m_beq, relative, lab4, nil, 0);
|
||||
GenLab(lab3);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenLab(lab4);
|
||||
end; {GenLorLnd}
|
||||
|
||||
|
||||
|
@ -7723,7 +7866,7 @@ var
|
|||
localSize := localSize + size;
|
||||
end {else if}
|
||||
else if opcode in
|
||||
[pc_les,pc_leq,pc_grt,pc_geq,pc_sto,pc_cpi,pc_ind,pc_lor,pc_lnd,
|
||||
[pc_les,pc_leq,pc_grt,pc_geq,pc_sto,pc_cpi,pc_ind,
|
||||
pc_ili,pc_iil,pc_idl,pc_ild,pc_ixa]
|
||||
then begin
|
||||
if dworkLoc = 0 then begin
|
||||
|
|
43
Native.pas
43
Native.pas
|
@ -110,6 +110,14 @@ procedure GenLab (lnum: integer);
|
|||
{ lnum - label number }
|
||||
|
||||
|
||||
procedure GenLabUsedOnce (lnum: integer);
|
||||
|
||||
{ generate a label that is only targeted by one branch }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ lnum - label number }
|
||||
|
||||
|
||||
procedure InitFile (keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean);
|
||||
|
||||
{ Set up the object file }
|
||||
|
@ -1637,7 +1645,7 @@ var
|
|||
end; {if}
|
||||
|
||||
m_bcs,m_beq,m_bne,m_bmi,m_bpl,m_bcc:
|
||||
if npeep[ns+2].opcode = d_lab then
|
||||
if npeep[ns+2].opcode = d_lab then begin
|
||||
if npeep[ns+2].operand = operand then
|
||||
if npeep[ns+1].opcode = m_brl then begin
|
||||
if Short(ns,npeep[ns+1].operand) then begin
|
||||
|
@ -1674,8 +1682,20 @@ var
|
|||
opcode := m_bmi;
|
||||
end {else if m_bra}
|
||||
else if npeep[ns+3].opcode in [m_bra,m_brl] then
|
||||
if Short(ns,npeep[ns+3].operand) then
|
||||
if Short(ns,npeep[ns+3].operand) then begin
|
||||
operand := npeep[ns+3].operand;
|
||||
if (npeep[ns+2].flags & labelUsedOnce) <> 0 then
|
||||
Remove(ns+2);
|
||||
end; {if}
|
||||
end {if}
|
||||
else if npeep[ns+3].opcode = d_lab then
|
||||
if npeep[ns+3].operand = operand then
|
||||
if npeep[ns+4].opcode in [m_bra,m_brl] then
|
||||
if Short(ns,npeep[ns+4].operand) then begin
|
||||
operand := npeep[ns+4].operand;
|
||||
if (npeep[ns+3].flags & labelUsedOnce) <> 0 then
|
||||
Remove(ns+3);
|
||||
end; {if}
|
||||
|
||||
m_brl:
|
||||
if Short(ns,operand) then begin
|
||||
|
@ -1700,11 +1720,12 @@ var
|
|||
Remove(ns+3);
|
||||
end; {if}
|
||||
|
||||
m_dec_abs:
|
||||
{disabled - can generate bad code}
|
||||
{m_dec_abs:
|
||||
if npeep[ns+1].opcode = m_lda_abs then
|
||||
if name^ = npeep[ns+1].name^ then
|
||||
if npeep[ns+2].opcode = m_beq then
|
||||
Remove(ns+1);
|
||||
Remove(ns+1);}
|
||||
|
||||
m_lda_abs:
|
||||
if npeep[ns+1].opcode = m_clc then begin
|
||||
|
@ -2301,6 +2322,18 @@ GenNative(d_lab, gnrlabel, lnum, nil, 0);
|
|||
end; {GenLab}
|
||||
|
||||
|
||||
procedure GenLabUsedOnce {lnum: integer};
|
||||
|
||||
{ generate a label that is only targeted by one branch }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ lnum - label number }
|
||||
|
||||
begin {GenLabUsedOnce}
|
||||
GenNative(d_lab, gnrlabel, lnum, nil, labelUsedOnce);
|
||||
end; {GenLabUsedOnce}
|
||||
|
||||
|
||||
procedure InitFile {keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean};
|
||||
|
||||
{ Set up the object file }
|
||||
|
@ -2625,7 +2658,7 @@ yRegister.condition := regUnknown;
|
|||
lastRegOpcode := 0; {BRK}
|
||||
nnextspot := 1;
|
||||
nleadOpcodes := [m_asl_a,m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_brl,{m_bvs,}
|
||||
m_dec_abs,m_lda_abs,m_lda_dir,m_lda_imm,m_ldx_imm,m_sta_abs,m_sta_dir,
|
||||
{m_dec_abs,}m_lda_abs,m_lda_dir,m_lda_imm,m_ldx_imm,m_sta_abs,m_sta_dir,
|
||||
m_pha,m_plb,{m_plx,}m_tax,m_tya,m_tyx,m_phy,m_pei_dir,m_ldy_imm,m_rep,
|
||||
m_ora_dir,m_ora_abs,m_and_imm,m_pea,m_tcd];
|
||||
nstopOpcodes := [d_end,d_pin];
|
||||
|
|
68
Parser.pas
68
Parser.pas
|
@ -122,13 +122,6 @@ type
|
|||
val: longlong; {switch value}
|
||||
end;
|
||||
|
||||
{token stack}
|
||||
{-----------}
|
||||
tokenStackPtr = ^tokenStackRecord;
|
||||
tokenStackRecord = record
|
||||
next: tokenStackPtr;
|
||||
token: tokenType;
|
||||
end;
|
||||
{statement stack}
|
||||
{---------------}
|
||||
statementPtr = ^statementRecord;
|
||||
|
@ -157,7 +150,7 @@ type
|
|||
);
|
||||
forSt: (
|
||||
forLoop: integer; {branch here to loop}
|
||||
e3List: tokenStackPtr; {tokens for last expression}
|
||||
e3Code: codeRef; {code for last expression}
|
||||
);
|
||||
switchSt: (
|
||||
maxVal: longint; {max switch value}
|
||||
|
@ -690,11 +683,9 @@ var
|
|||
{ handle a for statement }
|
||||
|
||||
var
|
||||
errorFound: boolean; {did we find an error?}
|
||||
e3Start: codeRef; {ref to start of code for expression 3}
|
||||
forLoop, continueLab, breakLab: integer; {branch points}
|
||||
parencount: integer; {number of unmatched '(' chars}
|
||||
stPtr: statementPtr; {work pointer}
|
||||
tl,tk: tokenStackPtr; {for forming expression list}
|
||||
|
||||
begin {ForStatement}
|
||||
NextToken; {skip the 'for' token}
|
||||
|
@ -733,29 +724,12 @@ var
|
|||
end; {if}
|
||||
Match(semicolonch,22);
|
||||
|
||||
tl := nil; {collect the tokens for the last expression}
|
||||
parencount := 0;
|
||||
errorFound := false;
|
||||
while (token.kind <> eofsy)
|
||||
and ((token.kind <> rparench) or (parencount <> 0))
|
||||
and (token.kind <> semicolonch) do begin
|
||||
new(tk); {place the token in the list}
|
||||
tk^.next := tl;
|
||||
tl := tk;
|
||||
tk^.token := token;
|
||||
if token.kind = lparench then {allow parens in the expression}
|
||||
parencount := parencount+1
|
||||
else if token.kind = rparench then
|
||||
parencount := parencount-1;
|
||||
NextToken; {next token}
|
||||
end; {while}
|
||||
if errorFound then {if an error was found, dump the list}
|
||||
while tl <> nil do begin
|
||||
tk := tl;
|
||||
tl := tl^.next;
|
||||
dispose(tk);
|
||||
end; {while}
|
||||
stPtr^.e3List := tl; {save the list}
|
||||
e3Start := GetCodeLocation; {generate and save code for expression 3}
|
||||
if token.kind <> rparench then begin
|
||||
Expression(normalExpression, [rparench]);
|
||||
Gen0t(pc_pop, UsualUnaryConversions);
|
||||
end; {if}
|
||||
stPtr^.e3Code := RemoveCode(e3Start);
|
||||
Match(rparench,12); {get the closing for loop paren}
|
||||
|
||||
if c99Scope then PushTable;
|
||||
|
@ -1128,37 +1102,13 @@ procedure EndForStatement;
|
|||
{ finish off a for statement }
|
||||
|
||||
var
|
||||
ltoken: tokenType; {for putting ; on stack}
|
||||
stPtr: statementPtr; {work pointer}
|
||||
tl,tk: tokenStackPtr; {for forming expression list}
|
||||
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||
|
||||
begin {EndForStatement}
|
||||
if c99Scope then PopTable;
|
||||
stPtr := statementList;
|
||||
Gen1(dc_lab, stPtr^.continueLab); {define the continue label}
|
||||
|
||||
tl := stPtr^.e3List; {place the expression back in the list}
|
||||
if tl <> nil then begin
|
||||
PutBackToken(token, false, false);
|
||||
ltoken.kind := semicolonch;
|
||||
ltoken.class := reservedSymbol;
|
||||
PutBackToken(ltoken, false, false);
|
||||
while tl <> nil do begin
|
||||
PutBackToken(tl^.token, false, false);
|
||||
tk := tl;
|
||||
tl := tl^.next;
|
||||
dispose(tk);
|
||||
end; {while}
|
||||
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token echo}
|
||||
suppressMacroExpansions := true;
|
||||
NextToken; {evaluate the expression}
|
||||
Expression(normalExpression, [semicolonch]);
|
||||
Gen0t(pc_pop, UsualUnaryConversions);
|
||||
NextToken; {skip the semicolon}
|
||||
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||
end; {if}
|
||||
|
||||
InsertCode(stPtr^.e3Code); {insert code for expression 3}
|
||||
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
|
||||
Gen1(dc_lab, stPtr^.breakLab); {create the exit label}
|
||||
statementList := stPtr^.next; {pop the statement record}
|
||||
|
|
4
cc.notes
4
cc.notes
|
@ -1616,6 +1616,10 @@ If you use #pragma debug 0x0010 to enable stack check debug code, the compiler w
|
|||
|
||||
13. If an empty argument was passed for a macro parameter that was used as an operand of the ## preprocessing operator, the result would likely be incorrect, and subsequent uses of the same macro also might not be expanded correctly.
|
||||
|
||||
14. If a struct, union, or enum type name appeared within the third expression in a for loop statement (e.g. in a cast or as the argument to sizeof), ORCA/C could behave incorrectly. It could report a spurious error if a semicolon occurred within the type name as part of a structure or union member declaration. Also, any tags or enumeration constants declared by such a type name should be in scope within the loop body, but they were not.
|
||||
|
||||
15. Native code peephole optimization might produce invalid code in some obscure circumstances where one element of a global or static array was decremented and then another element of the same array was accessed immediately thereafter.
|
||||
|
||||
-- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 ---------------------
|
||||
|
||||
1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination.
|
||||
|
|
Loading…
Reference in New Issue