mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 10:09:35 +01:00
* register fixes
This commit is contained in:
parent
92430d4881
commit
790e125329
@ -37,14 +37,6 @@ interface
|
||||
private
|
||||
function IsSimpleRef(const ref:treference):boolean;
|
||||
public
|
||||
{ This method is used to pass a parameter, which is located in a register, to a
|
||||
routine. It should give the parameter to the routine, as required by the
|
||||
specific processor ABI. It is overriden for each CPU target.
|
||||
Size : is the size of the operand in the register
|
||||
r : is the register source of the operand
|
||||
LocPara : is the location where the parameter will be stored }
|
||||
procedure a_param_reg(list:TAasmOutput;sz:tcgsize;r:tregister;const LocPara:TParaLocation);override;
|
||||
{ passes a parameter which is a constant to a function }
|
||||
procedure a_param_const(list:TAasmOutput;size:tcgsize;a:aword;const LocPara:TParaLocation);override;
|
||||
procedure a_param_ref(list:TAasmOutput;sz:tcgsize;const r:TReference;const LocPara:TParaLocation);override;
|
||||
procedure a_paramaddr_ref(list:TAasmOutput;const r:TReference;const LocPara:TParaLocation);override;
|
||||
@ -141,40 +133,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure TCgSparc.a_param_reg(list:TAasmOutput;sz:tcgsize;r:tregister;const LocPara:TParaLocation);
|
||||
var
|
||||
zeroreg:Tregister;
|
||||
begin
|
||||
zeroreg.enum:=R_INTREGISTER;
|
||||
zeroreg.number:=NR_G0;
|
||||
with list,LocPara do
|
||||
case Loc of
|
||||
LOC_REGISTER:
|
||||
begin
|
||||
case Sz of
|
||||
OS_8,OS_S8:
|
||||
Concat(taicpu.op_Reg_Const_Reg(A_AND,r,$FF,Register));
|
||||
OS_16,OS_S16:
|
||||
begin
|
||||
Concat(taicpu.op_Reg_Reg_Reg(A_AND,r,zeroreg,Register));
|
||||
{This will put 00...00111 in the hiest 22 bits of the reg}
|
||||
Concat(taicpu.op_Reg_Const_Reg(A_SETHI,Register,$7,Register));
|
||||
end;
|
||||
OS_32,OS_S32:
|
||||
begin
|
||||
if r.number<>Register.number then
|
||||
Concat(taicpu.op_Reg_Reg_Reg(A_OR,r,zeroreg,Register));
|
||||
end;
|
||||
else
|
||||
InternalError(2002032212);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
InternalError(2002101002);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCgSparc.a_param_const(list:TAasmOutput;size:tcgsize;a:aword;const LocPara:TParaLocation);
|
||||
var
|
||||
Ref:TReference;
|
||||
@ -203,7 +161,7 @@ implementation
|
||||
tmpreg:TRegister;
|
||||
begin
|
||||
with LocPara do
|
||||
case locpara.loc of
|
||||
case loc of
|
||||
LOC_REGISTER,LOC_CREGISTER:
|
||||
a_load_ref_reg(list,sz,r,Register);
|
||||
LOC_REFERENCE:
|
||||
@ -374,14 +332,14 @@ implementation
|
||||
|
||||
procedure TCgSparc.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
|
||||
var
|
||||
r : Tregister;
|
||||
zeroreg : Tregister;
|
||||
begin
|
||||
if(reg1.enum<>R_INTREGISTER)or(reg1.number=NR_NO) then
|
||||
InternalError(200303101);
|
||||
if(reg2.enum<>R_INTREGISTER)or(reg2.number=NR_NO) then
|
||||
InternalError(200303102);
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.Number:=NR_G0;
|
||||
zeroreg.enum:=R_INTREGISTER;
|
||||
zeroreg.Number:=NR_G0;
|
||||
if (reg1.Number<>reg2.Number) or
|
||||
(tcgsize2size[tosize]<tcgsize2size[fromsize]) or
|
||||
(
|
||||
@ -391,8 +349,19 @@ implementation
|
||||
) then
|
||||
begin
|
||||
case tosize of
|
||||
OS_8,OS_S8,OS_16,OS_S16,OS_32,OS_S32:
|
||||
list.concat(taicpu.op_reg_reg_reg(A_OR,r,reg1,reg2));
|
||||
OS_8,OS_S8:
|
||||
list.Concat(taicpu.op_Reg_Const_Reg(A_AND,reg1,$FF,reg2));
|
||||
OS_16,OS_S16:
|
||||
begin
|
||||
list.Concat(taicpu.op_Reg_Reg_Reg(A_AND,reg1,zeroreg,reg2));
|
||||
{ This will put 00...00111 in the highest 22 bits of the reg }
|
||||
list.Concat(taicpu.op_Reg_Const_Reg(A_SETHI,reg2,$7,reg2));
|
||||
end;
|
||||
OS_32,OS_S32:
|
||||
begin
|
||||
if reg1.number<>reg2.number then
|
||||
list.Concat(taicpu.op_Reg_Reg_Reg(A_OR,zeroreg,reg1,reg2));
|
||||
end;
|
||||
else
|
||||
internalerror(2002090901);
|
||||
end;
|
||||
@ -617,8 +586,8 @@ implementation
|
||||
|
||||
procedure TCgSparc.g_flags2reg(list:TAasmOutput;Size:TCgSize;const f:tresflags;reg:TRegister);
|
||||
var
|
||||
ai:taicpu;
|
||||
r,hreg:tregister;
|
||||
ai : taicpu;
|
||||
r : tregister;
|
||||
begin
|
||||
r.enum:=R_PSR;
|
||||
ai:=Taicpu.Op_reg_reg(A_RDPSR,r,reg);
|
||||
@ -831,11 +800,10 @@ implementation
|
||||
begin
|
||||
case op of
|
||||
OP_AND,OP_OR,OP_XOR:
|
||||
WITH cg DO
|
||||
begin
|
||||
a_op_const_reg(list,op,Lo(Value),regdst.reglo);
|
||||
a_op_const_reg(list,op,Hi(Value),regdst.reghi);
|
||||
end;
|
||||
begin
|
||||
cg.a_op_const_reg(list,op,Lo(Value),regdst.reglo);
|
||||
cg.a_op_const_reg(list,op,Hi(Value),regdst.reghi);
|
||||
end;
|
||||
OP_ADD, OP_SUB:
|
||||
begin
|
||||
{can't use a_op_const_ref because this may use dec/inc}
|
||||
@ -856,12 +824,11 @@ implementation
|
||||
begin
|
||||
case op of
|
||||
OP_AND,OP_OR,OP_XOR:
|
||||
with cg do
|
||||
begin
|
||||
a_op_const_ref(list,op,OS_32,Lo(Value),ref);
|
||||
cg.a_op_const_ref(list,op,OS_32,Lo(Value),ref);
|
||||
tempref:=ref;
|
||||
inc(tempref.offset,4);
|
||||
a_op_const_ref(list,op,OS_32,Hi(Value),tempref);
|
||||
cg.a_op_const_ref(list,op,OS_32,Hi(Value),tempref);
|
||||
end;
|
||||
OP_ADD, OP_SUB:
|
||||
begin
|
||||
@ -1053,7 +1020,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.53 2003-05-30 23:57:08 peter
|
||||
Revision 1.54 2003-05-31 01:00:51 peter
|
||||
* register fixes
|
||||
|
||||
Revision 1.53 2003/05/30 23:57:08 peter
|
||||
* more sparc cleanup
|
||||
* accumulator removed, splitted in function_return_reg (called) and
|
||||
function_result_reg (caller)
|
||||
|
||||
@ -324,38 +324,38 @@ uses
|
||||
|
||||
{Super registers:}
|
||||
RS_NO=$00;
|
||||
RS_O0=$01;
|
||||
RS_O1=$02;
|
||||
RS_O2=$03;
|
||||
RS_O3=$04;
|
||||
RS_O4=$05;
|
||||
RS_O5=$06;
|
||||
RS_O6=$07;
|
||||
RS_O7=$08;
|
||||
RS_L0=$09;
|
||||
RS_L1=$0A;
|
||||
RS_L2=$0B;
|
||||
RS_L3=$0C;
|
||||
RS_L4=$0D;
|
||||
RS_L5=$0E;
|
||||
RS_L6=$0F;
|
||||
RS_L7=$10;
|
||||
RS_I0=$11;
|
||||
RS_I1=$12;
|
||||
RS_I2=$13;
|
||||
RS_I3=$14;
|
||||
RS_I4=$15;
|
||||
RS_I5=$16;
|
||||
RS_I6=$17;
|
||||
RS_I7=$18;
|
||||
RS_G0=$19;
|
||||
RS_G1=$1A;
|
||||
RS_G2=$1B;
|
||||
RS_G3=$1C;
|
||||
RS_G4=$1D;
|
||||
RS_G5=$1E;
|
||||
RS_G6=$1F;
|
||||
RS_G7=$20;
|
||||
RS_G0=$01;
|
||||
RS_G1=$02;
|
||||
RS_G2=$03;
|
||||
RS_G3=$04;
|
||||
RS_G4=$05;
|
||||
RS_G5=$06;
|
||||
RS_G6=$07;
|
||||
RS_G7=$08;
|
||||
RS_O0=$09;
|
||||
RS_O1=$0a;
|
||||
RS_O2=$0b;
|
||||
RS_O3=$0c;
|
||||
RS_O4=$0d;
|
||||
RS_O5=$0e;
|
||||
RS_O6=$0f;
|
||||
RS_O7=$10;
|
||||
RS_L0=$11;
|
||||
RS_L1=$12;
|
||||
RS_L2=$13;
|
||||
RS_L3=$14;
|
||||
RS_L4=$15;
|
||||
RS_L5=$16;
|
||||
RS_L6=$17;
|
||||
RS_L7=$18;
|
||||
RS_I0=$19;
|
||||
RS_I1=$1a;
|
||||
RS_I2=$1b;
|
||||
RS_I3=$1c;
|
||||
RS_I4=$1d;
|
||||
RS_I5=$1e;
|
||||
RS_I6=$1f;
|
||||
RS_I7=$20;
|
||||
|
||||
first_supreg = $01;
|
||||
last_supreg = $20;
|
||||
@ -988,17 +988,12 @@ implementation
|
||||
|
||||
procedure convert_register_to_enum(var r:Tregister);
|
||||
begin
|
||||
with R do
|
||||
if(enum=R_INTREGISTER) then
|
||||
if(number<=RegEnum2Number[R_I7]) then
|
||||
begin
|
||||
enum:=Low(enum);
|
||||
repeat
|
||||
Inc(enum);
|
||||
until(number=RegEnum2Number[enum])or(enum=High(enum));
|
||||
end
|
||||
else
|
||||
if (r.enum=R_INTREGISTER) then
|
||||
begin
|
||||
if r.number>NR_I7 then
|
||||
internalerror(200301082);
|
||||
r.enum:=toldregister(r.number shr 8);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -1010,7 +1005,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.35 2003-05-30 23:57:08 peter
|
||||
Revision 1.36 2003-05-31 01:00:51 peter
|
||||
* register fixes
|
||||
|
||||
Revision 1.35 2003/05/30 23:57:08 peter
|
||||
* more sparc cleanup
|
||||
* accumulator removed, splitted in function_return_reg (called) and
|
||||
function_result_reg (caller)
|
||||
|
||||
@ -48,8 +48,6 @@ unit cpugas;
|
||||
begin
|
||||
inc(offset,offsetfixup);
|
||||
offsetfixup:=0;
|
||||
if (base.enum<>R_INTREGISTER) or (index.enum<>R_INTREGISTER) then
|
||||
internalerror(200301081);
|
||||
if assigned(symbol) then
|
||||
begin
|
||||
if (base.number<>NR_NO) or (index.number<>NR_NO) then
|
||||
@ -59,21 +57,34 @@ unit cpugas;
|
||||
GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
|
||||
else if offset<0 then
|
||||
GetReferenceString:=GetReferenceString+ToStr(offset);
|
||||
if symaddr=refs_hi then
|
||||
GetReferenceString:='%hi('+GetReferenceString+')'
|
||||
else if symaddr=refs_lo then
|
||||
GetReferenceString:='%lo('+GetReferenceString+')'
|
||||
else
|
||||
internalerror(2003052602);
|
||||
case symaddr of
|
||||
refs_hi :
|
||||
GetReferenceString:='%hi('+GetReferenceString+')';
|
||||
refs_lo :
|
||||
GetReferenceString:='%lo('+GetReferenceString+')';
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
GetReferenceString:='[';
|
||||
if base.number<>NR_NO then
|
||||
GetReferenceString:=std_reg2str[base.enum]+'+';
|
||||
GetReferenceString:=GetReferenceString+std_reg2str[base.enum];
|
||||
if index.number<>NR_NO then
|
||||
GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
|
||||
if Offset<>0 then
|
||||
internalerror(2003052603);
|
||||
begin
|
||||
if (Offset<-4096) or (Offset>4095) then
|
||||
internalerror(2003053008);
|
||||
if offset>0 then
|
||||
GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
|
||||
else if offset<0 then
|
||||
GetReferenceString:=GetReferenceString+ToStr(offset);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if Offset<>0 then
|
||||
internalerror(2003052603);
|
||||
GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
|
||||
end;
|
||||
GetReferenceString:=GetReferenceString+']';
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -140,10 +151,10 @@ unit cpugas;
|
||||
end;*)
|
||||
|
||||
procedure TGasSPARC.WriteInstruction(hp:Tai);
|
||||
var
|
||||
Op:TAsmOp;
|
||||
s:String;
|
||||
i:Integer;
|
||||
var
|
||||
Op:TAsmOp;
|
||||
s:String;
|
||||
i:Integer;
|
||||
begin
|
||||
if hp.typ<>ait_instruction then
|
||||
exit;
|
||||
@ -196,7 +207,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.16 2003-05-30 23:57:08 peter
|
||||
Revision 1.17 2003-05-31 01:00:51 peter
|
||||
* register fixes
|
||||
|
||||
Revision 1.16 2003/05/30 23:57:08 peter
|
||||
* more sparc cleanup
|
||||
* accumulator removed, splitted in function_return_reg (called) and
|
||||
function_result_reg (caller)
|
||||
|
||||
@ -72,6 +72,7 @@ implementation
|
||||
reference.index.number:=NR_FRAME_POINTER_REG;
|
||||
reference.offset:=-68-nr*4;
|
||||
end;
|
||||
size:=OS_INT;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -303,7 +304,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.17 2003-05-30 23:57:08 peter
|
||||
Revision 1.18 2003-05-31 01:00:51 peter
|
||||
* register fixes
|
||||
|
||||
Revision 1.17 2003/05/30 23:57:08 peter
|
||||
* more sparc cleanup
|
||||
* accumulator removed, splitted in function_return_reg (called) and
|
||||
function_result_reg (caller)
|
||||
|
||||
@ -43,7 +43,7 @@ function TRgCpu.GetExplicitRegisterInt(list:TAasmOutput;reg:TNewRegister):TRegis
|
||||
var
|
||||
r:TRegister;
|
||||
begin
|
||||
if(reg=RS_O7)or(reg=NR_I7)
|
||||
if(reg=NR_O7)or(reg=NR_I7)
|
||||
then
|
||||
begin
|
||||
r.enum:=R_INTREGISTER;
|
||||
@ -70,7 +70,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.9 2003-04-22 10:09:35 daniel
|
||||
Revision 1.10 2003-05-31 01:00:51 peter
|
||||
* register fixes
|
||||
|
||||
Revision 1.9 2003/04/22 10:09:35 daniel
|
||||
+ Implemented the actual register allocator
|
||||
+ Scratch registers unavailable when new register allocator used
|
||||
+ maybe_save/maybe_restore unavailable when new register allocator used
|
||||
|
||||
Loading…
Reference in New Issue
Block a user