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

View File

@ -123,6 +123,10 @@ opt[pc_bnq] := 'bnq';
opt[pc_ngq] := 'ngq'; opt[pc_ngq] := 'ngq';
opt[pc_mpq] := 'mpq'; opt[pc_mpq] := 'mpq';
opt[pc_umq] := 'umq'; opt[pc_umq] := 'umq';
opt[pc_dvq] := 'dvq';
opt[pc_udq] := 'udq';
opt[pc_mdq] := 'mdq';
opt[pc_uqm] := 'uqm';
end; {InitWriteCode} 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, 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, 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, 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} {intermediate code}
{-----------------} {-----------------}

View File

@ -2267,7 +2267,8 @@ case op^.opcode of
pc_udl, pc_ulm, pc_uml, pc_vsr: pc_udl, pc_ulm, pc_uml, pc_vsr:
TypeOf := cgULong; 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; TypeOf := cgQuad;
pc_ngr, pc_adr, pc_dvr, pc_mpr, pc_sbr: 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_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_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_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 then begin
op^.parents := icount; op^.parents := icount;
icount := icount+1; 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_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_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_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 begin
code^.right := Pop; code^.right := Pop;
code^.left := Pop; code^.left := Pop;

View File

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

46
Gen.pas
View File

@ -4493,7 +4493,8 @@ procedure GenTree {op: icptr};
procedure GenBinQuad (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); procedure GenOp (ops: integer);
@ -4529,6 +4530,46 @@ procedure GenTree {op: icptr};
pc_umq: GenCall(80); 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); otherwise: Error(cge1);
end; {case} end; {case}
end; {GenBinQuad} end; {GenBinQuad}
@ -6133,7 +6174,8 @@ case op^.opcode of
pc_and,pc_bnd,pc_bor,pc_bxr,pc_ior: GenLogic(op); 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_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_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_bnl,pc_ngl: GenUnaryLong(op);
pc_bnq,pc_ngq: GenUnaryQuad(op); pc_bnq,pc_ngq: GenUnaryQuad(op);
pc_bno: GenBno(op); pc_bno: GenBno(op);

View File

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