Implement 64-bit division and remainder, signed and unsigned.

These operations rely on new library routines in ORCALib (~CDIV8 and ~UDIV8).
This commit is contained in:
Stephen Heumann 2021-02-05 12:42:48 -06:00
parent 08cf7a0181
commit 05868667b2
7 changed files with 80 additions and 6 deletions

View File

@ -275,12 +275,16 @@
{ pc_udi - unsigned integer divide }
{ pc_dvl - long integer divide }
{ pc_udl - unsigned long divide }
{ pc_dvq - long long integer divide }
{ pc_udq - unsigned long long divide }
{ pc_dvr - real divide }
{ }
{ Gen0(pc_dvi) cgByte,cgWord }
{ Gen0(pc_udi) cgUByte,cgUWord }
{ Gen0(pc_dvl) cgLong }
{ Gen0(pc_udl) cgULong }
{ Gen0(pc_dvq) cgQuad }
{ Gen0(pc_udq) cgUQuad }
{ Gen0(pc_dvr) cgReal,cgDouble,cgComp,cgExtended }
{ }
{ The two values on the top of the evaluation stack are }
@ -464,11 +468,15 @@
{ pc_uim - unsigned integer modulus/remainder }
{ pc_mdl - long remainder }
{ pc_ulm - unsigned long modulus/remainder }
{ pc_mdq - long long remainder }
{ pc_uqm - unsigned long long modulus/remainder }
{ }
{ Gen0(pc_mod) cgByte,cgWord }
{ Gen0(pc_uim) cgUByte,cgUWord }
{ Gen0(pc_mdl) cgLong }
{ Gen0(pc_ulm) cgULong }
{ Gen0(pc_mdq) cgQuad }
{ Gen0(pc_uqm) cgUQuad }
{ }
{ The two values on the top of the evaluation stack are }
{ removed and the remainder after division is calculated. }

View File

@ -123,6 +123,10 @@ opt[pc_bnq] := 'bnq';
opt[pc_ngq] := 'ngq';
opt[pc_mpq] := 'mpq';
opt[pc_umq] := 'umq';
opt[pc_dvq] := 'dvq';
opt[pc_udq] := 'udq';
opt[pc_mdq] := 'mdq';
opt[pc_uqm] := 'uqm';
end; {InitWriteCode}

View File

@ -229,7 +229,8 @@ type
dc_sym,pc_lnd,pc_lor,pc_vsr,pc_uml,pc_udl,pc_ulm,pc_pop,pc_gil,
pc_gli,pc_gdl,pc_gld,pc_cpi,pc_tri,pc_lbu,pc_lbf,pc_sbf,pc_cbf,dc_cns,
dc_prm,pc_nat,pc_bno,pc_nop,pc_psh,pc_ili,pc_iil,pc_ild,pc_idl,
pc_bqr,pc_bqx,pc_baq,pc_bnq,pc_ngq,pc_adq,pc_sbq,pc_mpq,pc_umq);
pc_bqr,pc_bqx,pc_baq,pc_bnq,pc_ngq,pc_adq,pc_sbq,pc_mpq,pc_umq,pc_dvq,
pc_udq,pc_mdq,pc_uqm);
{intermediate code}
{-----------------}

View File

@ -2267,7 +2267,8 @@ case op^.opcode of
pc_udl, pc_ulm, pc_uml, pc_vsr:
TypeOf := cgULong;
pc_bnq, pc_ngq, pc_bqr, pc_bqx, pc_baq, pc_adq, pc_sbq, pc_mpq, pc_umq:
pc_bnq, pc_ngq, pc_bqr, pc_bqx, pc_baq, pc_adq, pc_sbq, pc_mpq,
pc_umq, pc_dvq, pc_udq, pc_mdq, pc_uqm:
TypeOf := cgQuad;
pc_ngr, pc_adr, pc_dvr, pc_mpr, pc_sbr:
@ -4064,7 +4065,7 @@ var
pc_ngl,pc_ngr,pc_not,pc_pop,pc_sbi,pc_sbl,pc_sbr,
pc_shl,pc_sll,pc_shr,pc_usr,pc_slr,pc_vsr,pc_tri,
pc_bqr,pc_bqx,pc_baq,pc_bnq,pc_ngq,pc_adq,pc_sbq,
pc_mpq,pc_umq]
pc_mpq,pc_umq,pc_dvq,pc_udq,pc_mdq,pc_uqm]
then begin
op^.parents := icount;
icount := icount+1;
@ -4945,7 +4946,7 @@ case code^.opcode of
pc_ulm, pc_mpi, pc_umi, pc_mpl, pc_uml, pc_mpr, pc_psh, pc_sbi,
pc_sbl, pc_sbr, pc_shl, pc_sll, pc_shr, pc_usr, pc_slr, pc_vsr,
pc_tri, pc_sbf, pc_sto, pc_cui, pc_bqr, pc_bqx, pc_baq, pc_adq,
pc_sbq, pc_mpq, pc_umq:
pc_sbq, pc_mpq, pc_umq, pc_dvq, pc_udq, pc_mdq, pc_uqm:
begin
code^.right := Pop;
code^.left := Pop;

