Optimize some quad ops to use interleaved loads and stores.

This allows them to bypass the intermediate step of loading the value onto the stack. Currently, this only works for simple cases where a value is loaded and immediately stored.
This commit is contained in:
Stephen Heumann 2021-02-20 23:38:42 -06:00
parent 3c0e4baf78
commit daff197811

487
Gen.pas
View File

@ -55,7 +55,7 @@ const
type type
{possible locations for 4 byte values} {possible locations for 4 byte values}
longType = record {description of current four byte value} longType = record {description of current four byte value}
preference: integer; {where you want the value} preference: integer; {where you want the value (bitmask)}
where: integer; {where the value is at} where: integer; {where the value is at}
fixedDisp: boolean; {is the displacement a fixed value?} fixedDisp: boolean; {is the displacement a fixed value?}
isLong: boolean; {is long addr required for named labs?} isLong: boolean; {is long addr required for named labs?}
@ -66,7 +66,7 @@ type
{possible locations for 8 byte values} {possible locations for 8 byte values}
{note: these always have fixed disp} {note: these always have fixed disp}
quadType = record {description of current 8 byte value} quadType = record {description of current 8 byte value}
preference: integer; {where you want the value} preference: integer; {where you want the value (single value)}
where: integer; {where the value is at} where: integer; {where the value is at}
disp: integer; {fixed displacement/local addr} disp: integer; {fixed displacement/local addr}
lval: longlong; {value} lval: longlong; {value}
@ -238,6 +238,61 @@ else {if icode^.opcode in [pc_ldo, pc_sro] then}
end; {DoOp} end; {DoOp}
procedure StoreWordOfQuad(offset: integer);
{ Store one word of a quad value to the location specified by }
{ gQuad.preference. The word value to store must be in A. }
{ }
{ The generated code may modify X, and may set Y to offset. }
{ It does not modify A or the carry flag. }
{ }
{ parameters: }
{ offset - offset of the word to store (0, 2, 4, or 6) }
{ }
{ Note: If gQuad.preference is onStack, this just generates a }
{ PHA. That is suitable if loading a value starting from }
{ the most significant word, but not in other cases. For }
{ other gQuad.preference values, any order is okay. }
begin {StoreWordOfQuad}
case gQuad.preference of
localAddress: begin
if gQuad.disp+offset <= 255 then
GenNative(m_sta_dir, direct, gQuad.disp+offset, nil, 0)
else begin
GenNative(m_ldx_imm, immediate, gQuad.disp+offset, nil, 0);
GenNative(m_sta_dirX, direct, 0, nil, 0);
end; {else}
end;
globalLabel: begin
if smallMemoryModel then
GenNative(m_sta_abs, absolute, gQuad.disp+offset, gQuad.lab, 0)
else
GenNative(m_sta_long, longabsolute, gQuad.disp+offset, gQuad.lab, 0);
end;
inPointer: begin
if (gQuad.disp > 255) or (gQuad.disp < 0) then
Error(cge1);
if offset = 0 then
GenNative(m_sta_indl, direct, gQuad.disp, nil, 0)
else begin
GenNative(m_ldy_imm, immediate, offset, nil, 0);
GenNative(m_sta_indly, direct, gQuad.disp, nil, 0);
end; {else}
end;
onStack:
GenImplied(m_pha);
nowhere: ; {discard the value}
otherwise: Error(cge1);
end; {case}
end; {StoreWordOfQuad}
procedure GetPointer (op: icptr); procedure GetPointer (op: icptr);
{ convert a tree into a usable pointer for indirect } { convert a tree into a usable pointer for indirect }
@ -1376,7 +1431,10 @@ begin {GenCnv}
lLong := gLong; lLong := gLong;
gLong.preference := onStack+A_X+constant; gLong.preference := onStack+A_X+constant;
gLong.where := onStack; gLong.where := onStack;
gQuad.preference := onStack; if op^.q in [quadToVoid,uQuadToVoid] then
gQuad.preference := nowhere
else
gQuad.preference := onStack;
if ((op^.q & $00F0) >> 4) in [cDouble,cExtended,cComp] then begin if ((op^.q & $00F0) >> 4) in [cDouble,cExtended,cComp] then begin
op^.q := (op^.q & $000F) | (cReal * 16); op^.q := (op^.q & $000F) | (cReal * 16);
fromReal := true; fromReal := true;
@ -1386,7 +1444,6 @@ else
if (op^.q & $000F) in [cDouble,cExtended,cComp] then if (op^.q & $000F) in [cDouble,cExtended,cComp] then
op^.q := (op^.q & $00F0) | cReal; op^.q := (op^.q & $00F0) | cReal;
GenTree(op^.left); GenTree(op^.left);
gQuad.where := onStack; {unless overridden below}
if op^.q in [wordToLong,wordToUlong] then begin if op^.q in [wordToLong,wordToUlong] then begin
lab1 := GenLabel; lab1 := GenLabel;
GenNative(m_ldx_imm, immediate, 0, nil, 0); GenNative(m_ldx_imm, immediate, 0, nil, 0);
@ -1552,6 +1609,7 @@ else if op^.q in [ubyteToQuad,ubyteToUQuad,uwordToQuad,uwordToUQuad] then begin
GenImplied(m_phy); GenImplied(m_phy);
GenImplied(m_phy); GenImplied(m_phy);
GenImplied(m_pha); GenImplied(m_pha);
gQuad.where := onStack;
end {else if} end {else if}
else if op^.q in [byteToQuad,byteToUQuad] then begin else if op^.q in [byteToQuad,byteToUQuad] then begin
lab1 := GenLabel; lab1 := GenLabel;
@ -1565,6 +1623,7 @@ else if op^.q in [byteToQuad,byteToUQuad] then begin
GenImplied(m_phx); GenImplied(m_phx);
GenImplied(m_phx); GenImplied(m_phx);
GenImplied(m_pha); GenImplied(m_pha);
gQuad.where := onStack;
end {else if} end {else if}
else if op^.q in [wordToQuad,wordToUQuad] then begin else if op^.q in [wordToQuad,wordToUQuad] then begin
lab1 := GenLabel; lab1 := GenLabel;
@ -1577,6 +1636,7 @@ else if op^.q in [wordToQuad,wordToUQuad] then begin
GenImplied(m_phx); GenImplied(m_phx);
GenImplied(m_phx); GenImplied(m_phx);
GenImplied(m_pha); GenImplied(m_pha);
gQuad.where := onStack;
end {else if} end {else if}
else if op^.q in [ulongToQuad,ulongToUQuad] then begin else if op^.q in [ulongToQuad,ulongToUQuad] then begin
if gLong.where = A_X then begin if gLong.where = A_X then begin
@ -1599,6 +1659,7 @@ else if op^.q in [ulongToQuad,ulongToUQuad] then begin
GenImplied(m_phx); GenImplied(m_phx);
GenImplied(m_pha); GenImplied(m_pha);
end; {else} end; {else}
gQuad.where := onStack;
end {else if} end {else if}
else if op^.q in [longToQuad,longToUQuad] then begin else if op^.q in [longToQuad,longToUQuad] then begin
if gLong.where = constant then begin if gLong.where = constant then begin
@ -1632,11 +1693,16 @@ else if op^.q in [longToQuad,longToUQuad] then begin
GenImplied(m_phx); GenImplied(m_phx);
GenImplied(m_pha); GenImplied(m_pha);
end; {else} end; {else}
gQuad.where := onStack;
end {else if}
else if op^.q = realToQuad then begin
GenCall(89);
gQuad.where := onStack;
end {else if}
else if op^.q = realToUQuad then begin
GenCall(90);
gQuad.where := onStack;
end {else if} end {else if}
else if op^.q = realToQuad then
GenCall(89)
else if op^.q = realToUQuad then
GenCall(90)
else if op^.q in [quadToWord,uquadToWord,quadToUWord,uquadToUWord] then begin else if op^.q in [quadToWord,uquadToWord,quadToUWord,uquadToUWord] then begin
GenImplied(m_pla); GenImplied(m_pla);
GenImplied(m_plx); GenImplied(m_plx);
@ -1677,10 +1743,12 @@ else if op^.q in [quadToLong,uquadToLong,quadToULong,uquadToULong] then begin
end; {else} end; {else}
end {else if} end {else if}
else if op^.q in [quadToVoid,uquadToVoid] then begin else if op^.q in [quadToVoid,uquadToVoid] then begin
GenImplied(m_tsc); if gQuad.where = onStack then begin
GenImplied(m_clc); GenImplied(m_tsc);
GenNative(m_adc_imm, immediate, 8, nil, 0); GenImplied(m_clc);
GenImplied(m_tcs); GenNative(m_adc_imm, immediate, 8, nil, 0);
GenImplied(m_tcs);
end; {if}
end {else if} end {else if}
else if op^.q = quadToReal then else if op^.q = quadToReal then
GenCall(83) GenCall(83)
@ -2583,6 +2651,7 @@ procedure GenInd (op: icptr);
var var
lab1: integer; {label} lab1: integer; {label}
lLong: longType; {requested address type} lLong: longType; {requested address type}
lQuad: quadType; {requested quad address type}
optype: baseTypeEnum; {op^.optype} optype: baseTypeEnum; {op^.optype}
q: integer; {op^.q} q: integer; {op^.q}
@ -2794,23 +2863,26 @@ case optype of
end; {case cgByte,cgUByte,cgWord,cgUWord} end; {case cgByte,cgUByte,cgWord,cgUWord}
cgQuad,cgUQuad: begin cgQuad,cgUQuad: begin
lQuad := gQuad;
GetPointer(op^.left); GetPointer(op^.left);
gQuad := lQuad;
gQuad.where := gQuad.preference; {unless overridden later}
if gLong.where = inPointer then begin if gLong.where = inPointer then begin
if q = 0 then begin if q = 0 then begin
if gLong.fixedDisp then begin if gLong.fixedDisp then begin
GenNative(m_ldy_imm, immediate, 6, nil, 0); GenNative(m_ldy_imm, immediate, 6, nil, 0);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenNative(m_lda_indl, direct, gLong.disp, nil, 0); GenNative(m_lda_indl, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end {if} end {if}
else begin else begin
GenImplied(m_tya); GenImplied(m_tya);
@ -2818,38 +2890,38 @@ case optype of
GenNative(m_adc_imm, immediate, 6, nil, 0); GenNative(m_adc_imm, immediate, 6, nil, 0);
GenImplied(m_tay); GenImplied(m_tay);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end; {else} end; {else}
end {if q = 0} end {if q = 0}
else begin else begin
if gLong.fixedDisp then begin if gLong.fixedDisp then begin
GenNative(m_ldy_imm, immediate, q+6, nil, 0); GenNative(m_ldy_imm, immediate, q+6, nil, 0);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end {if} end {if}
else begin else begin
GenImplied(m_tya); GenImplied(m_tya);
@ -2857,19 +2929,19 @@ case optype of
GenNative(m_adc_imm, immediate, q+6, nil, 0); GenNative(m_adc_imm, immediate, q+6, nil, 0);
GenImplied(m_tay); GenImplied(m_tay);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenImplied(m_dey); GenImplied(m_dey);
GenImplied(m_dey); GenImplied(m_dey);
GenNative(m_lda_indly, direct, gLong.disp, nil, 0); GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end; {else} end; {else}
end; {else} end; {else}
end {if glong.where = inPointer} end {if glong.where = inPointer}
@ -2877,12 +2949,25 @@ case optype of
gLong.disp := gLong.disp+q; gLong.disp := gLong.disp+q;
if gLong.fixedDisp then if gLong.fixedDisp then
if (gLong.disp < 250) and (gLong.disp >= 0) then begin if (gLong.disp < 250) and (gLong.disp >= 0) then begin
GenNative(m_pei_dir, direct, gLong.disp+6, nil, 0); if gQuad.preference = onStack then begin
GenNative(m_pei_dir, direct, gLong.disp+4, nil, 0); GenNative(m_pei_dir, direct, gLong.disp+6, nil, 0);
GenNative(m_pei_dir, direct, gLong.disp+2, nil, 0); GenNative(m_pei_dir, direct, gLong.disp+4, nil, 0);
GenNative(m_pei_dir, direct, gLong.disp, nil, 0); GenNative(m_pei_dir, direct, gLong.disp+2, nil, 0);
GenNative(m_pei_dir, direct, gLong.disp, nil, 0);
end {if}
else begin
GenNative(m_lda_dir, direct, gLong.disp+6, nil, 0);
StoreWordOfQuad(6);
GenNative(m_lda_dir, direct, gLong.disp+4, nil, 0);
StoreWordOfQuad(4);
GenNative(m_lda_dir, direct, gLong.disp+2, nil, 0);
StoreWordOfQuad(2);
GenNative(m_lda_dir, direct, gLong.disp, nil, 0);
StoreWordOfQuad(0);
end; {else}
end {if} end {if}
else begin else begin
gQuad.where := onStack;
GenNative(m_ldx_imm, immediate, gLong.disp, nil, 0); GenNative(m_ldx_imm, immediate, gLong.disp, nil, 0);
GenNative(m_lda_dirX, direct, 6, nil, 0); GenNative(m_lda_dirX, direct, 6, nil, 0);
GenImplied(m_pha); GenImplied(m_pha);
@ -2894,6 +2979,7 @@ case optype of
GenImplied(m_pha); GenImplied(m_pha);
end {else} end {else}
else begin else begin
gQuad.where := onStack;
if (gLong.disp >= 250) or (gLong.disp < 0) then begin if (gLong.disp >= 250) or (gLong.disp < 0) then begin
GenImplied(m_txa); GenImplied(m_txa);
GenImplied(m_clc); GenImplied(m_clc);
@ -2916,26 +3002,27 @@ case optype of
if gLong.fixedDisp then if gLong.fixedDisp then
if smallMemoryModel then begin if smallMemoryModel then begin
GenNative(m_lda_abs, absolute, gLong.disp+6, gLong.lab, 0); GenNative(m_lda_abs, absolute, gLong.disp+6, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenNative(m_lda_abs, absolute, gLong.disp+4, gLong.lab, 0); GenNative(m_lda_abs, absolute, gLong.disp+4, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenNative(m_lda_abs, absolute, gLong.disp+2, gLong.lab, 0); GenNative(m_lda_abs, absolute, gLong.disp+2, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenNative(m_lda_abs, absolute, gLong.disp, gLong.lab, 0); GenNative(m_lda_abs, absolute, gLong.disp, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end {if} end {if}
else begin else begin
GenNative(m_lda_long, longAbs, gLong.disp+6, gLong.lab, 0); GenNative(m_lda_long, longAbs, gLong.disp+6, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenNative(m_lda_long, longAbs, gLong.disp+4, gLong.lab, 0); GenNative(m_lda_long, longAbs, gLong.disp+4, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenNative(m_lda_long, longAbs, gLong.disp+2, gLong.lab, 0); GenNative(m_lda_long, longAbs, gLong.disp+2, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenNative(m_lda_long, longAbs, gLong.disp, gLong.lab, 0); GenNative(m_lda_long, longAbs, gLong.disp, gLong.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
end {else} end {else}
else else
if smallMemoryModel then begin if smallMemoryModel then begin
gQuad.where := onStack;
GenNative(m_lda_absX, absolute, gLong.disp+6, gLong.lab, 0); GenNative(m_lda_absX, absolute, gLong.disp+6, gLong.lab, 0);
GenImplied(m_pha); GenImplied(m_pha);
GenNative(m_lda_absX, absolute, gLong.disp+4, gLong.lab, 0); GenNative(m_lda_absX, absolute, gLong.disp+4, gLong.lab, 0);
@ -2946,6 +3033,7 @@ case optype of
GenImplied(m_pha); GenImplied(m_pha);
end {if} end {if}
else begin else begin
gQuad.where := onStack;
GenNative(m_lda_longX, longAbs, gLong.disp+6, gLong.lab, 0); GenNative(m_lda_longX, longAbs, gLong.disp+6, gLong.lab, 0);
GenImplied(m_pha); GenImplied(m_pha);
GenNative(m_lda_longX, longAbs, gLong.disp+4, gLong.lab, 0); GenNative(m_lda_longX, longAbs, gLong.disp+4, gLong.lab, 0);
@ -2956,7 +3044,6 @@ case optype of
GenImplied(m_pha); GenImplied(m_pha);
end; {else} end; {else}
end; {else} end; {else}
gQuad.where := onStack;
end; {case cgQuad,cgUQuad} end; {case cgQuad,cgUQuad}
otherwise: Error(cge1); otherwise: Error(cge1);
end; {case} end; {case}
@ -3799,42 +3886,48 @@ case optype of
end; {case CGLong, cgULong} end; {case CGLong, cgULong}
cgQuad, cgUQuad: begin cgQuad, cgUQuad: begin
gQuad.preference := onStack; if opcode = pc_sro then begin
gQuad.preference := globalLabel;
gQuad.lab := lab;
gQuad.disp := q;
end {if}
else {if opcode = pc_cpo then}
gQuad.preference := onStack;
GenTree(op^.left); GenTree(op^.left);
if opcode = pc_sro then if gQuad.where = onStack then begin
GenImplied(m_pla) if opcode = pc_sro then
else {if opcode = pc_cpo then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 1, nil, 0); else {if opcode = pc_cpo then}
if smallMemoryModel then GenNative(m_lda_s, direct, 1, nil, 0);
GenNative(m_sta_abs, absolute, q, lab, 0) if smallMemoryModel then
else GenNative(m_sta_abs, absolute, q, lab, 0)
GenNative(m_sta_long, longabsolute, q, lab, 0); else
if opcode = pc_sro then GenNative(m_sta_long, longabsolute, q, lab, 0);
GenImplied(m_pla) if opcode = pc_sro then
else {if opcode = pc_cpo then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 3, nil, 0); else {if opcode = pc_cpo then}
if smallMemoryModel then GenNative(m_lda_s, direct, 3, nil, 0);
GenNative(m_sta_abs, absolute, q+2, lab, 0) if smallMemoryModel then
else GenNative(m_sta_abs, absolute, q+2, lab, 0)
GenNative(m_sta_long, longabsolute, q+2, lab, 0); else
if opcode = pc_sro then GenNative(m_sta_long, longabsolute, q+2, lab, 0);
GenImplied(m_pla) if opcode = pc_sro then
else {if opcode = pc_cpo then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 5, nil, 0); else {if opcode = pc_cpo then}
if smallMemoryModel then GenNative(m_lda_s, direct, 5, nil, 0);
GenNative(m_sta_abs, absolute, q+4, lab, 0) if smallMemoryModel then
else GenNative(m_sta_abs, absolute, q+4, lab, 0)
GenNative(m_sta_long, longabsolute, q+4, lab, 0); else
if opcode = pc_sro then GenNative(m_sta_long, longabsolute, q+4, lab, 0);
GenImplied(m_pla) if opcode = pc_sro then
else {if opcode = pc_cpo then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 7, nil, 0); else {if opcode = pc_cpo then}
if smallMemoryModel then GenNative(m_lda_s, direct, 7, nil, 0);
GenNative(m_sta_abs, absolute, q+6, lab, 0) if smallMemoryModel then
else GenNative(m_sta_abs, absolute, q+6, lab, 0)
GenNative(m_sta_long, longabsolute, q+6, lab, 0); else
if opcode = pc_cpo then GenNative(m_sta_long, longabsolute, q+6, lab, 0);
gQuad.where := onStack; end; {if}
end; {case cgQuad, cgUQuad} end; {case cgQuad, cgUQuad}
end; {case} end; {case}
end; {GenSroCpo} end; {GenSroCpo}
@ -3950,42 +4043,52 @@ case optype of
cgQuad,cgUQuad: begin cgQuad,cgUQuad: begin
gQuad.preference := onStack; gQuad.preference := onStack;
if opcode = pc_sto then
if op^.left^.opcode = pc_lod then begin
disp := LabelToDisp(op^.left^.r) + op^.left^.q;
if disp <= 255 then begin
gQuad.preference := inPointer;
gQuad.disp := disp;
end; {if}
end; {if}
GenTree(op^.right); GenTree(op^.right);
gLong.preference := A_X; if gQuad.where = onStack then begin
GenTree(op^.left); gLong.preference := A_X;
if gLong.where = onStack then begin GenTree(op^.left);
GenImplied(m_pla); if gLong.where = onStack then begin
GenImplied(m_plx); GenImplied(m_pla);
GenImplied(m_plx);
end; {if}
GenNative(m_sta_dir, direct, dworkLoc, nil, 0);
GenNative(m_stx_dir, direct, dworkLoc+2, nil, 0);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 1, nil, 0);
GenNative(m_sta_indl, direct, dworkLoc, nil, 0);
GenNative(m_ldy_imm, immediate, 2, nil, 0);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 3, nil, 0);
GenNative(m_sta_indly, direct, dworkLoc, nil, 0);
GenImplied(m_iny);
GenImplied(m_iny);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 5, nil, 0);
GenNative(m_sta_indly, direct, dworkLoc, nil, 0);
GenImplied(m_iny);
GenImplied(m_iny);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 7, nil, 0);
GenNative(m_sta_indly, direct, dworkLoc, nil, 0);
if op^.opcode = pc_cpi then
gQuad.where := onStack;
end; {if} end; {if}
GenNative(m_sta_dir, direct, dworkLoc, nil, 0);
GenNative(m_stx_dir, direct, dworkLoc+2, nil, 0);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 1, nil, 0);
GenNative(m_sta_indl, direct, dworkLoc, nil, 0);
GenNative(m_ldy_imm, immediate, 2, nil, 0);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 3, nil, 0);
GenNative(m_sta_indly, direct, dworkLoc, nil, 0);
GenImplied(m_iny);
GenImplied(m_iny);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 5, nil, 0);
GenNative(m_sta_indly, direct, dworkLoc, nil, 0);
GenImplied(m_iny);
GenImplied(m_iny);
if opcode = pc_sto then
GenImplied(m_pla)
else {if op^.opcode = pc_cpi then}
GenNative(m_lda_s, direct, 7, nil, 0);
GenNative(m_sta_indly, direct, dworkLoc, nil, 0);
if op^.opcode = pc_cpi then
gQuad.where := onStack;
end; {case cgQuad,cgUQuad} end; {case cgQuad,cgUQuad}
cgLong,cgULong: begin cgLong,cgULong: begin
@ -4486,55 +4589,60 @@ case optype of
end; end;
cgQuad, cgUQuad: begin cgQuad, cgUQuad: begin
gQuad.preference := onStack; if op^.opcode = pc_str then begin
gQuad.preference := localAddress;
gQuad.disp := disp;
end {if}
else {if op^.opcode = pc_cop then}
gQuad.preference := onStack;
GenTree(op^.left); GenTree(op^.left);
if disp < 250 then begin if gQuad.where = onStack then begin
if op^.opcode = pc_str then if disp < 250 then begin
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 1, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dir, direct, disp, nil, 0); GenNative(m_lda_s, direct, 1, nil, 0);
if op^.opcode = pc_str then GenNative(m_sta_dir, direct, disp, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 3, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dir, direct, disp+2, nil, 0); GenNative(m_lda_s, direct, 3, nil, 0);
if op^.opcode = pc_str then GenNative(m_sta_dir, direct, disp+2, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 5, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dir, direct, disp+4, nil, 0); GenNative(m_lda_s, direct, 5, nil, 0);
if op^.opcode = pc_str then GenNative(m_sta_dir, direct, disp+4, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 7, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dir, direct, disp+6, nil, 0); GenNative(m_lda_s, direct, 7, nil, 0);
end {else if} GenNative(m_sta_dir, direct, disp+6, nil, 0);
else begin end {else if}
GenNative(m_ldx_imm, immediate, disp, nil, 0); else begin
if op^.opcode = pc_str then GenNative(m_ldx_imm, immediate, disp, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 1, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dirX, direct, 0, nil, 0); GenNative(m_lda_s, direct, 1, nil, 0);
if op^.opcode = pc_str then GenNative(m_sta_dirX, direct, 0, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 3, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dirX, direct, 2, nil, 0); GenNative(m_lda_s, direct, 3, nil, 0);
if op^.opcode = pc_str then GenNative(m_sta_dirX, direct, 2, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 5, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dirX, direct, 4, nil, 0); GenNative(m_lda_s, direct, 5, nil, 0);
if op^.opcode = pc_str then GenNative(m_sta_dirX, direct, 4, nil, 0);
GenImplied(m_pla) if op^.opcode = pc_str then
else {if op^.opcode = pc_cop then} GenImplied(m_pla)
GenNative(m_lda_s, direct, 7, nil, 0); else {if op^.opcode = pc_cop then}
GenNative(m_sta_dirX, direct, 6, nil, 0); GenNative(m_lda_s, direct, 7, nil, 0);
end; {else} GenNative(m_sta_dirX, direct, 6, nil, 0);
if op^.opcode = pc_cop then end; {else}
gQuad.where := onStack; end; {if}
end; end;
otherwise: Error(cge1); otherwise: Error(cge1);
@ -5440,11 +5548,23 @@ procedure GenTree {op: icptr};
end; end;
cgQuad,cgUQuad: begin cgQuad,cgUQuad: begin
GenNative(m_pea, immediate, long(op^.qval.hi).msw, nil, 0); if gQuad.preference = onStack then begin
GenNative(m_pea, immediate, long(op^.qval.hi).lsw, nil, 0); GenNative(m_pea, immediate, long(op^.qval.hi).msw, nil, 0);
GenNative(m_pea, immediate, long(op^.qval.lo).msw, nil, 0); GenNative(m_pea, immediate, long(op^.qval.hi).lsw, nil, 0);
GenNative(m_pea, immediate, long(op^.qval.lo).lsw, nil, 0); GenNative(m_pea, immediate, long(op^.qval.lo).msw, nil, 0);
gQuad.where := onStack; GenNative(m_pea, immediate, long(op^.qval.lo).lsw, nil, 0);
end {if}
else begin
GenNative(m_lda_imm, immediate, long(op^.qval.hi).msw, nil, 0);
StoreWordOfQuad(6);
GenNative(m_lda_imm, immediate, long(op^.qval.hi).lsw, nil, 0);
StoreWordOfQuad(4);
GenNative(m_lda_imm, immediate, long(op^.qval.lo).msw, nil, 0);
StoreWordOfQuad(2);
GenNative(m_lda_imm, immediate, long(op^.qval.lo).lsw, nil, 0);
StoreWordOfQuad(0);
end; {else}
gQuad.where := gQuad.preference;
end; end;
otherwise: otherwise:
@ -5525,25 +5645,25 @@ procedure GenTree {op: icptr};
cgQuad, cgUQuad: begin cgQuad, cgUQuad: begin
if smallMemoryModel then begin if smallMemoryModel then begin
GenNative(m_lda_abs, absolute, op^.q+6, op^.lab, 0); GenNative(m_lda_abs, absolute, op^.q+6, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenNative(m_lda_abs, absolute, op^.q+4, op^.lab, 0); GenNative(m_lda_abs, absolute, op^.q+4, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenNative(m_lda_abs, absolute, op^.q+2, op^.lab, 0); GenNative(m_lda_abs, absolute, op^.q+2, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenNative(m_lda_abs, absolute, op^.q, op^.lab, 0); GenNative(m_lda_abs, absolute, op^.q, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end {if} end {if}
else begin else begin
GenNative(m_lda_long, longabsolute, op^.q+6, op^.lab, 0); GenNative(m_lda_long, longabsolute, op^.q+6, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(6);
GenNative(m_lda_long, longabsolute, op^.q+4, op^.lab, 0); GenNative(m_lda_long, longabsolute, op^.q+4, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(4);
GenNative(m_lda_long, longabsolute, op^.q+2, op^.lab, 0); GenNative(m_lda_long, longabsolute, op^.q+2, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(2);
GenNative(m_lda_long, longabsolute, op^.q, op^.lab, 0); GenNative(m_lda_long, longabsolute, op^.q, op^.lab, 0);
GenImplied(m_pha); StoreWordOfQuad(0);
end; {else} end; {else}
gQuad.where := onStack; gQuad.where := gQuad.preference;
end; {case cgQuad,cgUQuad} end; {case cgQuad,cgUQuad}
otherwise: otherwise:
@ -5610,14 +5730,27 @@ procedure GenTree {op: icptr};
GenImplied(m_pha); GenImplied(m_pha);
GenNative(m_lda_dirx, direct, 0, nil, 0); GenNative(m_lda_dirx, direct, 0, nil, 0);
GenImplied(m_pha); GenImplied(m_pha);
gQuad.where := onStack;
end {if} end {if}
else begin else begin
GenNative(m_pei_dir, direct, disp+6, nil, 0); if gQuad.preference = onStack then begin
GenNative(m_pei_dir, direct, disp+4, nil, 0); GenNative(m_pei_dir, direct, disp+6, nil, 0);
GenNative(m_pei_dir, direct, disp+2, nil, 0); GenNative(m_pei_dir, direct, disp+4, nil, 0);
GenNative(m_pei_dir, direct, disp, nil, 0); GenNative(m_pei_dir, direct, disp+2, nil, 0);
GenNative(m_pei_dir, direct, disp, nil, 0);
end {if}
else begin
GenNative(m_lda_dir, direct, disp+6, nil, 0);
StoreWordOfQuad(6);
GenNative(m_lda_dir, direct, disp+4, nil, 0);
StoreWordOfQuad(4);
GenNative(m_lda_dir, direct, disp+2, nil, 0);
StoreWordOfQuad(2);
GenNative(m_lda_dir, direct, disp, nil, 0);
StoreWordOfQuad(0);
end; {else}
gQuad.where := gQuad.preference;
end; {else} end; {else}
gQuad.where := onStack;
end; end;
cgLong, cgULong: begin cgLong, cgULong: begin