* x86_64 uses generic concatcopy_valueopenarray for now

This commit is contained in:
florian 2004-02-22 16:48:09 +00:00
parent ec8c16f871
commit 0c35b6f3c4
3 changed files with 124 additions and 115 deletions

View File

@ -44,6 +44,7 @@ unit cgcpu;
class function reg_cgsize(const reg: tregister): tcgsize; override;
procedure g_save_all_registers(list : taasmoutput);override;
procedure g_restore_all_registers(list : taasmoutput;const funcretparaloc:tparalocation);override;
procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);override;
end;
tcg64f386 = class(tcg64f32)
@ -62,7 +63,6 @@ unit cgcpu;
symdef,symsym,defutil,paramgr,procinfo,
rgcpu,rgx86,tgobj;
procedure Tcg386.init_register_allocators;
begin
inherited init_register_allocators;
@ -147,6 +147,111 @@ unit cgcpu;
list.concat(taicpu.op_none(A_NOP,S_L));
end;
procedure tcg386.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);
var
power,len : longint;
opsize : topsize;
{$ifndef __NOWINPECOFF__}
again,ok : tasmlabel;
{$endif}
begin
{ get stack space }
getexplicitregister(list,NR_EDI);
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,NR_EDI));
list.concat(Taicpu.op_reg(A_INC,S_L,NR_EDI));
if (elesize<>1) then
begin
if ispowerof2(elesize, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_EDI))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,NR_EDI));
end;
{$ifndef __NOWINPECOFF__}
{ windows guards only a few pages for stack growing, }
{ so we have to access every page first }
if target_info.system=system_i386_win32 then
begin
objectlibrary.getlabel(again);
objectlibrary.getlabel(ok);
a_label(list,again);
list.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,NR_EDI));
a_jmp_cond(list,OC_B,ok);
list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,NR_ESP));
list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EDI));
list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,NR_EDI));
a_jmp_always(list,again);
a_label(list,ok);
list.concat(Taicpu.op_reg_reg(A_SUB,S_L,NR_EDI,NR_ESP));
ungetregister(list,NR_EDI);
{ now reload EDI }
getexplicitregister(list,NR_EDI);
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,NR_EDI));
list.concat(Taicpu.op_reg(A_INC,S_L,NR_EDI));
if (elesize<>1) then
begin
if ispowerof2(elesize, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_EDI))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,NR_EDI));
end;
end
else
{$endif __NOWINPECOFF__}
list.concat(Taicpu.op_reg_reg(A_SUB,S_L,NR_EDI,NR_ESP));
{ align stack on 4 bytes }
list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,NR_ESP));
{ load destination }
a_load_reg_reg(list,OS_INT,OS_INT,NR_ESP,NR_EDI);
{ Allocate other registers }
getexplicitregister(list,NR_ECX);
getexplicitregister(list,NR_ESI);
{ load count }
a_load_ref_reg(list,OS_INT,OS_INT,lenref,NR_ECX);
{ load source }
a_load_ref_reg(list,OS_INT,OS_INT,ref,NR_ESI);
{ scheduled .... }
list.concat(Taicpu.op_reg(A_INC,S_L,NR_ECX));
{ calculate size }
len:=elesize;
opsize:=S_B;
if (len and 3)=0 then
begin
opsize:=S_L;
len:=len shr 2;
end
else
if (len and 1)=0 then
begin
opsize:=S_W;
len:=len shr 1;
end;
if ispowerof2(len, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_ECX))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,len,NR_ECX));
list.concat(Taicpu.op_none(A_REP,S_NO));
case opsize of
S_B : list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
S_W : list.concat(Taicpu.Op_none(A_MOVSW,S_NO));
S_L : list.concat(Taicpu.Op_none(A_MOVSL,S_NO));
end;
ungetregister(list,NR_EDI);
ungetregister(list,NR_ECX);
ungetregister(list,NR_ESI);
{ patch the new address }
a_load_reg_ref(list,OS_INT,OS_INT,NR_ESP,ref);
end;
{ ************* 64bit operations ************ }
@ -283,7 +388,10 @@ begin
end.
{
$Log$
Revision 1.45 2004-02-04 22:01:13 peter
Revision 1.46 2004-02-22 16:48:09 florian
* x86_64 uses generic concatcopy_valueopenarray for now
Revision 1.45 2004/02/04 22:01:13 peter
* first try to get cpupara working for x86_64
Revision 1.44 2004/01/14 23:39:05 florian

View File

@ -274,6 +274,7 @@ implementation
ON 64-BIT SYSTEMS: SINCE PROCSYM FOR METHODS
CONSISTS OF TWO OS_ADDR, so you cannot set it
to OS_64 - how to solve?? Carl
Solved. Florian
}
if (sizeof(aword) = 4) then
location_reset(location,LOC_CREFERENCE,OS_64)
@ -905,7 +906,10 @@ begin
end.
{
$Log$
Revision 1.110 2004-02-22 16:30:37 florian
Revision 1.111 2004-02-22 16:48:09 florian
* x86_64 uses generic concatcopy_valueopenarray for now
Revision 1.110 2004/02/22 16:30:37 florian
* fixed
+ second_cmpfloatsse
@ -1351,4 +1355,4 @@ end.
* bugfix of hdisponen (base must be set, not index)
* more portability fixes
}
}

