mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 04:49:17 +02:00
* completed (not compilale yet though)
This commit is contained in:
parent
e41ba8650a
commit
c6d03a29f0
@ -55,7 +55,7 @@ implementation
|
|||||||
cgbase,cgobj,temp_gen,pass_1,pass_2,
|
cgbase,cgobj,temp_gen,pass_1,pass_2,
|
||||||
ncon,
|
ncon,
|
||||||
cpubase,
|
cpubase,
|
||||||
cga,tgcpu,nppcutil,cgcpu;
|
cga,tgcpu,nppcutil,cgcpu,cg64f32;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TPPCMODDIVNODE
|
TPPCMODDIVNODE
|
||||||
@ -118,7 +118,7 @@ implementation
|
|||||||
{ n = -13, (0xFFFF_FFF3), and k = 2, after executing the srawi }
|
{ n = -13, (0xFFFF_FFF3), and k = 2, after executing the srawi }
|
||||||
{ instruction, q = -4 (0xFFFF_FFFC) and CA = 1. After executing }
|
{ instruction, q = -4 (0xFFFF_FFFC) and CA = 1. After executing }
|
||||||
{ the addze instruction, q = -3, the correct quotient. }
|
{ the addze instruction, q = -3, the correct quotient. }
|
||||||
cg.a_op_reg_reg_reg(OP_SAR,power,numerator,resultreg);
|
cg.a_op_const_reg_reg(list,OP_SAR,OS_32,aword(power),numerator,resultreg);
|
||||||
exprasmlist.concat(taicpu.op_reg_reg(A_ADDZE,resultreg,resultreg));
|
exprasmlist.concat(taicpu.op_reg_reg(A_ADDZE,resultreg,resultreg));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -137,7 +137,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ needs overflow checking, (-maxlongint-1) div (-1) overflows! }
|
{ needs overflow checking, (-maxlongint-1) div (-1) overflows! }
|
||||||
{ (JM) }
|
{ And on PPC, the only way to catch a div-by-0 is by checking }
|
||||||
|
{ the overflow flag (JM) }
|
||||||
op := divops[is_signed(right.resulttype.def),
|
op := divops[is_signed(right.resulttype.def),
|
||||||
cs_check_overflow in aktlocalswitches];
|
cs_check_overflow in aktlocalswitches];
|
||||||
exprasmlist(taicpu.op_reg_reg_reg(op,resultreg,numerator,
|
exprasmlist(taicpu.op_reg_reg_reg(op,resultreg,numerator,
|
||||||
@ -163,9 +164,11 @@ implementation
|
|||||||
|
|
||||||
procedure tppcshlshrnode.pass_2;
|
procedure tppcshlshrnode.pass_2;
|
||||||
var
|
var
|
||||||
resultreg, hregister1,hregister2,hregister3,
|
resultreg, hregister1,hregister2,
|
||||||
hregisterhigh,hregisterlow : tregister;
|
hregisterhigh,hregisterlow : tregister;
|
||||||
op : topcg;
|
op : topcg;
|
||||||
|
asmop1, asmop2: tasmop;
|
||||||
|
shiftval: aword;
|
||||||
saved : boolean;
|
saved : boolean;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -177,7 +180,135 @@ implementation
|
|||||||
|
|
||||||
if is_64bitint(left.resulttype.def) then
|
if is_64bitint(left.resulttype.def) then
|
||||||
begin
|
begin
|
||||||
{ see green book appendix E, still needs to be implemented }
|
case left.location.loc of
|
||||||
|
LOC_REGISTER, LOC_CREGISTER:
|
||||||
|
begin
|
||||||
|
hregisterhigh := left.location.registerhigh;
|
||||||
|
hregisterlow := left.location.registerlow;
|
||||||
|
if left.location.loc = LOC_REGISTER then
|
||||||
|
begin
|
||||||
|
location.registerhigh := hregisterhigh;
|
||||||
|
location.registerlow := hregisterlow
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
location.registerhigh := getregisterint;
|
||||||
|
location.registerlow := getregisterint;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
LOC_REFERENCE,LOC_MEM:
|
||||||
|
begin
|
||||||
|
{ !!!!!!!! not good, registers are release too soon this way !!!! (JM) }
|
||||||
|
del_reference(left.location.reference);
|
||||||
|
hregisterhigh := getregisterint;
|
||||||
|
location.registerhigh := hregisterhigh;
|
||||||
|
hregisterlow := getregisterint;
|
||||||
|
location.registerlow := hregisterlow;
|
||||||
|
tcg64f32(cg).a_load64_ref_reg(list,left.location.reference,
|
||||||
|
hregisterlow,hregisterhigh);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (right.nodetype = ordconstn) then
|
||||||
|
begin
|
||||||
|
if tordconstnode(right).value > 31 then
|
||||||
|
begin
|
||||||
|
if nodetype = shln then
|
||||||
|
begin
|
||||||
|
if (value and 31) <> 0 then
|
||||||
|
cg.a_op_const_reg_reg(exprasmlist,OP_SHL,OS_32,value and 31,
|
||||||
|
hregisterlow,location.registerhigh)
|
||||||
|
cg.a_load_const_reg(exprasmlist,OS_32,0,location.registerlow);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (value and 31) <> 0 then
|
||||||
|
cg.a_op_const_reg_reg(exprasmlist,OP_SHR,OS_32,value and 31,
|
||||||
|
hregisterhigh,location.registerlow);
|
||||||
|
cg.a_load_const_reg(exprasmlist,OS_32,0,location.registerhigh);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
shiftval := aword(tordconstnode(right).value;
|
||||||
|
if nodetype = shln then
|
||||||
|
begin
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
|
||||||
|
A_RLWINM,location.registerhigh,hregisterhigh,shiftval,
|
||||||
|
0,31-shiftval));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
|
||||||
|
A_RLWIMI,location.registerhigh,hregisterlow,shiftval,
|
||||||
|
32-shiftval,31));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
|
||||||
|
A_RLWINM,location.registerlow,hregisterlow,shiftval,
|
||||||
|
0,31-shiftval));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
|
||||||
|
A_RLWINM,location.registerlow,hregisterlow,32-shiftval,
|
||||||
|
shiftval,31));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
|
||||||
|
A_RLWIMI,location.registerlow,hregisterhigh,32-shiftval,
|
||||||
|
0,shiftval-1));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
|
||||||
|
A_RLWINM,location.registerhigh,hregisterhigh,32-shiftval,
|
||||||
|
shiftval,31));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ no constant shiftcount }
|
||||||
|
begin
|
||||||
|
case right.location.loc of
|
||||||
|
LOC_REGISTER,LOC_CREGISTER:
|
||||||
|
begin
|
||||||
|
hregister1 := right.location.register;
|
||||||
|
end;
|
||||||
|
LOC_REFERENCE,LOC_MEM:
|
||||||
|
begin
|
||||||
|
hregister1 := get_scratch_reg(exprasmlist);
|
||||||
|
cg.a_load_ref_reg(exprasmlist,OS_S32,
|
||||||
|
right.location.reference,hregister1);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if nodetype = shln then
|
||||||
|
begin
|
||||||
|
asmop1 := A_SLW;
|
||||||
|
asmop2 := A_SRW;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
asmop1 := A_SRW;
|
||||||
|
asmop2 := A_SLW;
|
||||||
|
resultreg := location.registerhigh;
|
||||||
|
location.registerhigh := location.registerlow;
|
||||||
|
location.registerlow := resultreg;
|
||||||
|
end;
|
||||||
|
|
||||||
|
getexplicitregisterint(R_0);
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,
|
||||||
|
R_0,hregister1,32));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_reg(asmop1,
|
||||||
|
location.registerhigh,hregisterhigh,hregister1));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_reg(asmop2,
|
||||||
|
R_0,hregisterlow,R_0));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_reg(A_OR,
|
||||||
|
location.registerhigh,location.registerhigh,R_0));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBI,
|
||||||
|
R_0,hregister1,32));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_reg(asmop1,
|
||||||
|
R_0,hregisterlow,R_0));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_reg(A_OR,
|
||||||
|
location.registerhigh,location.registerhigh,R_0));
|
||||||
|
exprasmlist.concat(taicpu.op_reg_reg_reg(asmop1,
|
||||||
|
location.registerlow,hregisterlow,hregister1));
|
||||||
|
ungetregister(R_0);
|
||||||
|
|
||||||
|
if right.location.loc in [LOC_MEM,LOC_REFERENCE] then
|
||||||
|
free_scratch_reg(exprasmlist,hregister1)
|
||||||
|
else
|
||||||
|
ungetregister(hregister1);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -480,7 +611,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.1 2001-12-29 15:28:58 jonas
|
Revision 1.2 2002-01-03 14:57:52 jonas
|
||||||
|
* completed (not compilale yet though)
|
||||||
|
|
||||||
|
Revision 1.1 2001/12/29 15:28:58 jonas
|
||||||
* powerpc/cgcpu.pas compiles :)
|
* powerpc/cgcpu.pas compiles :)
|
||||||
* several powerpc-related fixes
|
* several powerpc-related fixes
|
||||||
* cpuasm unit is now based on common tainst unit
|
* cpuasm unit is now based on common tainst unit
|
||||||
|
Loading…
Reference in New Issue
Block a user