|
@@ -40,6 +40,11 @@ interface
|
|
|
procedure emit_mod_reg_reg(signed: boolean;denum,num : tregister);override;
|
|
|
end;
|
|
|
|
|
|
+ tm68kshlshrnode = class(tshlshrnode)
|
|
|
+ procedure pass_2;override;
|
|
|
+ { everything will be handled in pass_2 }
|
|
|
+ function first_shlshr64bitint: tnode; override;
|
|
|
+ end;
|
|
|
|
|
|
|
|
|
implementation
|
|
@@ -179,12 +184,14 @@ implementation
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
procedure tm68kmoddivnode.emit_mod_reg_reg(signed: boolean;denum,num : tregister);
|
|
|
var tmpreg : tregister;
|
|
|
continuelabel : tasmlabel;
|
|
|
signlabel : tasmlabel;
|
|
|
reg_d0,reg_d1 : tregister;
|
|
|
begin
|
|
|
+// writeln('emit mod reg reg');
|
|
|
{ no RTL call, so inline a zero denominator verification }
|
|
|
if aktoptprocessor <> MC68000 then
|
|
|
begin
|
|
@@ -217,7 +224,7 @@ implementation
|
|
|
exprasmlist.concat(taicpu.op_reg_reg_reg(A_DIVUL,S_L,denum,tmpreg,num));
|
|
|
{ remainder in tmpreg }
|
|
|
cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,tmpreg,denum);
|
|
|
- cg.ungetcpuregister(exprasmlist,tmpreg);
|
|
|
+// cg.ungetcpuregister(exprasmlist,tmpreg);
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
@@ -238,11 +245,116 @@ implementation
|
|
|
cg.ungetcpuregister(exprasmlist,Reg_D0);
|
|
|
cg.ungetcpuregister(exprasmlist,Reg_D1);
|
|
|
end;
|
|
|
+// writeln('exits');
|
|
|
end;
|
|
|
|
|
|
|
|
|
+{*****************************************************************************
|
|
|
+ TM68KSHLRSHRNODE
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+ function tm68kShlShrNode.first_shlshr64bitint:TNode;
|
|
|
+ begin
|
|
|
+ { 2nd pass is our friend }
|
|
|
+ result := nil;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{$WARNING FIX ME!!! shlshrnode needs review}
|
|
|
+ procedure tm68kshlshrnode.pass_2;
|
|
|
+ var
|
|
|
+ hregister,resultreg,hregister1,
|
|
|
+ hreg64hi,hreg64lo : tregister;
|
|
|
+ op : topcg;
|
|
|
+ shiftval: aword;
|
|
|
+ begin
|
|
|
+ secondpass(left);
|
|
|
+ secondpass(right);
|
|
|
+ if is_64bit(left.resulttype.def) then
|
|
|
+ begin
|
|
|
+ location_reset(location,LOC_REGISTER,OS_64);
|
|
|
+
|
|
|
+ { load left operator in a register }
|
|
|
+ location_force_reg(exprasmlist,left.location,OS_64,false);
|
|
|
+ hreg64hi:=left.location.register64.reghi;
|
|
|
+ hreg64lo:=left.location.register64.reglo;
|
|
|
+
|
|
|
+ shiftval := tordconstnode(right).value and 63;
|
|
|
+ if shiftval > 31 then
|
|
|
+ begin
|
|
|
+ if nodetype = shln then
|
|
|
+ begin
|
|
|
+ cg.a_load_const_reg(exprasmlist,OS_32,0,hreg64hi);
|
|
|
+ if (shiftval and 31) <> 0 then
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHL,OS_32,shiftval and 31,hreg64lo,hreg64lo);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ cg.a_load_const_reg(exprasmlist,OS_32,0,hreg64lo);
|
|
|
+ if (shiftval and 31) <> 0 then
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHR,OS_32,shiftval and 31,hreg64hi,hreg64hi);
|
|
|
+ end;
|
|
|
+ location.register64.reglo:=hreg64hi;
|
|
|
+ location.register64.reghi:=hreg64lo;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ hregister:=cg.getintregister(exprasmlist,OS_32);
|
|
|
+ if nodetype = shln then
|
|
|
+ begin
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHR,OS_32,32-shiftval,hreg64lo,hregister);
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHL,OS_32,shiftval,hreg64hi,hreg64hi);
|
|
|
+ cg.a_op_reg_reg_reg(exprasmlist,OP_OR,OS_32,hregister,hreg64hi,hreg64hi);
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHL,OS_32,shiftval,hreg64lo,hreg64lo);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHL,OS_32,32-shiftval,hreg64hi,hregister);
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHR,OS_32,shiftval,hreg64lo,hreg64lo);
|
|
|
+ cg.a_op_reg_reg_reg(exprasmlist,OP_OR,OS_32,hregister,hreg64lo,hreg64lo);
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,OP_SHR,OS_32,shiftval,hreg64hi,hreg64hi);
|
|
|
+ end;
|
|
|
+ location.register64.reghi:=hreg64hi;
|
|
|
+ location.register64.reglo:=hreg64lo;
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ { load left operators in a register }
|
|
|
+ location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),true);
|
|
|
+ location_copy(location,left.location);
|
|
|
+ resultreg := location.register;
|
|
|
+ hregister1 := location.register;
|
|
|
+ if (location.loc = LOC_CREGISTER) then
|
|
|
+ begin
|
|
|
+ location.loc := LOC_REGISTER;
|
|
|
+ resultreg := cg.GetIntRegister(exprasmlist,OS_INT);
|
|
|
+ location.register := resultreg;
|
|
|
+ end;
|
|
|
+ { determine operator }
|
|
|
+ if nodetype=shln then
|
|
|
+ op:=OP_SHL
|
|
|
+ else
|
|
|
+ op:=OP_SHR;
|
|
|
+ { shifting by a constant directly coded: }
|
|
|
+ if (right.nodetype=ordconstn) then
|
|
|
+ begin
|
|
|
+ if tordconstnode(right).value and 31<>0 then
|
|
|
+ cg.a_op_const_reg_reg(exprasmlist,op,OS_32,tordconstnode(right).value and 31,hregister1,resultreg)
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ { load shift count in a register if necessary }
|
|
|
+ location_force_reg(exprasmlist,right.location,def_cgsize(right.resulttype.def),true);
|
|
|
+ cg.a_op_reg_reg_reg(exprasmlist,op,OS_32,right.location.register,hregister1,resultreg);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
begin
|
|
|
cnotnode:=tm68knotnode;
|
|
|
cmoddivnode:=tm68kmoddivnode;
|
|
|
+ cshlshrnode:=tm68kshlshrnode;
|
|
|
end.
|