* completed (not compilale yet though)

This commit is contained in:
Jonas Maebe 2002-01-03 14:57:52 +00:00
parent e41ba8650a
commit c6d03a29f0

View File

@ -55,7 +55,7 @@ implementation
cgbase,cgobj,temp_gen,pass_1,pass_2,
ncon,
cpubase,
cga,tgcpu,nppcutil,cgcpu;
cga,tgcpu,nppcutil,cgcpu,cg64f32;
{*****************************************************************************
TPPCMODDIVNODE
@ -118,7 +118,7 @@ implementation
{ n = -13, (0xFFFF_FFF3), and k = 2, after executing the srawi }
{ instruction, q = -4 (0xFFFF_FFFC) and CA = 1. After executing }
{ 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));
end
else
@ -137,7 +137,8 @@ implementation
end;
{ 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),
cs_check_overflow in aktlocalswitches];
exprasmlist(taicpu.op_reg_reg_reg(op,resultreg,numerator,
@ -163,9 +164,11 @@ implementation
procedure tppcshlshrnode.pass_2;
var
resultreg, hregister1,hregister2,hregister3,
resultreg, hregister1,hregister2,
hregisterhigh,hregisterlow : tregister;
op : topcg;
asmop1, asmop2: tasmop;
shiftval: aword;
saved : boolean;
begin
@ -177,7 +180,135 @@ implementation
if is_64bitint(left.resulttype.def) then
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
else
begin
@ -480,7 +611,10 @@ begin
end.
{
$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 :)
* several powerpc-related fixes
* cpuasm unit is now based on common tainst unit