|
@@ -1168,14 +1168,22 @@ unit cgx86;
|
|
|
|
|
|
|
|
|
|
procedure tcgx86.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);
|
|
procedure tcgx86.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);
|
|
|
|
+ var
|
|
|
|
+ tmpref : treference;
|
|
begin
|
|
begin
|
|
- floatload(list,fromsize,ref);
|
|
|
|
|
|
+ tmpref:=ref;
|
|
|
|
+ make_simple_ref(list,tmpref);
|
|
|
|
+ floatload(list,fromsize,tmpref);
|
|
a_loadfpu_reg_reg(list,fromsize,tosize,NR_ST,reg);
|
|
a_loadfpu_reg_reg(list,fromsize,tosize,NR_ST,reg);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure tcgx86.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);
|
|
procedure tcgx86.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);
|
|
|
|
+ var
|
|
|
|
+ tmpref : treference;
|
|
begin
|
|
begin
|
|
|
|
+ tmpref:=ref;
|
|
|
|
+ make_simple_ref(list,tmpref);
|
|
{ in case a record returned in a floating point register
|
|
{ in case a record returned in a floating point register
|
|
(LOC_FPUREGISTER with OS_F32/OS_F64) is stored in memory
|
|
(LOC_FPUREGISTER with OS_F32/OS_F64) is stored in memory
|
|
(LOC_REFERENCE with OS_32/OS_64), we have to adjust the
|
|
(LOC_REFERENCE with OS_32/OS_64), we have to adjust the
|
|
@@ -1190,7 +1198,7 @@ unit cgx86;
|
|
end;
|
|
end;
|
|
if reg<>NR_ST then
|
|
if reg<>NR_ST then
|
|
a_loadfpu_reg_reg(list,fromsize,tosize,reg,NR_ST);
|
|
a_loadfpu_reg_reg(list,fromsize,tosize,reg,NR_ST);
|
|
- floatstore(list,tosize,ref);
|
|
|
|
|
|
+ floatstore(list,tosize,tmpref);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -2308,6 +2316,10 @@ unit cgx86;
|
|
saved_ds,saved_es: Boolean;
|
|
saved_ds,saved_es: Boolean;
|
|
|
|
|
|
begin
|
|
begin
|
|
|
|
+ srcref:=source;
|
|
|
|
+ dstref:=dest;
|
|
|
|
+ make_simple_ref(list,srcref);
|
|
|
|
+ make_simple_ref(list,dstref);
|
|
cm:=copy_move;
|
|
cm:=copy_move;
|
|
helpsize:=3*sizeof(aword);
|
|
helpsize:=3*sizeof(aword);
|
|
if cs_opt_size in current_settings.optimizerswitches then
|
|
if cs_opt_size in current_settings.optimizerswitches then
|
|
@@ -2345,15 +2357,13 @@ unit cgx86;
|
|
not(len in copy_len_sizes) then
|
|
not(len in copy_len_sizes) then
|
|
cm:=copy_string;
|
|
cm:=copy_string;
|
|
{$ifndef i8086}
|
|
{$ifndef i8086}
|
|
- if (source.segment<>NR_NO) or
|
|
|
|
- (dest.segment<>NR_NO) then
|
|
|
|
|
|
+ if (srcref.segment<>NR_NO) or
|
|
|
|
+ (dstref.segment<>NR_NO) then
|
|
cm:=copy_string;
|
|
cm:=copy_string;
|
|
{$endif not i8086}
|
|
{$endif not i8086}
|
|
case cm of
|
|
case cm of
|
|
copy_move:
|
|
copy_move:
|
|
begin
|
|
begin
|
|
- dstref:=dest;
|
|
|
|
- srcref:=source;
|
|
|
|
copysize:=sizeof(aint);
|
|
copysize:=sizeof(aint);
|
|
cgsize:=int_cgsize(copysize);
|
|
cgsize:=int_cgsize(copysize);
|
|
while len<>0 do
|
|
while len<>0 do
|
|
@@ -2394,8 +2404,6 @@ unit cgx86;
|
|
|
|
|
|
copy_mmx:
|
|
copy_mmx:
|
|
begin
|
|
begin
|
|
- dstref:=dest;
|
|
|
|
- srcref:=source;
|
|
|
|
r0:=getmmxregister(list);
|
|
r0:=getmmxregister(list);
|
|
r1:=NR_NO;
|
|
r1:=NR_NO;
|
|
r2:=NR_NO;
|
|
r2:=NR_NO;
|
|
@@ -2439,8 +2447,6 @@ unit cgx86;
|
|
|
|
|
|
copy_mm:
|
|
copy_mm:
|
|
begin
|
|
begin
|
|
- dstref:=dest;
|
|
|
|
- srcref:=source;
|
|
|
|
r0:=NR_NO;
|
|
r0:=NR_NO;
|
|
r1:=NR_NO;
|
|
r1:=NR_NO;
|
|
r2:=NR_NO;
|
|
r2:=NR_NO;
|
|
@@ -2492,8 +2498,6 @@ unit cgx86;
|
|
|
|
|
|
copy_avx:
|
|
copy_avx:
|
|
begin
|
|
begin
|
|
- dstref:=dest;
|
|
|
|
- srcref:=source;
|
|
|
|
r0:=NR_NO;
|
|
r0:=NR_NO;
|
|
r1:=NR_NO;
|
|
r1:=NR_NO;
|
|
r2:=NR_NO;
|
|
r2:=NR_NO;
|
|
@@ -2502,61 +2506,45 @@ unit cgx86;
|
|
begin
|
|
begin
|
|
r0:=getmmregister(list,OS_M128);
|
|
r0:=getmmregister(list,OS_M128);
|
|
{ we want to force the use of vmovups, so do not use a_loadmm_ref_reg }
|
|
{ we want to force the use of vmovups, so do not use a_loadmm_ref_reg }
|
|
- tmpref:=srcref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_ref_reg(A_VMOVUPS,S_NO,tmpref,r0));
|
|
|
|
|
|
+ list.concat(taicpu.op_ref_reg(A_VMOVUPS,S_NO,srcref,r0));
|
|
inc(srcref.offset,16);
|
|
inc(srcref.offset,16);
|
|
end;
|
|
end;
|
|
if len>=32 then
|
|
if len>=32 then
|
|
begin
|
|
begin
|
|
r1:=getmmregister(list,OS_M128);
|
|
r1:=getmmregister(list,OS_M128);
|
|
- tmpref:=srcref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_ref_reg(A_VMOVUPS,S_NO,tmpref,r1));
|
|
|
|
|
|
+ list.concat(taicpu.op_ref_reg(A_VMOVUPS,S_NO,srcref,r1));
|
|
inc(srcref.offset,16);
|
|
inc(srcref.offset,16);
|
|
end;
|
|
end;
|
|
if len>=48 then
|
|
if len>=48 then
|
|
begin
|
|
begin
|
|
r2:=getmmregister(list,OS_M128);
|
|
r2:=getmmregister(list,OS_M128);
|
|
- tmpref:=srcref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_ref_reg(A_VMOVUPS,S_NO,tmpref,r2));
|
|
|
|
|
|
+ list.concat(taicpu.op_ref_reg(A_VMOVUPS,S_NO,srcref,r2));
|
|
inc(srcref.offset,16);
|
|
inc(srcref.offset,16);
|
|
end;
|
|
end;
|
|
if (len=8) or (len=24) or (len=40) then
|
|
if (len=8) or (len=24) or (len=40) then
|
|
begin
|
|
begin
|
|
r3:=getmmregister(list,OS_M64);
|
|
r3:=getmmregister(list,OS_M64);
|
|
- tmpref:=srcref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_ref_reg(A_VMOVSD,S_NO,tmpref,r3));
|
|
|
|
|
|
+ list.concat(taicpu.op_ref_reg(A_VMOVSD,S_NO,srcref,r3));
|
|
end;
|
|
end;
|
|
|
|
|
|
if len>=16 then
|
|
if len>=16 then
|
|
begin
|
|
begin
|
|
- tmpref:=dstref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_reg_ref(A_VMOVUPS,S_NO,r0,tmpref));
|
|
|
|
|
|
+ list.concat(taicpu.op_reg_ref(A_VMOVUPS,S_NO,r0,dstref));
|
|
inc(dstref.offset,16);
|
|
inc(dstref.offset,16);
|
|
end;
|
|
end;
|
|
if len>=32 then
|
|
if len>=32 then
|
|
begin
|
|
begin
|
|
- tmpref:=dstref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_reg_ref(A_VMOVUPS,S_NO,r1,tmpref));
|
|
|
|
|
|
+ list.concat(taicpu.op_reg_ref(A_VMOVUPS,S_NO,r1,dstref));
|
|
inc(dstref.offset,16);
|
|
inc(dstref.offset,16);
|
|
end;
|
|
end;
|
|
if len>=48 then
|
|
if len>=48 then
|
|
begin
|
|
begin
|
|
- tmpref:=dstref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_reg_ref(A_VMOVUPS,S_NO,r2,tmpref));
|
|
|
|
|
|
+ list.concat(taicpu.op_reg_ref(A_VMOVUPS,S_NO,r2,dstref));
|
|
inc(dstref.offset,16);
|
|
inc(dstref.offset,16);
|
|
end;
|
|
end;
|
|
if (len=8) or (len=24) or (len=40) then
|
|
if (len=8) or (len=24) or (len=40) then
|
|
begin
|
|
begin
|
|
- tmpref:=dstref;
|
|
|
|
- make_simple_ref(list,tmpref);
|
|
|
|
- list.concat(taicpu.op_reg_ref(A_VMOVSD,S_NO,r3,tmpref));
|
|
|
|
|
|
+ list.concat(taicpu.op_reg_ref(A_VMOVSD,S_NO,r3,dstref));
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
else {copy_string, should be a good fallback in case of unhandled}
|
|
else {copy_string, should be a good fallback in case of unhandled}
|
|
@@ -2565,7 +2553,7 @@ unit cgx86;
|
|
if (dest.segment=NR_NO) and
|
|
if (dest.segment=NR_NO) and
|
|
(segment_regs_equal(NR_SS,NR_DS) or ((dest.base<>NR_BP) and (dest.base<>NR_SP))) then
|
|
(segment_regs_equal(NR_SS,NR_DS) or ((dest.base<>NR_BP) and (dest.base<>NR_SP))) then
|
|
begin
|
|
begin
|
|
- a_loadaddr_ref_reg(list,dest,REGDI);
|
|
|
|
|
|
+ a_loadaddr_ref_reg(list,dstref,REGDI);
|
|
saved_es:=false;
|
|
saved_es:=false;
|
|
{$ifdef volatile_es}
|
|
{$ifdef volatile_es}
|
|
list.concat(taicpu.op_reg(A_PUSH,push_segment_size,NR_DS));
|
|
list.concat(taicpu.op_reg(A_PUSH,push_segment_size,NR_DS));
|
|
@@ -2574,7 +2562,6 @@ unit cgx86;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- dstref:=dest;
|
|
|
|
dstref.segment:=NR_NO;
|
|
dstref.segment:=NR_NO;
|
|
a_loadaddr_ref_reg(list,dstref,REGDI);
|
|
a_loadaddr_ref_reg(list,dstref,REGDI);
|
|
{$ifdef volatile_es}
|
|
{$ifdef volatile_es}
|
|
@@ -2595,14 +2582,12 @@ unit cgx86;
|
|
if ((source.segment=NR_NO) and (segment_regs_equal(NR_SS,NR_DS) or ((source.base<>NR_BP) and (source.base<>NR_SP)))) or
|
|
if ((source.segment=NR_NO) and (segment_regs_equal(NR_SS,NR_DS) or ((source.base<>NR_BP) and (source.base<>NR_SP)))) or
|
|
(is_segment_reg(source.segment) and segment_regs_equal(source.segment,NR_DS)) then
|
|
(is_segment_reg(source.segment) and segment_regs_equal(source.segment,NR_DS)) then
|
|
begin
|
|
begin
|
|
- srcref:=source;
|
|
|
|
srcref.segment:=NR_NO;
|
|
srcref.segment:=NR_NO;
|
|
a_loadaddr_ref_reg(list,srcref,REGSI);
|
|
a_loadaddr_ref_reg(list,srcref,REGSI);
|
|
saved_ds:=false;
|
|
saved_ds:=false;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
- srcref:=source;
|
|
|
|
srcref.segment:=NR_NO;
|
|
srcref.segment:=NR_NO;
|
|
a_loadaddr_ref_reg(list,srcref,REGSI);
|
|
a_loadaddr_ref_reg(list,srcref,REGSI);
|
|
list.concat(taicpu.op_reg(A_PUSH,push_segment_size,NR_DS));
|
|
list.concat(taicpu.op_reg(A_PUSH,push_segment_size,NR_DS));
|