From 05868667b204c93d0e82de7aa01c3be9db1ad4e7 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 5 Feb 2021 12:42:48 -0600 Subject: [PATCH] Implement 64-bit division and remainder, signed and unsigned. These operations rely on new library routines in ORCALib (~CDIV8 and ~UDIV8). --- CGI.Comments | 8 ++++++++ CGI.Debug | 4 ++++ CGI.pas | 3 ++- DAG.pas | 7 ++++--- Expression.pas | 16 ++++++++++++++++ Gen.pas | 46 ++++++++++++++++++++++++++++++++++++++++++++-- Native.pas | 2 ++ 7 files changed, 80 insertions(+), 6 deletions(-) diff --git a/CGI.Comments b/CGI.Comments index 573cb45..dead7e6 100644 --- a/CGI.Comments +++ b/CGI.Comments @@ -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. } diff --git a/CGI.Debug b/CGI.Debug index 82ba67d..fc52fe6 100644 --- a/CGI.Debug +++ b/CGI.Debug @@ -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} diff --git a/CGI.pas b/CGI.pas index 75a3357..6dec193 100644 --- a/CGI.pas +++ b/CGI.pas @@ -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} {-----------------} diff --git a/DAG.pas b/DAG.pas index 0a68635..a8128c7 100644 --- a/DAG.pas +++ b/DAG.pas @@ -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; diff --git a/Expression.pas b/Expression.pas index 727ce83..07535b3 100644 --- a/Expression.pas +++ b/Expression.pas @@ -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} diff --git a/Gen.pas b/Gen.pas index 065dc46..12c1bb7 100644 --- a/Gen.pas +++ b/Gen.pas @@ -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); diff --git a/Native.pas b/Native.pas index 362213a..4088d9d 100644 --- a/Native.pas +++ b/Native.pas @@ -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}