* SPARC calling mechanism almost OK (as in GCC./mppcsparc )

This commit is contained in:
mazen 2002-11-10 19:07:45 +00:00
parent 3a78921639
commit f97aa452bd
8 changed files with 94 additions and 95 deletions

View File

@ -1315,7 +1315,6 @@ implementation
{ move register parameters which aren't regable into memory }
{ we do this after init_paras because it saves some code in init_paras if parameters are in register }
{ instead in memory }
{$IFNDEF SPARC}
hp:=tparaitem(procinfo.procdef.para.first);
while assigned(hp) do
begin
@ -1353,7 +1352,6 @@ implementation
end;
hp:=tparaitem(hp.next);
end;
{$ENDIF SPARC}
end;
if (not inlined) then
@ -1848,7 +1846,10 @@ implementation
end.
{
$Log$
Revision 1.57 2002-11-03 20:22:40 mazen
Revision 1.58 2002-11-10 19:07:45 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.57 2002/11/03 20:22:40 mazen
* parameter handling updated
Revision 1.56 2002/10/16 19:01:43 peter

View File

@ -31,7 +31,6 @@ uses
const
MaxPrefixes=4;
type
TOperandOrder=(op_intel,op_att);
{ alignment for operator }
tai_align=class(tai_align_abstract)
reg:tregister;
@ -46,15 +45,13 @@ type
constructor op_const(op:tasmop;_op1:aword);
constructor op_ref(op:tasmop;const _op1:treference);
constructor op_reg_reg(op:tasmop;_op1,_op2:tregister);
constructor op_reg_ref(op:tasmop;_op1:tregister;const _op2:treference);
constructor op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
constructor op_reg_const(op:tasmop;_op1:tregister;_op2:aword);
constructor op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
constructor op_ref_reg(op:tasmop;const _op1:treference;_op2:tregister);
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
constructor op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:tregister);
constructor op_reg_ref_reg(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference;_op3:TRegister);
constructor op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
constructor op_reg_const_reg(Op:TAsmOp;SrcReg:TRegister;value:aWord;DstReg:TRegister);
constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
@ -72,7 +69,6 @@ type
procedure loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
procedure loadraddr(opidx:longint;rg1,rg2:TRegister);
private
FOperandOrder:TOperandOrder;
procedure init(_size:topsize);{this need to be called by all constructor}
public
{ the next will reset all instructions that can change in pass 2 }
@ -80,7 +76,6 @@ type
procedure ResetPass2;
function CheckIfValid:boolean;
function Pass1(offset:longint):longint;virtual;
procedure SetOperandOrder(order:TOperandOrder);
private
{ next fields are filled in pass1, so pass2 is faster }
insentry : PInsEntry;
@ -153,10 +148,7 @@ procedure taicpu.changeopsize(siz:topsize);
end;
procedure taicpu.init(_size:topsize);
begin
{ default order is att }
FOperandOrder:=op_att;
{segprefix:=R_NONE;}{This may be only for I386 architecture!}
opsize:=_size;
opsize:=_size;
end;
constructor taicpu.op_none(op:tasmop);
begin
@ -200,13 +192,16 @@ constructor taicpu.op_reg_const(op:tasmop;_op1:tregister; _op2:aword);
loadreg(0,_op1);
loadconst(1,_op2);
end;
constructor taicpu.op_reg_ref(op:tasmop;_op1:tregister;const _op2:treference);
constructor taicpu.op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
begin
inherited create(op);
init(_size);
ops:=2;
loadreg(0,_op1);
loadref(1,_op2);
if not(Op in [A_STB..A_STDFQ])
then
fail;
inherited Create(Op);
init(_size);
ops:=2;
LoadReg(0,Reg);
LoadRef(1,Ref);
end;
constructor taicpu.op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
begin
@ -216,13 +211,16 @@ constructor taicpu.op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
loadconst(0,_op1);
loadreg(1,_op2);
end;
constructor taicpu.op_ref_reg(op:tasmop;const _op1:treference;_op2:tregister);
constructor TAiCpu.op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
begin
inherited create(op);
init(S_SW);
ops:=2;
loadref(0,_op1);
loadreg(1,_op2);
if not(Op in [A_JMPL,A_FLUSH,A_LDSB..A_LDDC,A_RETT,A_SWAP])
then
fail;
inherited Create(Op);
Init(S_SW);
Ops:=2;
LoadRef(0,Ref);
LoadReg(1,Reg);
end;
constructor taicpu.op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
begin
@ -241,23 +239,14 @@ constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
loadreg(1,_op2);
loadreg(2,_op3);
end;
CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:TRegister);
BEGIN
INHERITED create(op);
init(_size);
ops:=3;
LoadReg(0,_op1);
LoadConst(1,_op2);
LoadReg(2,_op3);
END;
constructor taicpu.op_reg_ref_reg(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference;_op3:tregister);
constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
begin
inherited create(op);
init(_size);
inherited Create(Op);
Init(S_W);
ops:=3;
LoadReg(0,_op1);
LoadRef(1,_op2);
LoadReg(2,_op3);
LoadReg(0,SrcReg);
LoadConst(1,Value);
LoadReg(2,DstReg);
end;
constructor taicpu.op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
begin
@ -421,18 +410,6 @@ procedure taicpu.Swatoperands;
end;
end;
end;
procedure taicpu.SetOperandOrder(order:TOperandOrder);
begin
if FOperandOrder<>order then
begin
Swatoperands;
FOperandOrder:=order;
end;
end;
{ This check must be done with the operand in ATT order
i.e.after swapping in the intel reader
but before swapping in the NASM and TASM writers PM }
@ -711,8 +688,6 @@ begin
optimize }
if (Insentry=nil) or ((InsEntry^.flags and IF_PASS2)<>0) then
begin
{ We need intel style operands }
SetOperandOrder(op_intel);
{ create the .ot fields }
create_ot;
{ set the file postion }
@ -1138,7 +1113,10 @@ procedure InitAsm;
end.
{
$Log$
Revision 1.11 2002-11-06 11:31:24 mazen
Revision 1.12 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.11 2002/11/06 11:31:24 mazen
* op_reg_reg_reg don't need any more a TOpSize parameter
Revision 1.10 2002/11/05 16:15:00 mazen

View File

@ -122,7 +122,7 @@ procedure emit_reg_reg(i:tasmop;s:topsize;reg1,reg2:tregister);
end;
procedure emit_const_reg_reg(i:tasmop;s:topsize;c:longint;reg1,reg2:tregister);
begin
exprasmList.concat(Taicpu.Op_reg_const_reg(i,S_L,reg1,c,reg2));
exprasmList.concat(Taicpu.Op_reg_const_reg(i,reg1,c,reg2));
end;
procedure emit_reg_reg_reg(i:tasmop;s:topsize;reg1,reg2,reg3:tregister);
begin
@ -135,7 +135,10 @@ procedure emit_sym(i:tasmop;s:topsize;op:tasmsymbol);
end.
{
$Log$
Revision 1.4 2002-11-06 11:31:24 mazen
Revision 1.5 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.4 2002/11/06 11:31:24 mazen
* op_reg_reg_reg don't need any more a TOpSize parameter
Revision 1.3 2002/10/22 13:43:01 mazen

View File

@ -28,7 +28,6 @@ USES
node,symconst;
TYPE
tcgSPARC=CLASS(tcg)
FreeParamRegSet:TRegisterSet;
{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.
@ -212,7 +211,7 @@ procedure tcgSPARC.a_load_const_reg(list:TAasmOutput;size:TCGSize;a:aword;reg:TR
WITH List DO
IF a<>0
THEN{R_G0 is usually set to zero, so we use it}
Concat(taicpu.op_reg_const_reg(A_OR,TCGSize2OpSize[size],R_G0,a,reg))
Concat(taicpu.op_reg_const_reg(A_OR,R_G0,a,reg))
ELSE{The is no A_MOV in sparc, that's why we use A_OR with help of R_G0}
Concat(taicpu.op_reg_reg_reg(A_OR,R_G0,R_G0,reg));
END;
@ -668,7 +667,7 @@ procedure tcgSPARC.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegiste
ispowerof2(a,power) then
{ can be done with a shift }
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
list.concat(taicpu.op_reg_const_reg(A_SMUL,S_SW,src,a,dst));
list.concat(taicpu.op_reg_const_reg(A_SMUL,src,a,dst));
end;
OP_ADD, OP_SUB:
if (a = 0) then
@ -822,7 +821,7 @@ stack frame. In the "SAVE %i6,size,%i6" the first %i6 is related to the state
before execution of the SAVE instrucion so it is the caller %i6, when the %i6
after execution of that instruction is the called function stack pointer}
with list do
concat(Taicpu.Op_reg_const_reg(A_SAVE,S_SW,Stack_Pointer_Reg,LocalSize,Stack_Pointer_Reg));
concat(Taicpu.Op_reg_const_reg(A_SAVE,Stack_Pointer_Reg,LocalSize,Stack_Pointer_Reg));
end;
procedure tcgSPARC.g_restore_frame_pointer(list:TAasmOutput);
begin
@ -847,7 +846,7 @@ If no inversion we can use just
concat(Taicpu.Op_caddr_reg(A_JMPL,R_I7,8,R_G0));
{We use trivial restore in the delay slot of the JMPL instruction, as we
already set result onto %i0}
concat(Taicpu.Op_reg_const_reg(A_RESTORE,S_SW,R_G0,0,R_G0));
concat(Taicpu.Op_reg_const_reg(A_RESTORE,R_G0,0,R_G0));
end
end;
procedure tcgSPARC.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tregister);
@ -1053,8 +1052,8 @@ procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;le
{ easy to notice in the generated assembler }
inc(dst.offset,8);
inc(src.offset,8);
list.concat(taicpu.op_reg_const_reg(A_SUB,S_SW,src.base,8,src.base));
list.concat(taicpu.op_reg_const_reg(A_SUB,S_SW,dst.base,8,dst.base));
list.concat(taicpu.op_reg_const_reg(A_SUB,src.base,8,src.base));
list.concat(taicpu.op_reg_const_reg(A_SUB,dst.base,8,dst.base));
countreg := get_scratch_reg_int(list);
a_load_const_reg(list,OS_32,count,countreg);
{ explicitely allocate R_O0 since it can be used safely here }
@ -1062,7 +1061,7 @@ procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;le
a_reg_alloc(list,R_F0);
objectlibrary.getlabel(lab);
a_label(list, lab);
list.concat(taicpu.op_reg_const_reg(A_SUB,S_SW,countreg,1,countreg));
list.concat(taicpu.op_reg_const_reg(A_SUB,countreg,1,countreg));
list.concat(taicpu.op_reg_ref(A_LDF,R_F0,src));
list.concat(taicpu.op_reg_ref(A_STD,R_F0,dst));
//a_jmp(list,A_BC,C_NE,0,lab);
@ -1254,7 +1253,10 @@ BEGIN
END.
{
$Log$
Revision 1.22 2002-11-06 11:31:24 mazen
Revision 1.23 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.22 2002/11/06 11:31:24 mazen
* op_reg_reg_reg don't need any more a TOpSize parameter
Revision 1.21 2002/11/05 16:15:00 mazen

View File

@ -160,7 +160,6 @@ procedure TGasSPARC.WriteInstruction(hp:Tai);
if hp.typ<>ait_instruction
then
Exit;
taicpu(hp).SetOperandOrder(op_att);
op:=taicpu(hp).opcode;
{call maybe not translated to call}
s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
@ -210,7 +209,10 @@ initialization
end.
{
$Log$
Revision 1.8 2002-10-25 19:37:53 mazen
Revision 1.9 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.8 2002/10/25 19:37:53 mazen
* bug of references name missing last character fixed
Revision 1.7 2002/10/20 19:01:38 mazen

View File

@ -72,9 +72,9 @@ procedure TSparcProcInfo.after_pass1;
else
procdef.localst.address_fixup:=6*4+(16+1)*4;
procinfo.firsttemp_offset:=procdef.localst.address_fixup+procdef.localst.datasize;
WriteLn('Parameter copies start at: %i6-'+tostr(procdef.parast.address_fixup));
WriteLn('Locals start at: %o6-'+tostr(procdef.localst.address_fixup));
WriteLn('Temp. space start: %o6-'+tostr(procinfo.firsttemp_offset));
WriteLn('Parameter copies start at: %i6+'+tostr(procdef.parast.address_fixup));
WriteLn('Locals start at: %o6+'+tostr(procdef.localst.address_fixup));
WriteLn('Temp. space start: %o6+'+tostr(procinfo.firsttemp_offset));
tg.firsttemp:=procinfo.firsttemp_offset;
tg.lasttemp:=procinfo.firsttemp_offset;
end;
@ -83,7 +83,10 @@ begin
end.
{
$Log$
Revision 1.5 2002-11-03 20:22:40 mazen
Revision 1.6 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.5 2002/11/03 20:22:40 mazen
* parameter handling updated
Revision 1.4 2002/10/20 19:01:38 mazen

View File

@ -122,7 +122,7 @@ procedure TSparcAddNode.left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
begin
{maybe we can reuse a constant register when the operation is a comparison that
doesn't change the value of the register}
location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype IN [ltn,lten,gtn,gten,equaln,unequaln]));
location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
end;
end;
procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extra_not,mboverflow:Boolean);
@ -181,9 +181,10 @@ procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extr
end
ELSE IF(op=A_ADD)AND(right.location.loc=LOC_CONSTANT)AND(right.location.value=1)AND NOT(cs_check_overflow in aktlocalswitches)
THEN
begin
emit_reg(A_INC,opsize,left.location.register);
end
with ExprAsmList,left.location do
begin
concat(TAiCpu.op_reg_const_reg(A_ADD,register,1,register));
end
ELSE IF(op=A_SUB)AND(right.location.loc=LOC_CONSTANT)AND(right.location.value=1)AND NOT(cs_check_overflow in aktlocalswitches)
THEN
begin
@ -236,14 +237,17 @@ procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extr
procedure TSparcAddNode.emit_op_right_left(op:TAsmOp);
begin
{left must be a register}
with exprasmlist do
case right.location.loc of
with left,location,exprasmlist do
case Right.Location.Loc of
LOC_REGISTER,LOC_CREGISTER:
concat(taicpu.op_reg_reg_reg(op,right.location.register,left.location.register,left.location.register));
concat(taicpu.op_reg_reg_reg(op,Register,Right.Location.register,register));
LOC_REFERENCE,LOC_CREFERENCE :
concat(taicpu.op_reg_ref_reg(op,S_W,left.location.register,right.location.reference,left.location.register));
begin
location_force_reg(exprasmlist,Right.Location,OS_32,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
concat(taicpu.op_reg_reg_reg(op,register,Right.Location.register,register));
end;
LOC_CONSTANT:
concat(taicpu.op_reg_const_reg(op,S_W,left.location.register,right.location.value,left.location.register));
concat(taicpu.op_reg_const_reg(op,register,Right.Location.value,register));
else
InternalError(200203232);
end;
@ -404,7 +408,10 @@ begin
end.
{
$Log$
Revision 1.8 2002-11-06 15:34:00 mazen
Revision 1.9 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.8 2002/11/06 15:34:00 mazen
*** empty log message ***
Revision 1.7 2002/11/06 11:31:24 mazen

View File

@ -236,13 +236,13 @@ implementation
internalerror(200110012);
end;
tempreg := cg.get_scratch_reg_int(exprasmlist);
{$WARNING FIXME what reallty should be done?}
exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,S_L,tempreg,$4330,tempreg));
{$WARNING FIXME what really should be done?}
exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,tempreg,$4330,tempreg));
cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
cg.free_scratch_reg(exprasmlist,tempreg);
if signed then
{$WARNING FIXME what reallty should be done?}
exprasmlist.concat(taicpu.op_reg_const_reg(A_XOR,S_L,leftreg,$8000,valuereg));
{$WARNING FIXME what really should be done?}
exprasmlist.concat(taicpu.op_reg_const_reg(A_XOR,leftreg,$8000,valuereg));
inc(ref.offset,4);
cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref);
dec(ref.offset,4);
@ -262,7 +262,7 @@ implementation
tempconst.free;
location.register := rg.getregisterfpu(exprasmlist);
{$WARNING FIXME what reallty should be done?}
{$WARNING FIXME what really should be done?}
exprasmlist.concat(taicpu.op_reg_ref(A_LD,location.register,ref));
tg.ungetiftemp(exprasmlist,ref);
@ -273,7 +273,7 @@ implementation
{ work around bug in some PowerPC processors }
if (tfloatdef(resulttype.def).typ = s32real) then
{$WARNING FIXME what reallty should be done?}
{$WARNING FIXME what really should be done?}
exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
end;
@ -285,7 +285,7 @@ implementation
{ properly converted to singles }
if (tfloatdef(left.resulttype.def).typ = s64real) and
(tfloatdef(resulttype.def).typ = s32real) then
{$WARNING FIXME what reallty should be done?}
{$WARNING FIXME what really should be done?}
exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
end;
@ -323,7 +323,7 @@ implementation
else
hreg2 := left.location.register;
hreg1 := rg.getregisterint(exprasmlist);
exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,S_L,hreg1,1,
exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,hreg1,1,
hreg2));
exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,hreg1,hreg1,hreg2));
rg.ungetregister(exprasmlist,hreg2);
@ -420,7 +420,10 @@ begin
end.
{
$Log$
Revision 1.6 2002-11-06 11:31:24 mazen
Revision 1.7 2002-11-10 19:07:46 mazen
* SPARC calling mechanism almost OK (as in GCC./mppcsparc )
Revision 1.6 2002/11/06 11:31:24 mazen
* op_reg_reg_reg don't need any more a TOpSize parameter
Revision 1.5 2002/10/22 13:43:01 mazen