View File

@ -116,7 +116,6 @@ unit cgx86;
procedure g_exception_reason_load(list : taasmoutput; const href : treference);override;
{ entry/exit code helpers }
procedure g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);override;
procedure g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);override;
procedure g_interrupt_stackframe_entry(list : taasmoutput);override;
procedure g_interrupt_stackframe_exit(list : taasmoutput;accused,acchiused:boolean);override;
@ -159,6 +158,10 @@ unit cgx86;
S_NO,S_NO,S_NO,S_MD,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
{$endif x86_64}
{$ifndef NOTARGETWIN32}
winstackpagesize = 4096;
{$endif NOTARGETWIN32}
implementation
@ -166,11 +169,7 @@ unit cgx86;
globtype,globals,verbose,systems,cutils,
symdef,defutil,paramgr,tgobj,procinfo;
{$ifndef NOTARGETWIN32}
const
winstackpagesize = 4096;
{$endif NOTARGETWIN32}
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_ADD,A_AND,A_DIV,
A_IDIV,A_MUL, A_IMUL, A_NEG,A_NOT,A_OR,
A_SAR,A_SHL,A_SHR,A_SUB,A_XOR);
@ -1500,111 +1499,6 @@ unit cgx86;
Entry/Exit Code Helpers
****************************************************************************}
procedure tcgx86.g_copyvaluepara_openarray(list : taasmoutput;const ref, lenref:treference;elesize:aword);
var
power,len : longint;
opsize : topsize;
{$ifndef __NOWINPECOFF__}
again,ok : tasmlabel;
{$endif}
begin
{ get stack space }
getexplicitregister(list,NR_EDI);
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,NR_EDI));
list.concat(Taicpu.op_reg(A_INC,S_L,NR_EDI));
if (elesize<>1) then
begin
if ispowerof2(elesize, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_EDI))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,NR_EDI));
end;
{$ifndef __NOWINPECOFF__}
{ windows guards only a few pages for stack growing, }
{ so we have to access every page first }
if target_info.system=system_i386_win32 then
begin
objectlibrary.getlabel(again);
objectlibrary.getlabel(ok);
a_label(list,again);
list.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,NR_EDI));
a_jmp_cond(list,OC_B,ok);
list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,NR_ESP));
list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EDI));
list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,NR_EDI));
a_jmp_always(list,again);
a_label(list,ok);
list.concat(Taicpu.op_reg_reg(A_SUB,S_L,NR_EDI,NR_ESP));
ungetregister(list,NR_EDI);
{ now reload EDI }
getexplicitregister(list,NR_EDI);
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,NR_EDI));
list.concat(Taicpu.op_reg(A_INC,S_L,NR_EDI));
if (elesize<>1) then
begin
if ispowerof2(elesize, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_EDI))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,NR_EDI));
end;
end
else
{$endif __NOWINPECOFF__}
list.concat(Taicpu.op_reg_reg(A_SUB,S_L,NR_EDI,NR_ESP));
{ align stack on 4 bytes }
list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,NR_ESP));
{ load destination }
a_load_reg_reg(list,OS_INT,OS_INT,NR_ESP,NR_EDI);
{ Allocate other registers }
getexplicitregister(list,NR_ECX);
getexplicitregister(list,NR_ESI);
{ load count }
a_load_ref_reg(list,OS_INT,OS_INT,lenref,NR_ECX);
{ load source }
a_load_ref_reg(list,OS_INT,OS_INT,ref,NR_ESI);
{ scheduled .... }
list.concat(Taicpu.op_reg(A_INC,S_L,NR_ECX));
{ calculate size }
len:=elesize;
opsize:=S_B;
if (len and 3)=0 then
begin
opsize:=S_L;
len:=len shr 2;
end
else
if (len and 1)=0 then
begin
opsize:=S_W;
len:=len shr 1;
end;
if ispowerof2(len, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,NR_ECX))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,len,NR_ECX));
list.concat(Taicpu.op_none(A_REP,S_NO));
case opsize of
S_B : list.concat(Taicpu.Op_none(A_MOVSB,S_NO));
S_W : list.concat(Taicpu.Op_none(A_MOVSW,S_NO));
S_L : list.concat(Taicpu.Op_none(A_MOVSL,S_NO));
end;
ungetregister(list,NR_EDI);
ungetregister(list,NR_ECX);
ungetregister(list,NR_ESI);
{ patch the new address }
a_load_reg_ref(list,OS_INT,OS_INT,NR_ESP,ref);
end;
procedure tcgx86.g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);
begin
{ Nothing to release }
@ -1887,7 +1781,10 @@ unit cgx86;
end.
{
$Log$
Revision 1.112 2004-02-21 19:46:37 florian
Revision 1.113 2004-02-22 16:48:10 florian
* x86_64 uses generic concatcopy_valueopenarray for now
Revision 1.112 2004/02/21 19:46:37 florian
* OP_SH* code generation fixed
Revision 1.111 2004/02/20 16:01:49 peter