View File

@ -3160,6 +3160,10 @@ case tree^.token.kind of
Gen0(pc_dvl)
else if et = cgULong then
Gen0(pc_udl)
else if et = cgQuad then
Gen0(pc_dvq)
else if et = cgUQuad then
Gen0(pc_udq)
else if et = cgExtended then
Gen0(pc_dvr)
else
@ -3174,6 +3178,10 @@ case tree^.token.kind of
Gen0(pc_mdl)
else if et = cgULong then
Gen0(pc_ulm)
else if et = cgQuad then
Gen0(pc_mdq)
else if et = cgUQuad then
Gen0(pc_uqm)
else
Error(66);
@ -3586,6 +3594,10 @@ case tree^.token.kind of
Gen0(pc_dvl);
cgULong:
Gen0(pc_udl);
cgQuad:
Gen0(pc_dvq);
cgUQuad:
Gen0(pc_udq);
cgExtended:
Gen0(pc_dvr);
otherwise:
@ -3610,6 +3622,10 @@ case tree^.token.kind of
Gen0(pc_mdl);
cgULong:
Gen0(pc_ulm);
cgQuad:
Gen0(pc_mdq);
cgUQuad:
Gen0(pc_uqm);
otherwise:
error(66);
end; {case}

46
Gen.pas
View File

@ -4493,7 +4493,8 @@ procedure GenTree {op: icptr};
procedure GenBinQuad (op: icptr);
{ generate one of: pc_bqr, pc_bqx, pc_baq }
{ generate one of: pc_bqr, pc_bqx, pc_baq, pc_mpq, pc_umq, }
{ pc_dvq, pc_udq, pc_mdq, pc_uqm }
procedure GenOp (ops: integer);
@ -4529,6 +4530,46 @@ procedure GenTree {op: icptr};
pc_umq: GenCall(80);
pc_dvq: begin
GenCall(81); {do division}
GenImplied(m_pla); {get quotient, discarding remainder}
GenNative(m_sta_s, direct, 7, nil, 0);
GenImplied(m_pla);
GenNative(m_sta_s, direct, 7, nil, 0);
GenImplied(m_pla);
GenNative(m_sta_s, direct, 7, nil, 0);
GenImplied(m_pla);
GenNative(m_sta_s, direct, 7, nil, 0);
end;
pc_udq: begin
GenCall(82); {do division}
GenImplied(m_pla); {get quotient, discarding remainder}
GenNative(m_sta_s, direct, 7, nil, 0);
GenImplied(m_pla);
GenNative(m_sta_s, direct, 7, nil, 0);
GenImplied(m_pla);
GenNative(m_sta_s, direct, 7, nil, 0);
GenImplied(m_pla);
GenNative(m_sta_s, direct, 7, nil, 0);
end;
pc_mdq: begin
GenCall(81); {do division}
GenImplied(m_tsc); {discard quotient, leaving remainder}
GenImplied(m_clc);
GenNative(m_adc_imm, immediate, 8, nil, 0);
GenImplied(m_tcs);
end;
pc_uqm: begin
GenCall(82); {do division}
GenImplied(m_tsc); {discard quotient, leaving remainder}
GenImplied(m_clc);
GenNative(m_adc_imm, immediate, 8, nil, 0);
GenImplied(m_tcs);
end;
otherwise: Error(cge1);
end; {case}
end; {GenBinQuad}
@ -6133,7 +6174,8 @@ case op^.opcode of
pc_and,pc_bnd,pc_bor,pc_bxr,pc_ior: GenLogic(op);
pc_blr,pc_blx,pc_bal,pc_dvl,pc_mdl,pc_mpl,pc_sll,pc_slr,pc_udl,pc_ulm,
pc_uml,pc_vsr: GenBinLong(op);
pc_bqr,pc_bqx,pc_baq,pc_mpq,pc_umq: GenBinQuad(op);
pc_bqr,pc_bqx,pc_baq,pc_mpq,pc_umq,pc_dvq,pc_udq,pc_mdq,pc_uqm:
GenBinQuad(op);
pc_bnl,pc_ngl: GenUnaryLong(op);
pc_bnq,pc_ngq: GenUnaryQuad(op);
pc_bno: GenBno(op);

View File

@ -2035,6 +2035,8 @@ case callNum of
78: sp := @'~DIV4'; {CC}
79: sp := @'~MUL8';
80: sp := @'~UMUL8';
81: sp := @'~CDIV8';
82: sp := @'~UDIV8';
otherwise:
Error(cge1);
end; {case}