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).
|
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 required by the C17 standard. It also has several other new
|
||||||
features, such as additional lint checks to help identify bugs and
|
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.
|
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
|
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
|
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:
|
following specifications:
|
||||||
|
|
||||||
* 2 MB of RAM (3 MB or more recommended)
|
* 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
|
This is an update package that can be used to update ORCA/C 2.1.0 or
|
||||||
ORCA/C 2.2.0. You must have an existing copy of ORCA/C 2.1.0 in order
|
2.2.0 to ORCA/C 2.2.1. You must have an existing copy of ORCA/C 2.1.0
|
||||||
to use this update. If you do not already have a copy, you can get it
|
or 2.2.0 in order to use this update. If you do not already have a
|
||||||
as part of Opus ][: The Software, a collection of Byte Works software
|
copy, you can get it as part of Opus ][: The Software, a collection of
|
||||||
which is sold by Juiced.GS:
|
Byte Works software which is sold by Juiced.GS:
|
||||||
https://juiced.gs/store/opus-ii-software/
|
https://juiced.gs/store/opus-ii-software/
|
||||||
|
|
||||||
This update must be applied to an existing ORCA installation containing
|
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
|
ORCA/C 2.1.0 or ORCA/C 2.2.0 (including the one provided on Opus ][:
|
||||||
Opus ][: The Software). To apply the update, you just need to copy
|
The Software). To apply the update, you just need to copy the files
|
||||||
the files from this distribution into the corresponding locations in
|
from this distribution into the corresponding locations in your ORCA
|
||||||
your ORCA installation, replacing any older versions.
|
installation, replacing any older versions.
|
||||||
|
|
||||||
If you received this update as a SHK file, you can simply extract the
|
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
|
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
|
by copying the files into place using the Finder, or by running the
|
||||||
following command within the root directory of your ORCA installation
|
following command within the root directory of your ORCA installation
|
||||||
using the text-based ORCA shell:
|
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
|
In addition to the ORCA shell environment, this update can also be
|
||||||
used under other environments that are compatible with ORCA/C, such as
|
used under other environments that are compatible with ORCA/C, such as
|
||||||
|
|
|
@ -139,7 +139,7 @@ opt[pc_ckn] := 'ckn';
|
||||||
end; {InitWriteCode}
|
end; {InitWriteCode}
|
||||||
|
|
||||||
|
|
||||||
procedure PrintDAG (tag: stringPtr; code: icptr);
|
procedure PrintDAG {tag: stringPtr; code: icptr};
|
||||||
|
|
||||||
{ print a DAG }
|
{ print a DAG }
|
||||||
{ }
|
{ }
|
||||||
|
|
108
CGI.pas
108
CGI.pas
|
@ -48,6 +48,7 @@ const
|
||||||
forFlags = 256; {instruction used for effect on flags only}
|
forFlags = 256; {instruction used for effect on flags only}
|
||||||
subtract1 = 512; {subtract 1 from address operand}
|
subtract1 = 512; {subtract 1 from address operand}
|
||||||
shiftLeft8 = 1024; {shift operand left 8 bits}
|
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_abs = $6D; {op code #s for 65816 instructions}
|
||||||
m_adc_dir = $65;
|
m_adc_dir = $65;
|
||||||
|
@ -292,6 +293,8 @@ type
|
||||||
ccPointer : (pval: longint; pstr: longStringPtr);
|
ccPointer : (pval: longint; pstr: longStringPtr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
codeRef = icptr; {reference to a code location}
|
||||||
|
|
||||||
{basic blocks}
|
{basic blocks}
|
||||||
{------------}
|
{------------}
|
||||||
iclist = ^iclistRecord; {used to form lists of records}
|
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 }
|
{ 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}
|
{procedure PrintBlocks (tag: stringPtr; bp: blockPtr); {debug}
|
||||||
|
|
||||||
{ print a series of basic blocks }
|
{ print a series of basic blocks }
|
||||||
|
@ -666,6 +684,28 @@ procedure GenTool (fop: pcodes; fp1, fp2: integer; dispatcher: longint);
|
||||||
{ bp - first block to print }
|
{ 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;
|
function TypeSize (tp: baseTypeEnum): integer;
|
||||||
|
|
||||||
{ Find the size, in bytes, of a variable }
|
{ Find the size, in bytes, of a variable }
|
||||||
|
@ -1430,6 +1470,74 @@ if codeGeneration then begin
|
||||||
end; {GenLdcReal}
|
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};
|
function TypeSize {tp: baseTypeEnum): integer};
|
||||||
|
|
||||||
{ Find the size, in bytes, of a variable }
|
{ 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}
|
begin {NeedsCondition}
|
||||||
NeedsCondition := opcode in
|
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_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_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,
|
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}
|
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}
|
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 }
|
{and pc_leq compares are reduced to their equivalent pc_grt and }
|
||||||
{pc_geq instructions. }
|
{pc_geq instructions. }
|
||||||
if op^.opcode = pc_les then begin
|
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
|
if NeedsCondition(op^.left^.opcode) then
|
||||||
GenImpliedForFlags(m_tax);
|
GenImpliedForFlags(m_tax);
|
||||||
if (num >= 0) and (num < 3) then begin
|
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;
|
lab2 := GenLabel;
|
||||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||||
for i := 1 to num do
|
if num = 2 then
|
||||||
GenImplied(m_dea);
|
GenImplied(m_lsr_a);
|
||||||
end; {if}
|
GenNative(m_bne, relative, lab1, nil, 0);
|
||||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
GenLabUsedOnce(lab2);
|
||||||
if num <> 0 then
|
end; {else}
|
||||||
GenLab(lab2);
|
|
||||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
end {if (num >= 0) and (num < 3)}
|
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_cmp_imm, immediate, num, nil, 0);
|
||||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||||
if num > 0 then begin
|
if num > 0 then begin
|
||||||
GenLab(lab1);
|
GenLabUsedOnce(lab1);
|
||||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab2);
|
GenLab(lab2);
|
||||||
end {if}
|
end {if}
|
||||||
|
@ -1147,8 +1162,17 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||||
end {if}
|
end {if}
|
||||||
else {if optype in [cgUByte,cgUWord] then} begin
|
else {if optype in [cgUByte,cgUWord] then} begin
|
||||||
if num <> 0 then begin
|
if num <> 0 then begin
|
||||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
if num in [1,2] then begin
|
||||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
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);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
end; {if}
|
end; {if}
|
||||||
|
@ -1163,9 +1187,9 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||||
if (num >= 0) and (num < 3) then begin
|
if (num >= 0) and (num < 3) then begin
|
||||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||||
if num > 0 then begin
|
if num > 0 then begin
|
||||||
for i := 1 to num do
|
if num = 2 then
|
||||||
GenImplied(m_dea);
|
GenImplied(m_lsr_a);
|
||||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
GenNative(m_beq, relative, lab1, nil, 0);
|
||||||
end; {if}
|
end; {if}
|
||||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
|
@ -1184,7 +1208,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
end {if}
|
end {if}
|
||||||
else begin
|
else begin
|
||||||
GenLab(lab1);
|
GenLabUsedOnce(lab1);
|
||||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab2);
|
GenLab(lab2);
|
||||||
end; {else}
|
end; {else}
|
||||||
|
@ -1192,8 +1216,17 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||||
end {if}
|
end {if}
|
||||||
else {if optype in [cgUByte,cgUWord] then} begin
|
else {if optype in [cgUByte,cgUWord] then} begin
|
||||||
if num <> 0 then begin
|
if num <> 0 then begin
|
||||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
if num in [1,2] then begin
|
||||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
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}
|
end; {if}
|
||||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
if num <> 0 then
|
if num <> 0 then
|
||||||
|
@ -1282,7 +1315,7 @@ else
|
||||||
else
|
else
|
||||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||||
if op^.opcode = pc_grt then
|
if op^.opcode = pc_grt then
|
||||||
GenLab(lab3);
|
GenLabUsedOnce(lab3);
|
||||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab2);
|
GenLab(lab2);
|
||||||
end {if}
|
end {if}
|
||||||
|
@ -1330,50 +1363,134 @@ else
|
||||||
end; {case optype of cgByte,cgUByte,cgWord,cgUWord}
|
end; {case optype of cgByte,cgUByte,cgWord,cgUWord}
|
||||||
|
|
||||||
cgULong: begin
|
cgULong: begin
|
||||||
gLong.preference := onStack;
|
lab1 := GenLabel;
|
||||||
GenTree(op^.right);
|
lab2 := GenLabel;
|
||||||
gLong.preference := A_X;
|
simple := false;
|
||||||
GenTree(op^.left);
|
if SimpleLongOp(op^.right) then
|
||||||
if gLong.where = onStack then begin
|
simple := true
|
||||||
GenImplied(m_ply);
|
else if rOpcode in [pc_fjp,pc_tjp] then
|
||||||
GenImplied(m_pla);
|
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}
|
end {if}
|
||||||
else begin
|
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);
|
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}
|
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;
|
end;
|
||||||
|
|
||||||
cgReal,cgDouble,cgComp,cgExtended: begin
|
cgReal,cgDouble,cgComp,cgExtended: begin
|
||||||
|
@ -2135,10 +2252,14 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||||
num := op^.right^.q;
|
num := op^.right^.q;
|
||||||
lab1 := GenLabel;
|
lab1 := GenLabel;
|
||||||
if opcode in [pc_fjp,pc_tjp] then begin
|
if opcode in [pc_fjp,pc_tjp] then begin
|
||||||
if num <> 0 then
|
if num = 0 then begin
|
||||||
GenNative(m_cmp_imm, immediate, num, nil, 0)
|
if NeedsCondition(leftOp) then
|
||||||
else if NeedsCondition(leftOp) then
|
GenImpliedForFlags(m_tay);
|
||||||
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
|
if opcode = pc_fjp then
|
||||||
GenNative(beq, relative, lab1, nil, 0)
|
GenNative(beq, relative, lab1, nil, 0)
|
||||||
else
|
else
|
||||||
|
@ -2147,12 +2268,20 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
end {if}
|
end {if}
|
||||||
else begin
|
else begin
|
||||||
GenNative(m_ldx_imm, immediate, 0, nil, 0);
|
if num <> 0 then
|
||||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
GenNative(m_eor_imm, immediate, num, nil, 0)
|
||||||
GenNative(bne, relative, lab1, nil, 0);
|
else if NeedsCondition(leftOp) then
|
||||||
GenImplied(m_inx);
|
GenImpliedForFlags(m_tax);
|
||||||
GenLab(lab1);
|
GenNative(m_beq, relative, lab1, nil, 0);
|
||||||
GenImplied(m_txa);
|
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}
|
||||||
end {if}
|
end {if}
|
||||||
else if (op^.optype in [cgLong,cgULong]) and (leftOp in [pc_ldo,pc_lod])
|
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);
|
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
end {if}
|
end {if}
|
||||||
else if op^.opcode = pc_equ then begin
|
else 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
|
|
||||||
lab1 := GenLabel;
|
lab1 := GenLabel;
|
||||||
DoOr(op^.left);
|
DoOr(op^.left);
|
||||||
GenNative(m_beq, relative, lab1, nil, 0);
|
GenNative(m_beq, relative, lab1, nil, 0);
|
||||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
if op^.opcode = pc_equ then begin
|
||||||
GenLab(lab1);
|
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||||
end; {else if}
|
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}
|
end {else if}
|
||||||
else if (op^.optype in [cgLong,cgULong]) and (rightOp in [pc_ldo,pc_lod]) then begin
|
else if (op^.optype in [cgLong,cgULong]) and (rightOp in [pc_ldo,pc_lod]) then begin
|
||||||
gLong.preference := A_X;
|
gLong.preference := A_X;
|
||||||
|
@ -2229,8 +2354,7 @@ else
|
||||||
if Complex(op^.right) or (not (opcode in [pc_fjp,pc_tjp])) then begin
|
if Complex(op^.right) or (not (opcode in [pc_fjp,pc_tjp])) then begin
|
||||||
GenImplied(m_pha);
|
GenImplied(m_pha);
|
||||||
GenTree(op^.right);
|
GenTree(op^.right);
|
||||||
GenImplied(m_sec);
|
GenNative(m_eor_s, direct, 1, nil, 0);
|
||||||
GenNative(m_sbc_s, direct, 1, nil, 0);
|
|
||||||
GenImplied(m_plx);
|
GenImplied(m_plx);
|
||||||
GenImplied(m_tax);
|
GenImplied(m_tax);
|
||||||
if opcode in [pc_fjp,pc_tjp] then begin
|
if opcode in [pc_fjp,pc_tjp] then begin
|
||||||
|
@ -2245,10 +2369,15 @@ else
|
||||||
else begin
|
else begin
|
||||||
lab1 := GenLabel;
|
lab1 := GenLabel;
|
||||||
GenNative(m_beq, relative, lab1, nil, 0);
|
GenNative(m_beq, relative, lab1, nil, 0);
|
||||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
if op^.opcode = pc_equ then begin
|
||||||
GenLab(lab1);
|
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||||
if op^.opcode = pc_equ then
|
GenLab(lab1);
|
||||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
GenImplied(m_ina);
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||||
|
GenLab(lab1);
|
||||||
|
end; {else}
|
||||||
end; {else}
|
end; {else}
|
||||||
end {if}
|
end {if}
|
||||||
else begin
|
else begin
|
||||||
|
@ -2392,10 +2521,15 @@ else
|
||||||
else begin
|
else begin
|
||||||
lab3 := GenLabel;
|
lab3 := GenLabel;
|
||||||
GenNative(m_beq, relative, lab3, nil, 0);
|
GenNative(m_beq, relative, lab3, nil, 0);
|
||||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
if op^.opcode = pc_equ then begin
|
||||||
GenLab(lab3);
|
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||||
if op^.opcode = pc_equ then
|
GenLab(lab3);
|
||||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
GenImplied(m_ina);
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||||
|
GenLab(lab3);
|
||||||
|
end; {else}
|
||||||
end; {else}
|
end; {else}
|
||||||
end; {case optype of cgQuad,cgUQuad}
|
end; {case optype of cgQuad,cgUQuad}
|
||||||
|
|
||||||
|
@ -3617,11 +3751,17 @@ else begin
|
||||||
else begin
|
else begin
|
||||||
if op^.left^.opcode = pc_lao then begin
|
if op^.left^.opcode = pc_lao then begin
|
||||||
GenTree(op^.right);
|
GenTree(op^.right);
|
||||||
if signed then
|
GenNative(m_ldx_imm, immediate, op^.left^.q, op^.left^.lab, shift16);
|
||||||
GenImplied(m_tay);
|
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);
|
GenImplied(m_clc);
|
||||||
GenNative(m_adc_imm, immediate, op^.left^.q, op^.left^.lab, 0);
|
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}
|
end {if}
|
||||||
else begin
|
else begin
|
||||||
gLong.preference := onStack;
|
gLong.preference := onStack;
|
||||||
|
@ -3696,7 +3836,7 @@ var
|
||||||
GenNative(m_inc_dirx, direct, 2, nil, 0);
|
GenNative(m_inc_dirx, direct, 2, nil, 0);
|
||||||
GenLab(lab1);
|
GenLab(lab1);
|
||||||
end {if}
|
end {if}
|
||||||
else {if op in [pc_gdl,pc_gld] then} begin
|
else {if op in [pc_ldl,pc_lld] then} begin
|
||||||
lab1 := GenLabel;
|
lab1 := GenLabel;
|
||||||
if p = 1 then begin
|
if p = 1 then begin
|
||||||
GenNative(m_lda_dirx, direct, 0, nil, 0);
|
GenNative(m_lda_dirx, direct, 0, nil, 0);
|
||||||
|
@ -5493,10 +5633,11 @@ procedure GenTree {op: icptr};
|
||||||
lab1: integer;
|
lab1: integer;
|
||||||
operandIsBoolean: boolean;
|
operandIsBoolean: boolean;
|
||||||
|
|
||||||
begin {GenntNgiNot}
|
begin {GenBntNgiNot}
|
||||||
if op^.opcode = pc_not then
|
if op^.opcode = pc_not then
|
||||||
operandIsBoolean := op^.left^.opcode in
|
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);
|
GenTree(op^.left);
|
||||||
case op^.opcode of
|
case op^.opcode of
|
||||||
pc_bnt:
|
pc_bnt:
|
||||||
|
@ -5507,16 +5648,17 @@ procedure GenTree {op: icptr};
|
||||||
GenImplied(m_ina);
|
GenImplied(m_ina);
|
||||||
end; {case pc_ngi}
|
end; {case pc_ngi}
|
||||||
|
|
||||||
pc_not: begin
|
pc_not:
|
||||||
if not operandIsBoolean then begin
|
if not operandIsBoolean then begin
|
||||||
lab1 := GenLabel;
|
lab1 := GenLabel;
|
||||||
GenImpliedForFlags(m_tax);
|
GenImpliedForFlags(m_tax);
|
||||||
GenNative(m_beq, relative, lab1, nil, 0);
|
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);
|
GenLab(lab1);
|
||||||
end; {if}
|
GenImplied(m_ina);
|
||||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
end {if}
|
||||||
end; {if}
|
else
|
||||||
|
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||||
end; {case}
|
end; {case}
|
||||||
end; {GenBntNgiNot}
|
end; {GenBntNgiNot}
|
||||||
|
|
||||||
|
@ -6504,49 +6646,50 @@ procedure GenTree {op: icptr};
|
||||||
{ Generate code for a pc_lor or pc_lnd }
|
{ Generate code for a pc_lor or pc_lnd }
|
||||||
|
|
||||||
var
|
var
|
||||||
lab1,lab2: integer; {label}
|
lab1,lab2,lab3,lab4: integer; {labels}
|
||||||
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}
|
|
||||||
|
|
||||||
|
|
||||||
begin {GenLorLnd}
|
begin {GenLorLnd}
|
||||||
opc := op^.opcode;
|
|
||||||
lab1 := GenLabel;
|
lab1 := GenLabel;
|
||||||
|
lab3 := GenLabel;
|
||||||
|
lab4 := GenLabel;
|
||||||
|
|
||||||
gLong.preference := A_X;
|
gLong.preference := A_X;
|
||||||
GenTree(op^.left);
|
GenTree(op^.left);
|
||||||
DoOra;
|
if glong.where = A_X then
|
||||||
|
GenImpliedForFlags(m_tay)
|
||||||
lab2 := GenLabel;
|
|
||||||
if opc = pc_lnd then
|
|
||||||
GenNative(m_bne, relative, lab2, nil, 0)
|
|
||||||
else begin
|
else begin
|
||||||
GenNative(m_beq, relative, lab2, nil, 0);
|
GenImplied(m_plx);
|
||||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
GenImplied(m_pla);
|
||||||
end; {else}
|
end; {else}
|
||||||
GenNative(m_brl, longrelative, lab1, nil, 0);
|
GenNative(m_bne, relative, lab1, nil, 0);
|
||||||
GenLab(lab2);
|
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;
|
gLong.preference := A_X;
|
||||||
GenTree(op^.right);
|
GenTree(op^.right);
|
||||||
DoOra;
|
if glong.where = A_X then
|
||||||
GenNative(m_beq, relative, lab1, nil, 0);
|
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);
|
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||||
GenLab(lab1);
|
GenLab(lab4);
|
||||||
end; {GenLorLnd}
|
end; {GenLorLnd}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7723,7 +7866,7 @@ var
|
||||||
localSize := localSize + size;
|
localSize := localSize + size;
|
||||||
end {else if}
|
end {else if}
|
||||||
else if opcode in
|
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]
|
pc_ili,pc_iil,pc_idl,pc_ild,pc_ixa]
|
||||||
then begin
|
then begin
|
||||||
if dworkLoc = 0 then begin
|
if dworkLoc = 0 then begin
|
||||||
|
|
43
Native.pas
43
Native.pas
|
@ -110,6 +110,14 @@ procedure GenLab (lnum: integer);
|
||||||
{ lnum - label number }
|
{ 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);
|
procedure InitFile (keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean);
|
||||||
|
|
||||||
{ Set up the object file }
|
{ Set up the object file }
|
||||||
|
@ -1637,7 +1645,7 @@ var
|
||||||
end; {if}
|
end; {if}
|
||||||
|
|
||||||
m_bcs,m_beq,m_bne,m_bmi,m_bpl,m_bcc:
|
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+2].operand = operand then
|
||||||
if npeep[ns+1].opcode = m_brl then begin
|
if npeep[ns+1].opcode = m_brl then begin
|
||||||
if Short(ns,npeep[ns+1].operand) then begin
|
if Short(ns,npeep[ns+1].operand) then begin
|
||||||
|
@ -1674,8 +1682,20 @@ var
|
||||||
opcode := m_bmi;
|
opcode := m_bmi;
|
||||||
end {else if m_bra}
|
end {else if m_bra}
|
||||||
else if npeep[ns+3].opcode in [m_bra,m_brl] then
|
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;
|
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:
|
m_brl:
|
||||||
if Short(ns,operand) then begin
|
if Short(ns,operand) then begin
|
||||||
|
@ -1700,11 +1720,12 @@ var
|
||||||
Remove(ns+3);
|
Remove(ns+3);
|
||||||
end; {if}
|
end; {if}
|
||||||
|
|
||||||
m_dec_abs:
|
{disabled - can generate bad code}
|
||||||
|
{m_dec_abs:
|
||||||
if npeep[ns+1].opcode = m_lda_abs then
|
if npeep[ns+1].opcode = m_lda_abs then
|
||||||
if name^ = npeep[ns+1].name^ then
|
if name^ = npeep[ns+1].name^ then
|
||||||
if npeep[ns+2].opcode = m_beq then
|
if npeep[ns+2].opcode = m_beq then
|
||||||
Remove(ns+1);
|
Remove(ns+1);}
|
||||||
|
|
||||||
m_lda_abs:
|
m_lda_abs:
|
||||||
if npeep[ns+1].opcode = m_clc then begin
|
if npeep[ns+1].opcode = m_clc then begin
|
||||||
|
@ -2301,6 +2322,18 @@ GenNative(d_lab, gnrlabel, lnum, nil, 0);
|
||||||
end; {GenLab}
|
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};
|
procedure InitFile {keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean};
|
||||||
|
|
||||||
{ Set up the object file }
|
{ Set up the object file }
|
||||||
|
@ -2625,7 +2658,7 @@ yRegister.condition := regUnknown;
|
||||||
lastRegOpcode := 0; {BRK}
|
lastRegOpcode := 0; {BRK}
|
||||||
nnextspot := 1;
|
nnextspot := 1;
|
||||||
nleadOpcodes := [m_asl_a,m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_brl,{m_bvs,}
|
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_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];
|
m_ora_dir,m_ora_abs,m_and_imm,m_pea,m_tcd];
|
||||||
nstopOpcodes := [d_end,d_pin];
|
nstopOpcodes := [d_end,d_pin];
|
||||||
|
|
68
Parser.pas
68
Parser.pas
|
@ -122,13 +122,6 @@ type
|
||||||
val: longlong; {switch value}
|
val: longlong; {switch value}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{token stack}
|
|
||||||
{-----------}
|
|
||||||
tokenStackPtr = ^tokenStackRecord;
|
|
||||||
tokenStackRecord = record
|
|
||||||
next: tokenStackPtr;
|
|
||||||
token: tokenType;
|
|
||||||
end;
|
|
||||||
{statement stack}
|
{statement stack}
|
||||||
{---------------}
|
{---------------}
|
||||||
statementPtr = ^statementRecord;
|
statementPtr = ^statementRecord;
|
||||||
|
@ -157,7 +150,7 @@ type
|
||||||
);
|
);
|
||||||
forSt: (
|
forSt: (
|
||||||
forLoop: integer; {branch here to loop}
|
forLoop: integer; {branch here to loop}
|
||||||
e3List: tokenStackPtr; {tokens for last expression}
|
e3Code: codeRef; {code for last expression}
|
||||||
);
|
);
|
||||||
switchSt: (
|
switchSt: (
|
||||||
maxVal: longint; {max switch value}
|
maxVal: longint; {max switch value}
|
||||||
|
@ -690,11 +683,9 @@ var
|
||||||
{ handle a for statement }
|
{ handle a for statement }
|
||||||
|
|
||||||
var
|
var
|
||||||
errorFound: boolean; {did we find an error?}
|
e3Start: codeRef; {ref to start of code for expression 3}
|
||||||
forLoop, continueLab, breakLab: integer; {branch points}
|
forLoop, continueLab, breakLab: integer; {branch points}
|
||||||
parencount: integer; {number of unmatched '(' chars}
|
|
||||||
stPtr: statementPtr; {work pointer}
|
stPtr: statementPtr; {work pointer}
|
||||||
tl,tk: tokenStackPtr; {for forming expression list}
|
|
||||||
|
|
||||||
begin {ForStatement}
|
begin {ForStatement}
|
||||||
NextToken; {skip the 'for' token}
|
NextToken; {skip the 'for' token}
|
||||||
|
@ -733,29 +724,12 @@ var
|
||||||
end; {if}
|
end; {if}
|
||||||
Match(semicolonch,22);
|
Match(semicolonch,22);
|
||||||
|
|
||||||
tl := nil; {collect the tokens for the last expression}
|
e3Start := GetCodeLocation; {generate and save code for expression 3}
|
||||||
parencount := 0;
|
if token.kind <> rparench then begin
|
||||||
errorFound := false;
|
Expression(normalExpression, [rparench]);
|
||||||
while (token.kind <> eofsy)
|
Gen0t(pc_pop, UsualUnaryConversions);
|
||||||
and ((token.kind <> rparench) or (parencount <> 0))
|
end; {if}
|
||||||
and (token.kind <> semicolonch) do begin
|
stPtr^.e3Code := RemoveCode(e3Start);
|
||||||
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}
|
|
||||||
Match(rparench,12); {get the closing for loop paren}
|
Match(rparench,12); {get the closing for loop paren}
|
||||||
|
|
||||||
if c99Scope then PushTable;
|
if c99Scope then PushTable;
|
||||||
|
@ -1128,37 +1102,13 @@ procedure EndForStatement;
|
||||||
{ finish off a for statement }
|
{ finish off a for statement }
|
||||||
|
|
||||||
var
|
var
|
||||||
ltoken: tokenType; {for putting ; on stack}
|
|
||||||
stPtr: statementPtr; {work pointer}
|
stPtr: statementPtr; {work pointer}
|
||||||
tl,tk: tokenStackPtr; {for forming expression list}
|
|
||||||
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
|
||||||
|
|
||||||
begin {EndForStatement}
|
begin {EndForStatement}
|
||||||
if c99Scope then PopTable;
|
if c99Scope then PopTable;
|
||||||
stPtr := statementList;
|
stPtr := statementList;
|
||||||
Gen1(dc_lab, stPtr^.continueLab); {define the continue label}
|
Gen1(dc_lab, stPtr^.continueLab); {define the continue label}
|
||||||
|
InsertCode(stPtr^.e3Code); {insert code for expression 3}
|
||||||
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}
|
|
||||||
|
|
||||||
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
|
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
|
||||||
Gen1(dc_lab, stPtr^.breakLab); {create the exit label}
|
Gen1(dc_lab, stPtr^.breakLab); {create the exit label}
|
||||||
statementList := stPtr^.next; {pop the statement record}
|
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.
|
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 ---------------------
|
-- 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.
|
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