[PATCH v5 14/15] target/ppc: Move dct{dp, qpq}, dr{sp, dpq}, dc{f, t}fix[q], dxex[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
dctdp:   DFP Convert To DFP Long
dctqpq:  DFP Convert To DFP Extended
drsp:DFP Round To DFP Short
drdpq:   DFP Round To DFP Long
dcffix:  DFP Convert From Fixed
dcffixq: DFP Convert From Fixed Quad
dctfix:  DFP Convert To Fixed
dctfixq: DFP Convert To Fixed Quad
dxex:DFP Extract Biased Exponent
dxexq:   DFP Extract Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 23 
 target/ppc/translate/dfp-impl.c.inc | 54 ++---
 target/ppc/translate/dfp-ops.c.inc  | 22 
 5 files changed, 69 insertions(+), 70 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index a50a73d3c0..d950d0d3fc 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -885,7 +885,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
 DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTDP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -901,7 +901,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 dfp_set_FPRF_from_FRT(&dfp);
 }
 
-void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTQPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -916,7 +916,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp128(t, &dfp.vt);
 }
 
-void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRSP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 uint32_t t_short = 0;
@@ -934,7 +934,7 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp64(t, &vt);
 }
 
-void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRDPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 dfp_prepare_decimal128(&dfp, 0, b, env);
@@ -972,8 +972,8 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_XX(dfp);
 }
 
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
+DFP_HELPER_CFFIX(DCFFIX, 64)
+DFP_HELPER_CFFIX(DCFFIXQ, 128)
 
 void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
 {
@@ -1022,8 +1022,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 set_dfp64(t, &dfp.vt);\
 }
 
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
+DFP_HELPER_CTFIX(DCTFIX, 64)
+DFP_HELPER_CTFIX(DCTFIXQ, 128)
 
 void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
 {
@@ -1233,8 +1233,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b) \
 }  \
 }
 
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
+DFP_HELPER_XEX(DXEX, 64)
+DFP_HELPER_XEX(DXEXQ, 128)
 
 static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cb05cc168c..4c2a349ce6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -728,22 +728,22 @@ DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTDP, void, env, fprp, fprp)
+DEF_HELPER_3(DCTQPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DRSP, void, env, fprp, fprp)
+DEF_HELPER_3(DRDPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
+DEF_HELPER_3(DXEX, void, env, fprp, fprp)
+DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, 

[PATCH v5 09/15] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
dtstdc:  DFP Test Data Class
dtstdcq: DFP Test Data Class Quad
dtstdg:  DFP Test Data Group
dtstdgq: DFP Test Data Group Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c |  8 +++
 target/ppc/helper.h |  8 +++
 target/ppc/insn32.decode| 14 
 target/ppc/translate/dfp-impl.c.inc | 35 +
 target/ppc/translate/dfp-ops.c.inc  | 10 -
 5 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 6ab46d7db5..f3c1e525a3 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -546,8 +546,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
+DFP_HELPER_TSTDC(DTSTDC, 64)
+DFP_HELPER_TSTDC(DTSTDCQ, 128)
 
 #define DFP_HELPER_TSTDG(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -601,8 +601,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
+DFP_HELPER_TSTDG(DTSTDG, 64)
+DFP_HELPER_TSTDG(DTSTDGQ, 128)
 
 #define DFP_HELPER_TSTEX(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 20041ce977..30e9247a5a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -708,10 +708,10 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
 DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6d97f9ae3b..38f8525d54 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -51,6 +51,12 @@
 %x_frbp 12:4 !function=times_2
 @X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
 
+&Z22_bf_fra bf fra dm
+@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   &Z22_bf_fra
+
+%z22_frap   17:4 !function=times_2
+@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -129,6 +135,14 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Test Instructions
+
+DTSTDC  111011 ... -- . .. 01110 -  @Z22_bf_fra
+DTSTDCQ 11 ... -- . .. 01110 -  @Z22_bf_frap
+
+DTSTDG  111011 ... -- . .. 011100010 -  @Z22_bf_fra
+DTSTDGQ 11 ... -- . .. 011100010 -  @Z22_bf_frap
+
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 1431d955c6..1a30c51467 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -60,21 +60,17 @@ static void gen_##name(DisasContext *ctx) \
 tcg_temp_free_ptr(rb);\
 }
 
-#define GEN_DFP_BF_A_DCM(name)\
-static void gen_##name(DisasContext *ctx) \
-{ \
-TCGv_ptr ra;  \
-TCGv_i32 dcm; \
-if (unlikely(!ctx->fpu_enabled)) {\
-gen_exception(ctx, POWERPC_EXCP_FPU); \
-return;   \
-} \
-ra = gen_fprp_ptr(rA(ctx->opcode));   \
-dcm = tcg_const_i32(DCM(ctx->opcode));\
-gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
-  cpu_env, ra, dcm);  \
-tcg_temp_free_ptr(ra);\
-tcg_temp_free_i32(dcm);   \
+#de

[PATCH v5 13/15] target/ppc: Move dqua[q], drrnd[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
dqua:   DFP Quantize
dquaq:  DFP Quantize Quad
drrnd:  DFP Reround
drrndq: DFP Reround Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c |  8 ++---
 target/ppc/helper.h |  8 ++---
 target/ppc/insn32.decode| 18 +--
 target/ppc/translate/dfp-impl.c.inc | 50 +
 target/ppc/translate/dfp-ops.c.inc  | 25 ---
 5 files changed, 47 insertions(+), 62 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index df3e6c7cb1..a50a73d3c0 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -769,8 +769,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
+DFP_HELPER_QUA(DQUA, 64)
+DFP_HELPER_QUA(DQUAQ, 128)
 
 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
  struct PPC_DFP *dfp)
@@ -847,8 +847,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
+DFP_HELPER_RRND(DRRND, 64)
+DFP_HELPER_RRND(DRRNDQ, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)   
\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,   
\
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 520cce8378..cb05cc168c 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -720,10 +720,10 @@ DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUA, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUAQ, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRND, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRNDQ, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index f0e17580e0..86dbdada47 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,11 +77,19 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
-&Z23_tb frt frb r:bool rmc rc:bool
-@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+&Z23_tabfrt fra frb rmc rc:bool
+@Z23_tab.. frt:5 fra:5 frb:5 rmc:2  rc:1&Z23_tab
 
 %z23_frtp   22:4 !function=times_2
+%z23_frap   17:4 !function=times_2
 %z23_frbp   12:4 !function=times_2
+@Z23_tabp   .. 0 0 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp fra=%z23_frap frb=%z23_frbp
+
+@Z23_tp_a_bp.. 0 fra:5 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
 @Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
 
 &Z23_te_tb  te frt frb rmc rc:bool
@@ -211,6 +219,12 @@ DTSTSFIQ11 ... - .. . 1010100011 -  
@X_bf_uim_bp
 DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
 DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
 
+DQUA111011 . . . .. 0011 .  @Z23_tab
+DQUAQ   11 . . . .. 0011 .  @Z23_tabp
+
+DRRND   111011 . . . .. 00100011 .  @Z23_tab
+DRRNDQ  11 . . . .. 00100011 .  @Z23_tp_a_bp
+
 DRINTX  111011 .  . . .. 01100011 . @Z23_tb
 DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index cb481d028a..30d65ffb46 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -86,28 +86,25 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  
 \
 return true; \
 }
 
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)   \
-static void gen_##name(DisasContext *ctx)\
-{\
-TCGv_ptr rt, ra, rb; \
-TCGv_i32 i32

[PATCH v5 12/15] target/ppc: Move dquai[q], drint{x, n}[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
dquai:   DFP Quantize Immediate
dquaiq:  DFP Quantize Immediate Quad
drintx:  DFP Round to FP Integer With Inexact
drintxq: DFP Round to FP Integer With Inexact Quad
drintn:  DFP Round to FP Integer Without Inexact
drintnq: DFP Round to FP Integer Without Inexact Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 12 +++
 target/ppc/helper.h | 12 +++
 target/ppc/insn32.decode| 23 +
 target/ppc/translate/dfp-impl.c.inc | 51 +
 target/ppc/translate/dfp-ops.c.inc  | 18 --
 5 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 9be6809b33..df3e6c7cb1 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -751,8 +751,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
+DFP_HELPER_QUAI(DQUAI, 64)
+DFP_HELPER_QUAI(DQUAIQ, 128)
 
 #define DFP_HELPER_QUA(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,\
@@ -873,8 +873,8 @@ static void RINTX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
+DFP_HELPER_RINT(DRINTX, RINTX_PPs, 64)
+DFP_HELPER_RINT(DRINTXQ, RINTX_PPs, 128)
 
 static void RINTN_PPs(struct PPC_DFP *dfp)
 {
@@ -882,8 +882,8 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
+DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
+DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 22bf167b15..520cce8378 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -718,16 +718,16 @@ DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_3(dctdp, void, env, fprp, fprp)
 DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
 DEF_HELPER_3(drsp, void, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index aaeccebca0..f0e17580e0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,6 +77,18 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
+%z23_frtp   22:4 !function=times_2
+%z23_frbp   12:4 !function=times_2
+@Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_te_tb  te frt frb rmc rc:bool
+@Z23_te_tb  .. frt:5 te:5 frb:5 rmc:2  rc:1 &Z23_te_tb
+
+@Z23_te_tbp .. 0 te:5 0 rmc:2  rc:1 &Z23_te_tb 
frt=%z23_frtp frb=%z23_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -194,6 +206,17 @@ DTSTSFQ 11 ... -- . . 1010100010 -  
@X_bf_a_bp
 DTSTSFI 111011 ... - .. . 1010100011 -  @X_bf_uim
 DTSTSFIQ11 ... - .. . 1010100011 -  @X_bf_uim_bp
 
+### Decimal Floating-Point Quantum Adjustment Instructions
+
+DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
+DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
+
+DRINTX  111011 .  . . .. 01100011 . @Z23_tb
+DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
+
+DRINTN  111011 .  . . .. 11100011 . @Z23_tb
+DRINTNQ 11 . ---

[PATCH v5 04/15] target/ppc: Implement DCFFIXQQ

2021-10-29 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dcffixqq: DFP Convert From Fixed Quadword Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 12 
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  8 
 target/ppc/translate.c  |  5 +
 target/ppc/translate/dfp-impl.c.inc | 17 +
 5 files changed, 43 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 07341a69f5..6b837c4450 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -970,6 +970,18 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
+void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
+{
+struct PPC_DFP dfp;
+
+dfp_prepare_decimal128(&dfp, NULL, NULL, env);
+decNumberFromInt128(&dfp.t, (uint64_t)b->VsrD(1), (int64_t)b->VsrD(0));
+dfp_finalize_decimal128(&dfp);
+CFFIX_PPs(&dfp);
+
+set_dfp128(t, &dfp.vt);
+}
+
 #define DFP_HELPER_CTFIX(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)  \
 { \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fff7bd46ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -734,6 +734,7 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp)
 DEF_HELPER_3(drdpq, void, env, fprp, fprp)
 DEF_HELPER_3(dcffix, void, env, fprp, fprp)
 DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..92ea2d0739 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -43,6 +43,10 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_frtp_vrb frtp vrb
+%x_frtp 22:4 !function=times_2
+@X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -121,6 +125,10 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Conversion Instructions
+
+DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 48a484eef6..6224cb3211 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7438,6 +7438,11 @@ static inline void set_avr64(int regno, TCGv_i64 src, 
bool high)
 /*
  * Helpers for decodetree used by !function for decoding arguments.
  */
+static int times_2(DisasContext *ctx, int x)
+{
+return x * 2;
+}
+
 static int times_4(DisasContext *ctx, int x)
 {
 return x * 4;
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 6c556dc2e1..d5b66567a6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -230,3 +230,20 @@ GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 #undef GEN_DFP_T_A_B_I32_Rc
 #undef GEN_DFP_T_B_Rc
 #undef GEN_DFP_T_FPR_I32_Rc
+
+static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_fprp_ptr(a->frtp);
+rb = gen_avr_ptr(a->vrb);
+gen_helper_DCFFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v5 01/15] libdecnumber: introduce decNumberFrom[U]Int128

2021-10-29 Thread Luis Pires
This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h |  2 ++
 libdecnumber/decNumber.c | 36 
 2 files changed, 38 insertions(+)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed07..0cf69c7db2 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -116,6 +116,8 @@
   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
   decNumber *decNumberFromInt64(decNumber *, int64_t);
   decNumber *decNumberFromUInt64(decNumber *, uint64_t);
+  decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
+  decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
   char * decNumberToString(const decNumber *, char *);
   char * decNumberToEngString(const decNumber *, char *);
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 1ffe458ad8..d7716ce175 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -167,6 +167,7 @@
 /* -- */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "libdecnumber/dconfig.h"
 #include "libdecnumber/decNumber.h"
 #include "libdecnumber/decNumberLocal.h"
@@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
 return dn;
 } /* decNumberFromUInt64 */
 
+decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
+{
+uint64_t unsig_hi = hi;
+if (hi < 0) {
+if (lo == 0) {
+unsig_hi = -unsig_hi;
+} else {
+unsig_hi = ~unsig_hi;
+lo = -lo;
+}
+}
+
+decNumberFromUInt128(dn, lo, unsig_hi);
+if (hi < 0) {
+dn->bits = DECNEG;/* sign needed */
+}
+return dn;
+} /* decNumberFromInt128 */
+
+decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
+{
+uint64_t rem;
+Unit *up; /* work pointer */
+decNumberZero(dn);/* clean */
+if (lo == 0 && hi == 0) {
+return dn;/* [or decGetDigits bad call] */
+}
+for (up = dn->lsu; hi > 0 || lo > 0; up++) {
+rem = divu128(&lo, &hi, DECDPUNMAX + 1);
+*up = (Unit)rem;
+}
+dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+return dn;
+} /* decNumberFromUInt128 */
+
 /* -- */
 /* to-int64 -- conversion to int64*/
 /**/
-- 
2.25.1




[PATCH v5 07/15] target/ppc: Implement DCTFIXQQ

2021-10-29 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dctfixqq: DFP Convert To Fixed Quadword Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 52 +
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  5 +++
 target/ppc/translate/dfp-impl.c.inc | 17 ++
 4 files changed, 75 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 6b837c4450..6ab46d7db5 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -51,6 +51,11 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 dfp[1].VsrD(0) = src->VsrD(1);
 }
 
+static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
+{
+*dst = *src;
+}
+
 struct PPC_DFP {
 CPUPPCState *env;
 ppc_vsr_t vt, va, vb;
@@ -1020,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
+void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, 0, b, env);
+
+if (unlikely(decNumberIsSpecial(&dfp.b))) {
+uint64_t invalid_flags = FP_VX | FP_VXCVI;
+if (decNumberIsInfinite(&dfp.b)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+} else { /* NaN */
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+if (decNumberIsSNaN(&dfp.b)) {
+invalid_flags |= FP_VXSNAN;
+}
+}
+dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);
+} else if (unlikely(decNumberIsZero(&dfp.b))) {
+dfp.vt.VsrD(0) = 0;
+dfp.vt.VsrD(1) = 0;
+} else {
+decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);
+decNumberIntegralToInt128(&dfp.b, &dfp.context,
+&dfp.vt.VsrD(1), &dfp.vt.VsrD(0));
+if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);
+} else {
+dfp_check_for_XX(&dfp);
+}
+}
+
+set_dfp128_to_avr(t, &dfp.vt);
+}
+
 static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
 unsigned n)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fff7bd46ad..20041ce977 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -737,6 +737,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 92ea2d0739..6d97f9ae3b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -47,6 +47,10 @@
 %x_frtp 22:4 !function=times_2
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
+&X_vrt_frbp vrt frbp
+%x_frbp 12:4 !function=times_2
+@X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -128,6 +132,7 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+DCTFIXQQ11 . 1 . 100010 -   @X_vrt_frbp
 
 ## Vector Bit Manipulation Instruction
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index d5b66567a6..e149777481 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ 
*a)
 
 return true;
 }
+
+static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_avr_ptr(a->vrt);
+rb = gen_fprp_ptr(a->frbp);
+gen_helper_DCTFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v5 10/15] target/ppc: Move d{add, sub, mul, div, iex}[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
dadd:  DFP Add
daddq: DFP Add Quad
dsub:  DFP Subtract
dsubq: DFP Subtract Quad
dmul:  DFP Multiply
dmulq: DFP Multiply Quad
ddiv:  DFP Divide
ddivq: DFP Divide Quad
diex:  DFP Insert Biased Exponent
diexq: DFP Insert Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 31 ++--
 target/ppc/translate/dfp-impl.c.inc | 56 ++---
 target/ppc/translate/dfp-ops.c.inc  | 19 --
 5 files changed, 76 insertions(+), 70 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index f3c1e525a3..da8eaaaff1 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -445,8 +445,8 @@ static void ADD_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_add(dfp);
 }
 
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
+DFP_HELPER_TAB(DADD, decNumberAdd, ADD_PPs, 64)
+DFP_HELPER_TAB(DADDQ, decNumberAdd, ADD_PPs, 128)
 
 static void SUB_PPs(struct PPC_DFP *dfp)
 {
@@ -458,8 +458,8 @@ static void SUB_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_subtract(dfp);
 }
 
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
+DFP_HELPER_TAB(DSUB, decNumberSubtract, SUB_PPs, 64)
+DFP_HELPER_TAB(DSUBQ, decNumberSubtract, SUB_PPs, 128)
 
 static void MUL_PPs(struct PPC_DFP *dfp)
 {
@@ -471,8 +471,8 @@ static void MUL_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIMZ(dfp);
 }
 
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
+DFP_HELPER_TAB(DMUL, decNumberMultiply, MUL_PPs, 64)
+DFP_HELPER_TAB(DMULQ, decNumberMultiply, MUL_PPs, 128)
 
 static void DIV_PPs(struct PPC_DFP *dfp)
 {
@@ -486,8 +486,8 @@ static void DIV_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIDI(dfp);
 }
 
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
+DFP_HELPER_TAB(DDIV, decNumberDivide, DIV_PPs, 64)
+DFP_HELPER_TAB(DDIVQ, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)
\
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)   
\
@@ -1299,8 +1299,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
+DFP_HELPER_IEX(DIEX, 64)
+DFP_HELPER_IEX(DIEXQ, 128)
 
 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 30e9247a5a..1f00e47b82 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -696,14 +696,14 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #define dh_alias_fprp ptr
 #define dh_ctype_fprp ppc_fprp_t *
 
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADD, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADDQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUB, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUBQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
@@ -744,8 +744,8 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
 DEF_HELPER_3(dxex, void, env, fprp, fprp)
 DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 38f8525d54..c4a8cc7ec5 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -37,6 +37,16 @@
 &X  rt ra rb
 @X  .. rt:5 ra:5 rb:5 .. .  &X
 
+&X_rc   rt ra rb rc:bool
+@X_rc   .. rt:5 ra:5 rb:5 .. rc:1   &X_rc
+
+%x_frtp 22:4 !function=times_2
+

[PATCH v5 00/15] target/ppc: DFP instructions using decodetree

2021-10-29 Thread Luis Pires
This series moves all existing DFP instructions to decodetree and
implements the 2 new instructions (dcffixqq and dctfixqq) from
Power ISA 3.1.

In order to implement dcffixqq, divu128/divs128 were modified to
support 128-bit quotients (previously, they were limited to 64-bit
quotients), along with adjustments being made to their existing callers.
libdecnumber was also expanded to allow creating decimal numbers from
128-bit integers.

Similarly, for dctfixqq, mulu128 (host-utils) and decNumberIntegralToInt128
(libdecnumber) were introduced to support 128-bit integers.

The remaining patches of this series move all of the already existing
DFP instructions to decodetree, and end up removing dfp-ops.c.inc, which
is no longer needed.

---

I'm resending this series because I missed adding a R-b tag on one
of the commits in v4. I also dropped patches that were already applied and
rebased against master.

All of these patches are reviewed and ready to be applied.

Changes in v5:
- Rebased against master
- Skipped patches that were already applied (v4 1-4)

Changes in v4:
- Rebased against dgibson/ppc-for-6.2
- Skipped patches that were already applied (v3 1-4)
- Changed divu128/divs128 to return the remainder (rth)
- Moved changes that drop nip updates to a separate patch (rth)

Changes in v3:
- Split the uabs64 patch in 2
- Included patch to fix missing zero-extension in divs128
- Folded divisor == 0 into the dhi == 0 case in divu128
- Moved udiv_qrnnd from softfloat-macros.h to host-utils.h
- Used udiv_qrnnd in divu128
- Replaced int with bool in divs128
- Added unit test to check the divisor normalization in divu128
- Removed 'inline' from times_* functions in ppc/translate.c
- Used uadd64_overflow in mulu128
- Removed unnecessary 'else' from decNumberIntegralToInt128

Changes in v2:
- Renamed abs64() to uabs64()

Bruno Larsen (1):
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

Fernando Valle (1):
  target/ppc: Introduce REQUIRE_FPU

Luis Pires (13):
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Do not update nip on DFP instructions
  target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree
  target/ppc: Move d{add,sub,mul,div,iex}[q] to decodetree
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree
  target/ppc: Move dquai[q], drint{x,n}[q] to decodetree
  target/ppc: Move dqua[q], drrnd[q] to decodetree
  target/ppc: Move dct{dp,qpq},dr{sp,dpq},dc{f,t}fix[q],dxex[q] to
decodetree
  target/ppc: Move ddedpd[q],denbcd[q],dscli[q],dscri[q] to decodetree

 include/libdecnumber/decNumber.h   |   4 +
 include/libdecnumber/decNumberLocal.h  |   2 +-
 include/qemu/host-utils.h  |  36 +++
 libdecnumber/decContext.c  |   7 +-
 libdecnumber/decNumber.c   | 131 
 target/ppc/dfp_helper.c| 168 +++---
 target/ppc/helper.h| 106 ---
 target/ppc/insn32.decode   | 171 ++
 target/ppc/translate.c |  23 +-
 target/ppc/translate/dfp-impl.c.inc| 419 -
 target/ppc/translate/dfp-ops.c.inc | 165 --
 target/ppc/translate/vector-impl.c.inc |  10 +-
 12 files changed, 747 insertions(+), 495 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

-- 
2.25.1




[PATCH v5 06/15] libdecnumber: Introduce decNumberIntegralToInt128

2021-10-29 Thread Luis Pires
This will be used to implement PowerPC's dctfixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h  |  2 +
 include/libdecnumber/decNumberLocal.h |  2 +-
 libdecnumber/decContext.c |  7 +-
 libdecnumber/decNumber.c  | 95 +++
 4 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 0cf69c7db2..41bc2a0d36 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -124,6 +124,8 @@
   uint32_tdecNumberToUInt32(const decNumber *, decContext *);
   int32_t decNumberToInt32(const decNumber *, decContext *);
   int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
+  voiddecNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh);
   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
 
diff --git a/include/libdecnumber/decNumberLocal.h 
b/include/libdecnumber/decNumberLocal.h
index 4d53c077f2..6198ca8593 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
 
   /* Shared lookup tables*/
   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
-  extern const uLong  DECPOWERS[19];/* powers of ten table*/
+  extern const uLong  DECPOWERS[20];/* powers of ten table*/
   /* The following are included from decDPD.h*/
   extern const uShort DPD2BIN[1024];   /* DPD -> 0-999   */
   extern const uShort BIN2DPD[1000];   /* 0-999 -> DPD   */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 7d97a65ac5..1956edf0a7 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -53,12 +53,13 @@ static  const  Flag *mfctop=(Flag *)&mfcone; /* -> top 
byte */
 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
 
 /* -- */
-/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
 /* -- */
-const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100,
+const uLong DECPOWERS[20] = {1, 10, 100, 1000, 1, 10, 100,
   1000, 1, 10, 100ULL, 1000ULL,
   1ULL, 10ULL, 100ULL, 1000ULL,
-  1ULL, 10ULL, 100ULL, };
+  1ULL, 10ULL, 100ULL,
+  1000ULL,};
 
 /* -- */
 /* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index d7716ce175..31282adafd 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -264,6 +264,7 @@ static decNumber * decTrim(decNumber *, decContext *, Flag, 
Int *);
 static IntdecUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
  Unit *, Int);
 static IntdecUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+static boolmulUInt128ByPowOf10(uLong *, uLong *, uInt);
 
 #if !DECSUBSET
 /* decFinish == decFinalize when no subset arithmetic needed */
@@ -542,6 +543,68 @@ Invalid:
 return 0;
 } /* decNumberIntegralToInt64 */
 
+/* -- */
+/* decNumberIntegralToInt128 -- conversion to int128  */
+/**/
+/*  dn is the decNumber to convert.  dn is assumed to have been   */
+/*rounded to a floating point integer value.  */
+/*  set is the context for reporting errors   */
+/*  returns the converted decNumber via plow and phigh*/
+/**/
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/
+/* range for a signed 128 bit integer.*/
+/* -- */
+
+void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh)
+{
+int d;/* work */
+const Unit *up;   /* .. */
+uint64_t lo = 0, hi = 0;
+
+if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+   (dn->digits + dn->exponent > 39)) {
+goto Invalid;
+}
+
+up = dn->lsu; /* -> lsu */
+

[PATCH v5 08/15] target/ppc: Do not update nip on DFP instructions

2021-10-29 Thread Luis Pires
Before moving the existing DFP instructions to decodetree, drop the
nip update that shouldn't be done for these instructions.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/translate/dfp-impl.c.inc | 8 
 1 file changed, 8 deletions(-)

diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index e149777481..1431d955c6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -15,7 +15,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rd = gen_fprp_ptr(rD(ctx->opcode));  \
 ra = gen_fprp_ptr(rA(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
@@ -36,7 +35,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 ra = gen_fprp_ptr(rA(ctx->opcode));   \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -54,7 +52,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 uim = tcg_const_i32(UIMM5(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -72,7 +69,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
 ra = gen_fprp_ptr(rA(ctx->opcode));   \
 dcm = tcg_const_i32(DCM(ctx->opcode));\
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -90,7 +86,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
 rt = gen_fprp_ptr(rD(ctx->opcode));   \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 u32_1 = tcg_const_i32(u32f1(ctx->opcode));\
@@ -114,7 +109,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rt = gen_fprp_ptr(rD(ctx->opcode));  \
 ra = gen_fprp_ptr(rA(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
@@ -137,7 +131,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rt = gen_fprp_ptr(rD(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
 gen_helper_##name(cpu_env, rt, rb);  \
@@ -157,7 +150,6 @@ static void gen_##name(DisasContext *ctx)  \
 gen_exception(ctx, POWERPC_EXCP_FPU);  \
 return;\
 }  \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 rt = gen_fprp_ptr(rD(ctx->opcode));\
 rs = gen_fprp_ptr(fprfld(ctx->opcode));\
 i32 = tcg_const_i32(i32fld(ctx->opcode));  \
-- 
2.25.1




[PATCH v5 15/15] target/ppc: Move ddedpd[q], denbcd[q], dscli[q], dscri[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
ddedpd:  DFP Decode DPD To BCD
ddedpdq: DFP Decode DPD To BCD Quad
denbcd:  DFP Encode BCD To DPD
denbcdq: DFP Encode BCD To DPD Quad
dscli:   DFP Shift Significand Left Immediate
dscliq:  DFP Shift Significand Left Immediate Quad
dscri:   DFP Shift Significand Right Immediate
dscriq:  DFP Shift Significand Right Immediate Quad

Also deleted dfp-ops.c.inc, now that all PPC DFP instructions were
moved to decodetree.

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 16 -
 target/ppc/helper.h | 16 -
 target/ppc/insn32.decode| 28 +++
 target/ppc/translate.c  |  2 --
 target/ppc/translate/dfp-impl.c.inc | 53 +
 target/ppc/translate/dfp-ops.c.inc  | 40 --
 6 files changed, 68 insertions(+), 87 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index d950d0d3fc..0d01ac3de0 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1131,8 +1131,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
+DFP_HELPER_DEDPD(DDEDPD, 64)
+DFP_HELPER_DEDPD(DDEDPDQ, 128)
 
 static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
@@ -1199,8 +1199,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 set_dfp##size(t, &dfp.vt);   \
 }
 
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
+DFP_HELPER_ENBCD(DENBCD, 64)
+DFP_HELPER_ENBCD(DENBCDQ, 128)
 
 #define DFP_HELPER_XEX(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
@@ -1387,7 +1387,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
+DFP_HELPER_SHIFT(DSCLI, 64, 1)
+DFP_HELPER_SHIFT(DSCLIQ, 128, 1)
+DFP_HELPER_SHIFT(DSCRI, 64, 0)
+DFP_HELPER_SHIFT(DSCRIQ, 128, 0)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4c2a349ce6..6fa3e15fe9 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -738,18 +738,18 @@ DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPDQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCDQ, void, env, fprp, fprp, i32)
 DEF_HELPER_3(DXEX, void, env, fprp, fprp)
 DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRIQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLIQ, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
 DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2ce8b0ab95..6aec1c0728 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -74,6 +74,16 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_tb_sp_rc rt rb sp rc:bool
+@X_tb_sp_rc .. rt:5 sp:2 ... rb:5 .. rc:1   &X_tb_sp_rc
+
+@X_tbp_sp_rc.. 0 sp:2 ... 0 .. rc:1 &X_tb_sp_rc 
rt=%x_frtp rb=%x_frbp
+
+&X_tb_s_rc  rt rb s:bool rc:bool
+@X_tb_s_rc  .. rt:5 s:1  rb:5 .. rc:1   &X_tb_s_rc
+
+@X_tbp_s_rc .. 0 s:1  0 .. rc:1 &X_tb_s_rc 
rt=%x_frtp rb=%x_frbp
+
 &X_frtp_vrb frtp vrb
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
@@ -86,6 +96,12 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z22_ta_sh_rc   rt ra sh rc:bool
+@Z22_ta_sh_rc   .. rt:5 ra:5 sh:6 . rc:

[PATCH v5 03/15] target/ppc: Introduce REQUIRE_FPU

2021-10-29 Thread Luis Pires
From: Fernando Valle 

Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index c2fafebd1c..48a484eef6 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7477,6 +7477,14 @@ static int times_4(DisasContext *ctx, int x)
 }   \
 } while (0)
 
+#define REQUIRE_FPU(ctx)\
+do {\
+if (unlikely(!(ctx)->fpu_enabled)) {\
+gen_exception((ctx), POWERPC_EXCP_FPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
-- 
2.25.1




[PATCH v5 05/15] host-utils: Introduce mulu128

2021-10-29 Thread Luis Pires
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/qemu/host-utils.h | 36 
 1 file changed, 36 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index a3a7ced78d..ca979dc6cc 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -590,6 +590,42 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, 
uint64_t *ret)
 #endif
 }
 
+/*
+ * Unsigned 128x64 multiplication.
+ * Returns true if the result got truncated to 128 bits.
+ * Otherwise, returns false and the multiplication result via plow and phigh.
+ */
+static inline bool mulu128(uint64_t *plow, uint64_t *phigh, uint64_t factor)
+{
+#if defined(CONFIG_INT128) && \
+(__has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5)
+bool res;
+__uint128_t r;
+__uint128_t f = ((__uint128_t)*phigh << 64) | *plow;
+res = __builtin_mul_overflow(f, factor, &r);
+
+*plow = r;
+*phigh = r >> 64;
+
+return res;
+#else
+uint64_t dhi = *phigh;
+uint64_t dlo = *plow;
+uint64_t ahi;
+uint64_t blo, bhi;
+
+if (dhi == 0) {
+mulu64(plow, phigh, dlo, factor);
+return false;
+}
+
+mulu64(plow, &ahi, dlo, factor);
+mulu64(&blo, &bhi, dhi, factor);
+
+return uadd64_overflow(ahi, blo, phigh) || bhi != 0;
+#endif
+}
+
 /**
  * uadd64_carry - addition with carry-in and carry-out
  * @x, @y: addends
-- 
2.25.1




[PATCH v5 11/15] target/ppc: Move dcmp{u, o}[q], dts{tex, tsf, tsfi}[q] to decodetree

2021-10-29 Thread Luis Pires
Move the following instructions to decodetree:
dcmpu:DFP Compare Unordered
dcmpuq:   DFP Compare Unordered Quad
dcmpo:DFP Compare Ordered
dcmpoq:   DFP Compare Ordered Quad
dtstex:   DFP Test Exponent
dtstexq:  DFP Test Exponent Quad
dtstsf:   DFP Test Significance
dtstsfq:  DFP Test Significance Quad
dtstsfi:  DFP Test Significance Immediate
dtstsfiq: DFP Test Significance Immediate Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 
 target/ppc/helper.h | 20 
 target/ppc/insn32.decode| 29 +++
 target/ppc/translate/dfp-impl.c.inc | 74 +
 target/ppc/translate/dfp-ops.c.inc  | 31 
 5 files changed, 83 insertions(+), 91 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index da8eaaaff1..9be6809b33 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -507,8 +507,8 @@ static void CMPU_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
+DFP_HELPER_BF_AB(DCMPU, decNumberCompare, CMPU_PPs, 64)
+DFP_HELPER_BF_AB(DCMPUQ, decNumberCompare, CMPU_PPs, 128)
 
 static void CMPO_PPs(struct PPC_DFP *dfp)
 {
@@ -518,8 +518,8 @@ static void CMPO_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXVC(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
+DFP_HELPER_BF_AB(DCMPO, decNumberCompare, CMPO_PPs, 64)
+DFP_HELPER_BF_AB(DCMPOQ, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -633,8 +633,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
+DFP_HELPER_TSTEX(DTSTEX, 64)
+DFP_HELPER_TSTEX(DTSTEXQ, 128)
 
 #define DFP_HELPER_TSTSF(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
@@ -670,8 +670,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
+DFP_HELPER_TSTSF(DTSTSF, 64)
+DFP_HELPER_TSTSF(DTSTSFQ, 128)
 
 #define DFP_HELPER_TSTSFI(op, size) \
 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)   \
@@ -705,8 +705,8 @@ uint32_t helper_##op(CPUPPCState *env, uint32_t a, 
ppc_fprp_t *b)   \
 return dfp.crbf;\
 }
 
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
+DFP_HELPER_TSTSFI(DTSTSFI, 64)
+DFP_HELPER_TSTSFI(DTSTSFIQ, 128)
 
 static void QUA_PPs(struct PPC_DFP *dfp)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 1f00e47b82..22bf167b15 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -704,20 +704,20 @@ DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPO, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPOQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPU, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPUQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTEX, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTEXQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index c4a8cc7ec5..aaeccebca0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -50,6 +50,18 @@
 &X_bi   rt bi
 @X_bi   .. rt:5 bi:5 - .. - &X_bi
 
+&X_bf   bf ra rb
+@X_bf   .. 

[PATCH v5 02/15] target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

2021-10-29 Thread Luis Pires
From: Bruno Larsen 

Move REQUIRE_ALTIVEC to translate.c and rename it to REQUIRE_VECTOR.

Signed-off-by: Bruno Larsen 
Signed-off-by: Matheus Ferst 
Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 target/ppc/translate.c |  8 
 target/ppc/translate/vector-impl.c.inc | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 518337bcb7..c2fafebd1c 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7469,6 +7469,14 @@ static int times_4(DisasContext *ctx, int x)
 # define REQUIRE_64BIT(CTX)  REQUIRE_INSNS_FLAGS(CTX, 64B)
 #endif
 
+#define REQUIRE_VECTOR(CTX) \
+do {\
+if (unlikely(!(CTX)->altivec_enabled)) {\
+gen_exception((CTX), POWERPC_EXCP_VPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
diff --git a/target/ppc/translate/vector-impl.c.inc 
b/target/ppc/translate/vector-impl.c.inc
index 117ce9b137..197e903337 100644
--- a/target/ppc/translate/vector-impl.c.inc
+++ b/target/ppc/translate/vector-impl.c.inc
@@ -17,20 +17,12 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define REQUIRE_ALTIVEC(CTX) \
-do {\
-if (unlikely(!(CTX)->altivec_enabled)) {\
-gen_exception((CTX), POWERPC_EXCP_VPU); \
-return true;\
-}   \
-} while (0)
-
 static bool trans_VCFUGED(DisasContext *ctx, arg_VX *a)
 {
 TCGv_i64 tgt, src, mask;
 
 REQUIRE_INSNS_FLAGS2(ctx, ISA310);
-REQUIRE_ALTIVEC(ctx);
+REQUIRE_VECTOR(ctx);
 
 tgt = tcg_temp_new_i64();
 src = tcg_temp_new_i64();
-- 
2.25.1




[PATCH v4 19/19] target/ppc: Move ddedpd[q], denbcd[q], dscli[q], dscri[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
ddedpd:  DFP Decode DPD To BCD
ddedpdq: DFP Decode DPD To BCD Quad
denbcd:  DFP Encode BCD To DPD
denbcdq: DFP Encode BCD To DPD Quad
dscli:   DFP Shift Significand Left Immediate
dscliq:  DFP Shift Significand Left Immediate Quad
dscri:   DFP Shift Significand Right Immediate
dscriq:  DFP Shift Significand Right Immediate Quad

Also deleted dfp-ops.c.inc, now that all PPC DFP instructions were
moved to decodetree.

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 16 -
 target/ppc/helper.h | 16 -
 target/ppc/insn32.decode| 28 +++
 target/ppc/translate.c  |  2 --
 target/ppc/translate/dfp-impl.c.inc | 53 +
 target/ppc/translate/dfp-ops.c.inc  | 40 --
 6 files changed, 68 insertions(+), 87 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index d950d0d3fc..0d01ac3de0 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1131,8 +1131,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
+DFP_HELPER_DEDPD(DDEDPD, 64)
+DFP_HELPER_DEDPD(DDEDPDQ, 128)
 
 static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
@@ -1199,8 +1199,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 set_dfp##size(t, &dfp.vt);   \
 }
 
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
+DFP_HELPER_ENBCD(DENBCD, 64)
+DFP_HELPER_ENBCD(DENBCDQ, 128)
 
 #define DFP_HELPER_XEX(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
@@ -1387,7 +1387,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
+DFP_HELPER_SHIFT(DSCLI, 64, 1)
+DFP_HELPER_SHIFT(DSCLIQ, 128, 1)
+DFP_HELPER_SHIFT(DSCRI, 64, 0)
+DFP_HELPER_SHIFT(DSCRIQ, 128, 0)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4c2a349ce6..6fa3e15fe9 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -738,18 +738,18 @@ DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPDQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCDQ, void, env, fprp, fprp, i32)
 DEF_HELPER_3(DXEX, void, env, fprp, fprp)
 DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRIQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLIQ, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
 DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2ce8b0ab95..6aec1c0728 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -74,6 +74,16 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_tb_sp_rc rt rb sp rc:bool
+@X_tb_sp_rc .. rt:5 sp:2 ... rb:5 .. rc:1   &X_tb_sp_rc
+
+@X_tbp_sp_rc.. 0 sp:2 ... 0 .. rc:1 &X_tb_sp_rc 
rt=%x_frtp rb=%x_frbp
+
+&X_tb_s_rc  rt rb s:bool rc:bool
+@X_tb_s_rc  .. rt:5 s:1  rb:5 .. rc:1   &X_tb_s_rc
+
+@X_tbp_s_rc .. 0 s:1  0 .. rc:1 &X_tb_s_rc 
rt=%x_frtp rb=%x_frbp
+
 &X_frtp_vrb frtp vrb
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
@@ -86,6 +96,12 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z22_ta_sh_rc   rt ra sh rc:bool
+@Z22_ta_sh_rc   .. rt:5 ra:5 sh:6 . rc:

[PATCH v4 18/19] target/ppc: Move dct{dp, qpq}, dr{sp, dpq}, dc{f, t}fix[q], dxex[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dctdp:   DFP Convert To DFP Long
dctqpq:  DFP Convert To DFP Extended
drsp:DFP Round To DFP Short
drdpq:   DFP Round To DFP Long
dcffix:  DFP Convert From Fixed
dcffixq: DFP Convert From Fixed Quad
dctfix:  DFP Convert To Fixed
dctfixq: DFP Convert To Fixed Quad
dxex:DFP Extract Biased Exponent
dxexq:   DFP Extract Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 23 
 target/ppc/translate/dfp-impl.c.inc | 54 ++---
 target/ppc/translate/dfp-ops.c.inc  | 22 
 5 files changed, 69 insertions(+), 70 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index a50a73d3c0..d950d0d3fc 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -885,7 +885,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
 DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTDP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -901,7 +901,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 dfp_set_FPRF_from_FRT(&dfp);
 }
 
-void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTQPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -916,7 +916,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp128(t, &dfp.vt);
 }
 
-void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRSP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 uint32_t t_short = 0;
@@ -934,7 +934,7 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp64(t, &vt);
 }
 
-void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRDPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 dfp_prepare_decimal128(&dfp, 0, b, env);
@@ -972,8 +972,8 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_XX(dfp);
 }
 
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
+DFP_HELPER_CFFIX(DCFFIX, 64)
+DFP_HELPER_CFFIX(DCFFIXQ, 128)
 
 void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
 {
@@ -1022,8 +1022,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 set_dfp64(t, &dfp.vt);\
 }
 
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
+DFP_HELPER_CTFIX(DCTFIX, 64)
+DFP_HELPER_CTFIX(DCTFIXQ, 128)
 
 void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
 {
@@ -1233,8 +1233,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b) \
 }  \
 }
 
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
+DFP_HELPER_XEX(DXEX, 64)
+DFP_HELPER_XEX(DXEXQ, 128)
 
 static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cb05cc168c..4c2a349ce6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -728,22 +728,22 @@ DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTDP, void, env, fprp, fprp)
+DEF_HELPER_3(DCTQPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DRSP, void, env, fprp, fprp)
+DEF_HELPER_3(DRDPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
+DEF_HELPER_3(DXEX, void, env, fprp, fprp)
+DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, 

[PATCH v4 17/19] target/ppc: Move dqua[q], drrnd[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dqua:   DFP Quantize
dquaq:  DFP Quantize Quad
drrnd:  DFP Reround
drrndq: DFP Reround Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c |  8 ++---
 target/ppc/helper.h |  8 ++---
 target/ppc/insn32.decode| 18 +--
 target/ppc/translate/dfp-impl.c.inc | 50 +
 target/ppc/translate/dfp-ops.c.inc  | 25 ---
 5 files changed, 47 insertions(+), 62 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index df3e6c7cb1..a50a73d3c0 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -769,8 +769,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
+DFP_HELPER_QUA(DQUA, 64)
+DFP_HELPER_QUA(DQUAQ, 128)
 
 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
  struct PPC_DFP *dfp)
@@ -847,8 +847,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
+DFP_HELPER_RRND(DRRND, 64)
+DFP_HELPER_RRND(DRRNDQ, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)   
\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,   
\
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 520cce8378..cb05cc168c 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -720,10 +720,10 @@ DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUA, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUAQ, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRND, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRNDQ, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index f0e17580e0..86dbdada47 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,11 +77,19 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
-&Z23_tb frt frb r:bool rmc rc:bool
-@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+&Z23_tabfrt fra frb rmc rc:bool
+@Z23_tab.. frt:5 fra:5 frb:5 rmc:2  rc:1&Z23_tab
 
 %z23_frtp   22:4 !function=times_2
+%z23_frap   17:4 !function=times_2
 %z23_frbp   12:4 !function=times_2
+@Z23_tabp   .. 0 0 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp fra=%z23_frap frb=%z23_frbp
+
+@Z23_tp_a_bp.. 0 fra:5 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
 @Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
 
 &Z23_te_tb  te frt frb rmc rc:bool
@@ -211,6 +219,12 @@ DTSTSFIQ11 ... - .. . 1010100011 -  
@X_bf_uim_bp
 DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
 DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
 
+DQUA111011 . . . .. 0011 .  @Z23_tab
+DQUAQ   11 . . . .. 0011 .  @Z23_tabp
+
+DRRND   111011 . . . .. 00100011 .  @Z23_tab
+DRRNDQ  11 . . . .. 00100011 .  @Z23_tp_a_bp
+
 DRINTX  111011 .  . . .. 01100011 . @Z23_tb
 DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index cb481d028a..30d65ffb46 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -86,28 +86,25 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  
 \
 return true; \
 }
 
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)   \
-static void gen_##name(DisasContext *ctx)\
-{\
-TCGv_ptr rt, ra, rb; \
-TCGv_i32 i32

[PATCH v4 11/19] target/ppc: Implement DCTFIXQQ

2021-10-25 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dctfixqq: DFP Convert To Fixed Quadword Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 52 +
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  5 +++
 target/ppc/translate/dfp-impl.c.inc | 17 ++
 4 files changed, 75 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 6b837c4450..6ab46d7db5 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -51,6 +51,11 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 dfp[1].VsrD(0) = src->VsrD(1);
 }
 
+static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
+{
+*dst = *src;
+}
+
 struct PPC_DFP {
 CPUPPCState *env;
 ppc_vsr_t vt, va, vb;
@@ -1020,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
+void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, 0, b, env);
+
+if (unlikely(decNumberIsSpecial(&dfp.b))) {
+uint64_t invalid_flags = FP_VX | FP_VXCVI;
+if (decNumberIsInfinite(&dfp.b)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+} else { /* NaN */
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+if (decNumberIsSNaN(&dfp.b)) {
+invalid_flags |= FP_VXSNAN;
+}
+}
+dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);
+} else if (unlikely(decNumberIsZero(&dfp.b))) {
+dfp.vt.VsrD(0) = 0;
+dfp.vt.VsrD(1) = 0;
+} else {
+decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);
+decNumberIntegralToInt128(&dfp.b, &dfp.context,
+&dfp.vt.VsrD(1), &dfp.vt.VsrD(0));
+if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);
+} else {
+dfp_check_for_XX(&dfp);
+}
+}
+
+set_dfp128_to_avr(t, &dfp.vt);
+}
+
 static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
 unsigned n)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fff7bd46ad..20041ce977 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -737,6 +737,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 92ea2d0739..6d97f9ae3b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -47,6 +47,10 @@
 %x_frtp 22:4 !function=times_2
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
+&X_vrt_frbp vrt frbp
+%x_frbp 12:4 !function=times_2
+@X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -128,6 +132,7 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+DCTFIXQQ11 . 1 . 100010 -   @X_vrt_frbp
 
 ## Vector Bit Manipulation Instruction
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index d5b66567a6..e149777481 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ 
*a)
 
 return true;
 }
+
+static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_avr_ptr(a->vrt);
+rb = gen_fprp_ptr(a->frbp);
+gen_helper_DCTFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v4 10/19] libdecnumber: Introduce decNumberIntegralToInt128

2021-10-25 Thread Luis Pires
This will be used to implement PowerPC's dctfixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h  |  2 +
 include/libdecnumber/decNumberLocal.h |  2 +-
 libdecnumber/decContext.c |  7 +-
 libdecnumber/decNumber.c  | 95 +++
 4 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 0cf69c7db2..41bc2a0d36 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -124,6 +124,8 @@
   uint32_tdecNumberToUInt32(const decNumber *, decContext *);
   int32_t decNumberToInt32(const decNumber *, decContext *);
   int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
+  voiddecNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh);
   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
 
diff --git a/include/libdecnumber/decNumberLocal.h 
b/include/libdecnumber/decNumberLocal.h
index 4d53c077f2..6198ca8593 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
 
   /* Shared lookup tables*/
   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
-  extern const uLong  DECPOWERS[19];/* powers of ten table*/
+  extern const uLong  DECPOWERS[20];/* powers of ten table*/
   /* The following are included from decDPD.h*/
   extern const uShort DPD2BIN[1024];   /* DPD -> 0-999   */
   extern const uShort BIN2DPD[1000];   /* 0-999 -> DPD   */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 7d97a65ac5..1956edf0a7 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -53,12 +53,13 @@ static  const  Flag *mfctop=(Flag *)&mfcone; /* -> top 
byte */
 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
 
 /* -- */
-/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
 /* -- */
-const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100,
+const uLong DECPOWERS[20] = {1, 10, 100, 1000, 1, 10, 100,
   1000, 1, 10, 100ULL, 1000ULL,
   1ULL, 10ULL, 100ULL, 1000ULL,
-  1ULL, 10ULL, 100ULL, };
+  1ULL, 10ULL, 100ULL,
+  1000ULL,};
 
 /* -- */
 /* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index d7716ce175..31282adafd 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -264,6 +264,7 @@ static decNumber * decTrim(decNumber *, decContext *, Flag, 
Int *);
 static IntdecUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
  Unit *, Int);
 static IntdecUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+static boolmulUInt128ByPowOf10(uLong *, uLong *, uInt);
 
 #if !DECSUBSET
 /* decFinish == decFinalize when no subset arithmetic needed */
@@ -542,6 +543,68 @@ Invalid:
 return 0;
 } /* decNumberIntegralToInt64 */
 
+/* -- */
+/* decNumberIntegralToInt128 -- conversion to int128  */
+/**/
+/*  dn is the decNumber to convert.  dn is assumed to have been   */
+/*rounded to a floating point integer value.  */
+/*  set is the context for reporting errors   */
+/*  returns the converted decNumber via plow and phigh*/
+/**/
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/
+/* range for a signed 128 bit integer.*/
+/* -- */
+
+void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh)
+{
+int d;/* work */
+const Unit *up;   /* .. */
+uint64_t lo = 0, hi = 0;
+
+if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+   (dn->digits + dn->exponent > 39)) {
+goto Invalid;
+}
+
+up = dn->lsu; /* -> lsu */
+

[PATCH v4 09/19] host-utils: Introduce mulu128

2021-10-25 Thread Luis Pires
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/qemu/host-utils.h | 36 
 1 file changed, 36 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index a3a7ced78d..ca979dc6cc 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -590,6 +590,42 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, 
uint64_t *ret)
 #endif
 }
 
+/*
+ * Unsigned 128x64 multiplication.
+ * Returns true if the result got truncated to 128 bits.
+ * Otherwise, returns false and the multiplication result via plow and phigh.
+ */
+static inline bool mulu128(uint64_t *plow, uint64_t *phigh, uint64_t factor)
+{
+#if defined(CONFIG_INT128) && \
+(__has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5)
+bool res;
+__uint128_t r;
+__uint128_t f = ((__uint128_t)*phigh << 64) | *plow;
+res = __builtin_mul_overflow(f, factor, &r);
+
+*plow = r;
+*phigh = r >> 64;
+
+return res;
+#else
+uint64_t dhi = *phigh;
+uint64_t dlo = *plow;
+uint64_t ahi;
+uint64_t blo, bhi;
+
+if (dhi == 0) {
+mulu64(plow, phigh, dlo, factor);
+return false;
+}
+
+mulu64(plow, &ahi, dlo, factor);
+mulu64(&blo, &bhi, dhi, factor);
+
+return uadd64_overflow(ahi, blo, phigh) || bhi != 0;
+#endif
+}
+
 /**
  * uadd64_carry - addition with carry-in and carry-out
  * @x, @y: addends
-- 
2.25.1




[PATCH v4 07/19] target/ppc: Introduce REQUIRE_FPU

2021-10-25 Thread Luis Pires
From: Fernando Valle 

Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index c2fafebd1c..48a484eef6 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7477,6 +7477,14 @@ static int times_4(DisasContext *ctx, int x)
 }   \
 } while (0)
 
+#define REQUIRE_FPU(ctx)\
+do {\
+if (unlikely(!(ctx)->fpu_enabled)) {\
+gen_exception((ctx), POWERPC_EXCP_FPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
-- 
2.25.1




[PATCH v4 06/19] target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

2021-10-25 Thread Luis Pires
From: Bruno Larsen 

Move REQUIRE_ALTIVEC to translate.c and rename it to REQUIRE_VECTOR.

Signed-off-by: Bruno Larsen 
Signed-off-by: Matheus Ferst 
Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 target/ppc/translate.c |  8 
 target/ppc/translate/vector-impl.c.inc | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 518337bcb7..c2fafebd1c 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7469,6 +7469,14 @@ static int times_4(DisasContext *ctx, int x)
 # define REQUIRE_64BIT(CTX)  REQUIRE_INSNS_FLAGS(CTX, 64B)
 #endif
 
+#define REQUIRE_VECTOR(CTX) \
+do {\
+if (unlikely(!(CTX)->altivec_enabled)) {\
+gen_exception((CTX), POWERPC_EXCP_VPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
diff --git a/target/ppc/translate/vector-impl.c.inc 
b/target/ppc/translate/vector-impl.c.inc
index 117ce9b137..197e903337 100644
--- a/target/ppc/translate/vector-impl.c.inc
+++ b/target/ppc/translate/vector-impl.c.inc
@@ -17,20 +17,12 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define REQUIRE_ALTIVEC(CTX) \
-do {\
-if (unlikely(!(CTX)->altivec_enabled)) {\
-gen_exception((CTX), POWERPC_EXCP_VPU); \
-return true;\
-}   \
-} while (0)
-
 static bool trans_VCFUGED(DisasContext *ctx, arg_VX *a)
 {
 TCGv_i64 tgt, src, mask;
 
 REQUIRE_INSNS_FLAGS2(ctx, ISA310);
-REQUIRE_ALTIVEC(ctx);
+REQUIRE_VECTOR(ctx);
 
 tgt = tcg_temp_new_i64();
 src = tcg_temp_new_i64();
-- 
2.25.1




[PATCH v4 15/19] target/ppc: Move dcmp{u, o}[q], dts{tex, tsf, tsfi}[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dcmpu:DFP Compare Unordered
dcmpuq:   DFP Compare Unordered Quad
dcmpo:DFP Compare Ordered
dcmpoq:   DFP Compare Ordered Quad
dtstex:   DFP Test Exponent
dtstexq:  DFP Test Exponent Quad
dtstsf:   DFP Test Significance
dtstsfq:  DFP Test Significance Quad
dtstsfi:  DFP Test Significance Immediate
dtstsfiq: DFP Test Significance Immediate Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 
 target/ppc/helper.h | 20 
 target/ppc/insn32.decode| 29 +++
 target/ppc/translate/dfp-impl.c.inc | 74 +
 target/ppc/translate/dfp-ops.c.inc  | 31 
 5 files changed, 83 insertions(+), 91 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index da8eaaaff1..9be6809b33 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -507,8 +507,8 @@ static void CMPU_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
+DFP_HELPER_BF_AB(DCMPU, decNumberCompare, CMPU_PPs, 64)
+DFP_HELPER_BF_AB(DCMPUQ, decNumberCompare, CMPU_PPs, 128)
 
 static void CMPO_PPs(struct PPC_DFP *dfp)
 {
@@ -518,8 +518,8 @@ static void CMPO_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXVC(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
+DFP_HELPER_BF_AB(DCMPO, decNumberCompare, CMPO_PPs, 64)
+DFP_HELPER_BF_AB(DCMPOQ, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -633,8 +633,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
+DFP_HELPER_TSTEX(DTSTEX, 64)
+DFP_HELPER_TSTEX(DTSTEXQ, 128)
 
 #define DFP_HELPER_TSTSF(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
@@ -670,8 +670,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
+DFP_HELPER_TSTSF(DTSTSF, 64)
+DFP_HELPER_TSTSF(DTSTSFQ, 128)
 
 #define DFP_HELPER_TSTSFI(op, size) \
 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)   \
@@ -705,8 +705,8 @@ uint32_t helper_##op(CPUPPCState *env, uint32_t a, 
ppc_fprp_t *b)   \
 return dfp.crbf;\
 }
 
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
+DFP_HELPER_TSTSFI(DTSTSFI, 64)
+DFP_HELPER_TSTSFI(DTSTSFIQ, 128)
 
 static void QUA_PPs(struct PPC_DFP *dfp)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 1f00e47b82..22bf167b15 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -704,20 +704,20 @@ DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPO, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPOQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPU, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPUQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTEX, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTEXQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index c4a8cc7ec5..aaeccebca0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -50,6 +50,18 @@
 &X_bi   rt bi
 @X_bi   .. rt:5 bi:5 - .. - &X_bi
 
+&X_bf   bf ra rb
+@X_bf   .. 

[PATCH v4 16/19] target/ppc: Move dquai[q], drint{x, n}[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dquai:   DFP Quantize Immediate
dquaiq:  DFP Quantize Immediate Quad
drintx:  DFP Round to FP Integer With Inexact
drintxq: DFP Round to FP Integer With Inexact Quad
drintn:  DFP Round to FP Integer Without Inexact
drintnq: DFP Round to FP Integer Without Inexact Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 12 +++
 target/ppc/helper.h | 12 +++
 target/ppc/insn32.decode| 23 +
 target/ppc/translate/dfp-impl.c.inc | 51 +
 target/ppc/translate/dfp-ops.c.inc  | 18 --
 5 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 9be6809b33..df3e6c7cb1 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -751,8 +751,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
+DFP_HELPER_QUAI(DQUAI, 64)
+DFP_HELPER_QUAI(DQUAIQ, 128)
 
 #define DFP_HELPER_QUA(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,\
@@ -873,8 +873,8 @@ static void RINTX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
+DFP_HELPER_RINT(DRINTX, RINTX_PPs, 64)
+DFP_HELPER_RINT(DRINTXQ, RINTX_PPs, 128)
 
 static void RINTN_PPs(struct PPC_DFP *dfp)
 {
@@ -882,8 +882,8 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
+DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
+DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 22bf167b15..520cce8378 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -718,16 +718,16 @@ DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_3(dctdp, void, env, fprp, fprp)
 DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
 DEF_HELPER_3(drsp, void, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index aaeccebca0..f0e17580e0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,6 +77,18 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
+%z23_frtp   22:4 !function=times_2
+%z23_frbp   12:4 !function=times_2
+@Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_te_tb  te frt frb rmc rc:bool
+@Z23_te_tb  .. frt:5 te:5 frb:5 rmc:2  rc:1 &Z23_te_tb
+
+@Z23_te_tbp .. 0 te:5 0 rmc:2  rc:1 &Z23_te_tb 
frt=%z23_frtp frb=%z23_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -194,6 +206,17 @@ DTSTSFQ 11 ... -- . . 1010100010 -  
@X_bf_a_bp
 DTSTSFI 111011 ... - .. . 1010100011 -  @X_bf_uim
 DTSTSFIQ11 ... - .. . 1010100011 -  @X_bf_uim_bp
 
+### Decimal Floating-Point Quantum Adjustment Instructions
+
+DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
+DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
+
+DRINTX  111011 .  . . .. 01100011 . @Z23_tb
+DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
+
+DRINTN  111011 .  . . .. 11100011 . @Z23_tb
+DRINTNQ 11 . ---

[PATCH v4 05/19] libdecnumber: introduce decNumberFrom[U]Int128

2021-10-25 Thread Luis Pires
This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h |  2 ++
 libdecnumber/decNumber.c | 36 
 2 files changed, 38 insertions(+)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed07..0cf69c7db2 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -116,6 +116,8 @@
   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
   decNumber *decNumberFromInt64(decNumber *, int64_t);
   decNumber *decNumberFromUInt64(decNumber *, uint64_t);
+  decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
+  decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
   char * decNumberToString(const decNumber *, char *);
   char * decNumberToEngString(const decNumber *, char *);
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 1ffe458ad8..d7716ce175 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -167,6 +167,7 @@
 /* -- */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "libdecnumber/dconfig.h"
 #include "libdecnumber/decNumber.h"
 #include "libdecnumber/decNumberLocal.h"
@@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
 return dn;
 } /* decNumberFromUInt64 */
 
+decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
+{
+uint64_t unsig_hi = hi;
+if (hi < 0) {
+if (lo == 0) {
+unsig_hi = -unsig_hi;
+} else {
+unsig_hi = ~unsig_hi;
+lo = -lo;
+}
+}
+
+decNumberFromUInt128(dn, lo, unsig_hi);
+if (hi < 0) {
+dn->bits = DECNEG;/* sign needed */
+}
+return dn;
+} /* decNumberFromInt128 */
+
+decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
+{
+uint64_t rem;
+Unit *up; /* work pointer */
+decNumberZero(dn);/* clean */
+if (lo == 0 && hi == 0) {
+return dn;/* [or decGetDigits bad call] */
+}
+for (up = dn->lsu; hi > 0 || lo > 0; up++) {
+rem = divu128(&lo, &hi, DECDPUNMAX + 1);
+*up = (Unit)rem;
+}
+dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+return dn;
+} /* decNumberFromUInt128 */
+
 /* -- */
 /* to-int64 -- conversion to int64*/
 /**/
-- 
2.25.1




[PATCH v4 14/19] target/ppc: Move d{add, sub, mul, div, iex}[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dadd:  DFP Add
daddq: DFP Add Quad
dsub:  DFP Subtract
dsubq: DFP Subtract Quad
dmul:  DFP Multiply
dmulq: DFP Multiply Quad
ddiv:  DFP Divide
ddivq: DFP Divide Quad
diex:  DFP Insert Biased Exponent
diexq: DFP Insert Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 31 ++--
 target/ppc/translate/dfp-impl.c.inc | 56 ++---
 target/ppc/translate/dfp-ops.c.inc  | 19 --
 5 files changed, 76 insertions(+), 70 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index f3c1e525a3..da8eaaaff1 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -445,8 +445,8 @@ static void ADD_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_add(dfp);
 }
 
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
+DFP_HELPER_TAB(DADD, decNumberAdd, ADD_PPs, 64)
+DFP_HELPER_TAB(DADDQ, decNumberAdd, ADD_PPs, 128)
 
 static void SUB_PPs(struct PPC_DFP *dfp)
 {
@@ -458,8 +458,8 @@ static void SUB_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_subtract(dfp);
 }
 
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
+DFP_HELPER_TAB(DSUB, decNumberSubtract, SUB_PPs, 64)
+DFP_HELPER_TAB(DSUBQ, decNumberSubtract, SUB_PPs, 128)
 
 static void MUL_PPs(struct PPC_DFP *dfp)
 {
@@ -471,8 +471,8 @@ static void MUL_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIMZ(dfp);
 }
 
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
+DFP_HELPER_TAB(DMUL, decNumberMultiply, MUL_PPs, 64)
+DFP_HELPER_TAB(DMULQ, decNumberMultiply, MUL_PPs, 128)
 
 static void DIV_PPs(struct PPC_DFP *dfp)
 {
@@ -486,8 +486,8 @@ static void DIV_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIDI(dfp);
 }
 
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
+DFP_HELPER_TAB(DDIV, decNumberDivide, DIV_PPs, 64)
+DFP_HELPER_TAB(DDIVQ, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)
\
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)   
\
@@ -1299,8 +1299,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
+DFP_HELPER_IEX(DIEX, 64)
+DFP_HELPER_IEX(DIEXQ, 128)
 
 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 30e9247a5a..1f00e47b82 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -696,14 +696,14 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #define dh_alias_fprp ptr
 #define dh_ctype_fprp ppc_fprp_t *
 
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADD, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADDQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUB, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUBQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
@@ -744,8 +744,8 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
 DEF_HELPER_3(dxex, void, env, fprp, fprp)
 DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 38f8525d54..c4a8cc7ec5 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -37,6 +37,16 @@
 &X  rt ra rb
 @X  .. rt:5 ra:5 rb:5 .. .  &X
 
+&X_rc   rt ra rb rc:bool
+@X_rc   .. rt:5 ra:5 rb:5 .. rc:1   &X_rc
+
+%x_frtp 22:4 !function=times_2
+

[PATCH v4 12/19] target/ppc: Do not update nip on DFP instructions

2021-10-25 Thread Luis Pires
Before moving the existing DFP instructions to decodetree, drop the
nip update that shouldn't be done for these instructions.

Signed-off-by: Luis Pires 
---
 target/ppc/translate/dfp-impl.c.inc | 8 
 1 file changed, 8 deletions(-)

diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index e149777481..1431d955c6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -15,7 +15,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rd = gen_fprp_ptr(rD(ctx->opcode));  \
 ra = gen_fprp_ptr(rA(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
@@ -36,7 +35,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 ra = gen_fprp_ptr(rA(ctx->opcode));   \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -54,7 +52,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 uim = tcg_const_i32(UIMM5(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -72,7 +69,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
 ra = gen_fprp_ptr(rA(ctx->opcode));   \
 dcm = tcg_const_i32(DCM(ctx->opcode));\
 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
@@ -90,7 +86,6 @@ static void gen_##name(DisasContext *ctx) \
 gen_exception(ctx, POWERPC_EXCP_FPU); \
 return;   \
 } \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
 rt = gen_fprp_ptr(rD(ctx->opcode));   \
 rb = gen_fprp_ptr(rB(ctx->opcode));   \
 u32_1 = tcg_const_i32(u32f1(ctx->opcode));\
@@ -114,7 +109,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rt = gen_fprp_ptr(rD(ctx->opcode));  \
 ra = gen_fprp_ptr(rA(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
@@ -137,7 +131,6 @@ static void gen_##name(DisasContext *ctx)\
 gen_exception(ctx, POWERPC_EXCP_FPU);\
 return;  \
 }\
-gen_update_nip(ctx, ctx->base.pc_next - 4);  \
 rt = gen_fprp_ptr(rD(ctx->opcode));  \
 rb = gen_fprp_ptr(rB(ctx->opcode));  \
 gen_helper_##name(cpu_env, rt, rb);  \
@@ -157,7 +150,6 @@ static void gen_##name(DisasContext *ctx)  \
 gen_exception(ctx, POWERPC_EXCP_FPU);  \
 return;\
 }  \
-gen_update_nip(ctx, ctx->base.pc_next - 4);\
 rt = gen_fprp_ptr(rD(ctx->opcode));\
 rs = gen_fprp_ptr(fprfld(ctx->opcode));\
 i32 = tcg_const_i32(i32fld(ctx->opcode));  \
-- 
2.25.1




[PATCH v4 13/19] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-10-25 Thread Luis Pires
Move the following instructions to decodetree:
dtstdc:  DFP Test Data Class
dtstdcq: DFP Test Data Class Quad
dtstdg:  DFP Test Data Group
dtstdgq: DFP Test Data Group Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c |  8 +++
 target/ppc/helper.h |  8 +++
 target/ppc/insn32.decode| 14 
 target/ppc/translate/dfp-impl.c.inc | 35 +
 target/ppc/translate/dfp-ops.c.inc  | 10 -
 5 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 6ab46d7db5..f3c1e525a3 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -546,8 +546,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
+DFP_HELPER_TSTDC(DTSTDC, 64)
+DFP_HELPER_TSTDC(DTSTDCQ, 128)
 
 #define DFP_HELPER_TSTDG(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -601,8 +601,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
+DFP_HELPER_TSTDG(DTSTDG, 64)
+DFP_HELPER_TSTDG(DTSTDGQ, 128)
 
 #define DFP_HELPER_TSTEX(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 20041ce977..30e9247a5a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -708,10 +708,10 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
 DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6d97f9ae3b..38f8525d54 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -51,6 +51,12 @@
 %x_frbp 12:4 !function=times_2
 @X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
 
+&Z22_bf_fra bf fra dm
+@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   &Z22_bf_fra
+
+%z22_frap   17:4 !function=times_2
+@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -129,6 +135,14 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Test Instructions
+
+DTSTDC  111011 ... -- . .. 01110 -  @Z22_bf_fra
+DTSTDCQ 11 ... -- . .. 01110 -  @Z22_bf_frap
+
+DTSTDG  111011 ... -- . .. 011100010 -  @Z22_bf_fra
+DTSTDGQ 11 ... -- . .. 011100010 -  @Z22_bf_frap
+
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 1431d955c6..1a30c51467 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -60,21 +60,17 @@ static void gen_##name(DisasContext *ctx) \
 tcg_temp_free_ptr(rb);\
 }
 
-#define GEN_DFP_BF_A_DCM(name)\
-static void gen_##name(DisasContext *ctx) \
-{ \
-TCGv_ptr ra;  \
-TCGv_i32 dcm; \
-if (unlikely(!ctx->fpu_enabled)) {\
-gen_exception(ctx, POWERPC_EXCP_FPU); \
-return;   \
-} \
-ra = gen_fprp_ptr(rA(ctx->opcode));   \
-dcm = tcg_const_i32(DCM(ctx->opcode));\
-gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
-  cpu_env, ra, dcm);  \
-tcg_temp_free_ptr(ra);\
-tcg_temp_free_i32(dcm);   \
+#de

[PATCH v4 04/19] host-utils: add unit tests for divu128/divs128

2021-10-25 Thread Luis Pires
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 tests/unit/meson.build   |   1 +
 tests/unit/test-div128.c | 197 +++
 2 files changed, 198 insertions(+)
 create mode 100644 tests/unit/test-div128.c

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 7c297d7e5c..5ac2d9e943 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -23,6 +23,7 @@ tests = {
   # all code tested by test-x86-cpuid is inside topology.h
   'test-x86-cpuid': [],
   'test-cutils': [],
+  'test-div128': [],
   'test-shift128': [],
   'test-mul64': [],
   # all code tested by test-int128 is inside int128.h
diff --git a/tests/unit/test-div128.c b/tests/unit/test-div128.c
new file mode 100644
index 00..0bc25fe4a8
--- /dev/null
+++ b/tests/unit/test-div128.c
@@ -0,0 +1,197 @@
+/*
+ * Test 128-bit division functions
+ *
+ * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+
+typedef struct {
+uint64_t high;
+uint64_t low;
+uint64_t rhigh;
+uint64_t rlow;
+uint64_t divisor;
+uint64_t remainder;
+} test_data_unsigned;
+
+typedef struct {
+int64_t high;
+uint64_t low;
+int64_t rhigh;
+uint64_t rlow;
+int64_t divisor;
+int64_t remainder;
+} test_data_signed;
+
+static const test_data_unsigned test_table_unsigned[] = {
+/* Dividend fits in 64 bits */
+{ 0xULL, 0xULL,
+  0xULL, 0xULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0001ULL,
+  0xULL, 0x0001ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0003ULL,
+  0xULL, 0x0001ULL,
+  0x0002ULL, 0x0001ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x8000ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0xa000ULL,
+  0xULL, 0x0002ULL,
+  0x4000ULL, 0x2000ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x0001ULL,
+  0x8000ULL, 0xULL},
+
+/* Dividend > 64 bits, with MSB 0 */
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0xULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0x000dULL,
+  0x123456789abcdefeULL, 0x03456789abcdf03bULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0123456789abcdefULL, 0xeefedcba98765432ULL,
+  0x0010ULL, 0x0001ULL},
+
+/* Dividend > 64 bits, with MSB 1 */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0feeddccbbaa9988ULL, 0x7766554433221100ULL,
+  0x0010ULL, 0x000fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x000eULL, 0x00f0f0f0f0f0f35aULL,
+  0x123456789abcdefeULL, 0x0f8922bc55ef90c3ULL},
+
+/**
+ * Divisor == 64 bits, with MSB 1
+ * and high 64 bits of dividend >= divisor
+ * (for testing normalization)
+ */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xfddbb9977553310aULL,
+  0x8001ULL, 0x78899aabbccddf05ULL},
+
+/* Dividend > 64 bits, divisor almost as big */
+{ 0x0001ULL, 0x23456789abcdef01ULL,
+  0xULL, 0x

[PATCH v4 01/19] host-utils: move checks out of divu128/divs128

2021-10-25 Thread Luis Pires
In preparation for changing the divu128/divs128 implementations
to allow for quotients larger than 64 bits, move the div-by-zero
and overflow checks to the callers.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/hw/clock.h|  5 +++--
 include/qemu/host-utils.h | 36 +--
 target/ppc/int_helper.c   | 14 +-
 util/host-utils.c | 40 ++-
 4 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 11f67fb970..7443e6c4ab 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -324,8 +324,9 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 return 0;
 }
 /*
- * Ignore divu128() return value as we've caught div-by-zero and don't
- * need different behaviour for overflow.
+ * BUG: when CONFIG_INT128 is not defined, the current implementation of
+ * divu128 does not return a valid truncated quotient, so the result will
+ * be wrong.
  */
 divu128(&lo, &hi, clk->period);
 return lo;
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index ca9f3f021b..e82e6239af 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,36 +52,26 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
-{
-if (divisor == 0) {
-return 1;
-} else {
-__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
-__uint128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result > UINT64_MAX;
-}
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
+__uint128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 
-static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
 {
-if (divisor == 0) {
-return 1;
-} else {
-__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
-__int128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result != *plow;
-}
+__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
+__int128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f5dac3aa87..510faf24cf 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -104,10 +104,11 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 uint64_t rt = 0;
 int overflow = 0;
 
-overflow = divu128(&rt, &ra, rb);
-
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || ra >= rb)) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divu128(&rt, &ra, rb);
 }
 
 if (oe) {
@@ -122,10 +123,13 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 int64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
-int overflow = divs128(&rt, &ra, rb);
+int overflow = 0;
 
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || uabs64(ra) >= uabs64(rb))) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divs128(&rt, &ra, rb);
 }
 
 if (oe) {
diff --git a/util/host-utils.c b/util/host-utils.c
index a789a11b46..701a371843 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -86,24 +86,23 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 *phigh = rh;
 }
 
-/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
-/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
-/* remainder via phigh. */
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+/*
+ * Unsigned 128-by-64 division. Returns quotient via plow and
+ * remainder via phigh.
+ * The result must fit in 64 bits (plow) - otherwise, the result
+ * is undefined.
+ * This function will cause a division by zero if passed a zero divisor.
+ */

[PATCH v4 03/19] host-utils: add 128-bit quotient support to divu128/divs128

2021-10-25 Thread Luis Pires
These will be used to implement new decimal floating point
instructions from Power ISA 3.1.

The remainder is now returned directly by divu128/divs128,
freeing up phigh to receive the high 64 bits of the quotient.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/hw/clock.h|   6 +-
 include/qemu/host-utils.h |  20 +++---
 target/ppc/int_helper.c   |   9 +--
 util/host-utils.c | 127 ++
 4 files changed, 105 insertions(+), 57 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 7443e6c4ab..5c927cee7f 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -323,11 +323,7 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 if (clk->period == 0) {
 return 0;
 }
-/*
- * BUG: when CONFIG_INT128 is not defined, the current implementation of
- * divu128 does not return a valid truncated quotient, so the result will
- * be wrong.
- */
+
 divu128(&lo, &hi, clk->period);
 return lo;
 }
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 08a17e16e5..a3a7ced78d 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -56,26 +56,32 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+static inline uint64_t divu128(uint64_t *plow, uint64_t *phigh,
+   uint64_t divisor)
 {
 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
 __uint128_t result = dividend / divisor;
+
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+return dividend % divisor;
 }
 
-static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline int64_t divs128(uint64_t *plow, int64_t *phigh,
+  int64_t divisor)
 {
-__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
+__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
 __int128_t result = dividend / divisor;
+
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+return dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+uint64_t divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+int64_t divs128(uint64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 510faf24cf..eeb7781a9e 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -120,7 +120,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 
 uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t 
oe)
 {
-int64_t rt = 0;
+uint64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
 int overflow = 0;
@@ -2506,6 +2506,7 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 int cr;
 uint64_t lo_value;
 uint64_t hi_value;
+uint64_t rem;
 ppc_avr_t ret = { .u64 = { 0, 0 } };
 
 if (b->VsrSD(0) < 0) {
@@ -2541,10 +2542,10 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
  * In that case, we leave r unchanged.
  */
 } else {
-divu128(&lo_value, &hi_value, 1000ULL);
+rem = divu128(&lo_value, &hi_value, 1000ULL);
 
-for (i = 1; i < 16; hi_value /= 10, i++) {
-bcd_put_digit(&ret, hi_value % 10, i);
+for (i = 1; i < 16; rem /= 10, i++) {
+bcd_put_digit(&ret, rem % 10, i);
 }
 
 for (; i < 32; lo_value /= 10, i++) {
diff --git a/util/host-utils.c b/util/host-utils.c
index 701a371843..bcc772b8ec 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -87,72 +87,117 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 }
 
 /*
- * Unsigned 128-by-64 division. Returns quotient via plow and
- * remainder via phigh.
- * The result must fit in 64 bits (plow) - otherwise, the result
- * is undefined.
- * This function will cause a division by zero if passed a zero divisor.
+ * Unsigned 128-by-64 division.
+ * Returns the remainder.
+ * Returns quotient via plow and phigh.
+ * Also returns the remainder via the function return value.
  */
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+uint64_t divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
 {
 uint64_t dhi = *phigh;
 uint64_t dlo = *plow;
-unsigned i;
-uint64_t carry

[PATCH v4 08/19] target/ppc: Implement DCFFIXQQ

2021-10-25 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dcffixqq: DFP Convert From Fixed Quadword Quad

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/dfp_helper.c | 12 
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  8 
 target/ppc/translate.c  |  5 +
 target/ppc/translate/dfp-impl.c.inc | 17 +
 5 files changed, 43 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 07341a69f5..6b837c4450 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -970,6 +970,18 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
+void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
+{
+struct PPC_DFP dfp;
+
+dfp_prepare_decimal128(&dfp, NULL, NULL, env);
+decNumberFromInt128(&dfp.t, (uint64_t)b->VsrD(1), (int64_t)b->VsrD(0));
+dfp_finalize_decimal128(&dfp);
+CFFIX_PPs(&dfp);
+
+set_dfp128(t, &dfp.vt);
+}
+
 #define DFP_HELPER_CTFIX(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)  \
 { \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fff7bd46ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -734,6 +734,7 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp)
 DEF_HELPER_3(drdpq, void, env, fprp, fprp)
 DEF_HELPER_3(dcffix, void, env, fprp, fprp)
 DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..92ea2d0739 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -43,6 +43,10 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_frtp_vrb frtp vrb
+%x_frtp 22:4 !function=times_2
+@X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -121,6 +125,10 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Conversion Instructions
+
+DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 48a484eef6..6224cb3211 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7438,6 +7438,11 @@ static inline void set_avr64(int regno, TCGv_i64 src, 
bool high)
 /*
  * Helpers for decodetree used by !function for decoding arguments.
  */
+static int times_2(DisasContext *ctx, int x)
+{
+return x * 2;
+}
+
 static int times_4(DisasContext *ctx, int x)
 {
 return x * 4;
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 6c556dc2e1..d5b66567a6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -230,3 +230,20 @@ GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 #undef GEN_DFP_T_A_B_I32_Rc
 #undef GEN_DFP_T_B_Rc
 #undef GEN_DFP_T_FPR_I32_Rc
+
+static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_fprp_ptr(a->frtp);
+rb = gen_avr_ptr(a->vrb);
+gen_helper_DCFFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v4 02/19] host-utils: move udiv_qrnnd() to host-utils

2021-10-25 Thread Luis Pires
Move udiv_qrnnd() from include/fpu/softfloat-macros.h to host-utils,
so it can be reused by divu128().

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/fpu/softfloat-macros.h | 82 --
 include/qemu/host-utils.h  | 81 +
 2 files changed, 81 insertions(+), 82 deletions(-)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index 81c3fe8256..f35cdbfa63 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -8,7 +8,6 @@
  * so some portions are provided under:
  *  the SoftFloat-2a license
  *  the BSD license
- *  GPL-v2-or-later
  *
  * Any future contributions to this file after December 1st 2014 will be
  * taken to be licensed under the Softfloat-2a license unless specifically
@@ -75,10 +74,6 @@ this code that are retained.
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* Portions of this work are licensed under the terms of the GNU GPL,
- * version 2 or later. See the COPYING file in the top-level directory.
- */
-
 #ifndef FPU_SOFTFLOAT_MACROS_H
 #define FPU_SOFTFLOAT_MACROS_H
 
@@ -585,83 +580,6 @@ static inline uint64_t estimateDiv128To64(uint64_t a0, 
uint64_t a1, uint64_t b)
 
 }
 
-/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd
- * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
- *
- * Licensed under the GPLv2/LGPLv3
- */
-static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
-  uint64_t n0, uint64_t d)
-{
-#if defined(__x86_64__)
-uint64_t q;
-asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
-return q;
-#elif defined(__s390x__) && !defined(__clang__)
-/* Need to use a TImode type to get an even register pair for DLGR.  */
-unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
-asm("dlgr %0, %1" : "+r"(n) : "r"(d));
-*r = n >> 64;
-return n;
-#elif defined(_ARCH_PPC64) && defined(_ARCH_PWR7)
-/* From Power ISA 2.06, programming note for divdeu.  */
-uint64_t q1, q2, Q, r1, r2, R;
-asm("divdeu %0,%2,%4; divdu %1,%3,%4"
-: "=&r"(q1), "=r"(q2)
-: "r"(n1), "r"(n0), "r"(d));
-r1 = -(q1 * d); /* low part of (n1<<64) - (q1 * d) */
-r2 = n0 - (q2 * d);
-Q = q1 + q2;
-R = r1 + r2;
-if (R >= d || R < r2) { /* overflow implies R > d */
-Q += 1;
-R -= d;
-}
-*r = R;
-return Q;
-#else
-uint64_t d0, d1, q0, q1, r1, r0, m;
-
-d0 = (uint32_t)d;
-d1 = d >> 32;
-
-r1 = n1 % d1;
-q1 = n1 / d1;
-m = q1 * d0;
-r1 = (r1 << 32) | (n0 >> 32);
-if (r1 < m) {
-q1 -= 1;
-r1 += d;
-if (r1 >= d) {
-if (r1 < m) {
-q1 -= 1;
-r1 += d;
-}
-}
-}
-r1 -= m;
-
-r0 = r1 % d1;
-q0 = r1 / d1;
-m = q0 * d0;
-r0 = (r0 << 32) | (uint32_t)n0;
-if (r0 < m) {
-q0 -= 1;
-r0 += d;
-if (r0 >= d) {
-if (r0 < m) {
-q0 -= 1;
-r0 += d;
-}
-}
-}
-r0 -= m;
-
-*r = r0;
-return (q1 << 32) | q0;
-#endif
-}
-
 /*
 | Returns an approximation to the square root of the 32-bit significand given
 | by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index e82e6239af..08a17e16e5 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -23,6 +23,10 @@
  * THE SOFTWARE.
  */
 
+/* Portions of this work are licensed under the terms of the GNU GPL,
+ * version 2 or later. See the COPYING file in the top-level directory.
+ */
+
 #ifndef HOST_UTILS_H
 #define HOST_UTILS_H
 
@@ -726,4 +730,81 @@ void urshift(uint64_t *plow, uint64_t *phigh, int32_t 
shift);
  */
 void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow);
 
+/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd
+ * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
+ *
+ * Licensed under the GPLv2/LGPLv3
+ */
+static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
+  uint64_t n0, uint64_t d)
+{
+#if defined(__x86_64__)
+uint64_t q;
+asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
+return q;
+#elif defined(__s390x__) && !defined(__clang__)
+/* Need to use a TImode type to get an even register pair for DLGR.  */
+unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
+asm("dlgr %0, %1" : "+r"(n) 

[PATCH v4 00/19] target/ppc: DFP instructions using decodetree

2021-10-25 Thread Luis Pires
This series moves all existing DFP instructions to decodetree and
implements the 2 new instructions (dcffixqq and dctfixqq) from
Power ISA 3.1.

In order to implement dcffixqq, divu128/divs128 were modified to
support 128-bit quotients (previously, they were limited to 64-bit
quotients), along with adjustments being made to their existing callers.
libdecnumber was also expanded to allow creating decimal numbers from
128-bit integers.

Similarly, for dctfixqq, mulu128 (host-utils) and decNumberIntegralToInt128
(libdecnumber) were introduced to support 128-bit integers.

The remaining patches of this series move all of the already existing
DFP instructions to decodetree, and end up removing dfp-ops.c.inc, which
is no longer needed.

NOTE 1: The previous, non-decodetree code, was updating ctx->nip for all the
DFP instructions. I've removed that, but it would be great if someone could
confirm that updating nip really wasn't necessary.

NOTE 2: Some arithmetic function support for 128-bit integers was added,
for now, still using 64-bit pairs. In the near future, I think we should
modify all of them to use Int128 (and introduce UInt128). But I'll send
out an RFC to discuss how to do that in another patch series.

NOTE 3: The helper names are in uppercase, to match the instruction
names and to simplify the macros that define trans* functions.
Previously, this wasn't the case, as we were using lowercase instruction
names in the pre-decodetree code. Another standalone patch will be sent
later on, changing to uppercase the other new (decodetree) helpers whose
names are directly related to instruction names, eventually making PPC
helper names consistent.

The only patch still needing review is:
[PATCH v4 12/19] target/ppc: Do not update nip on DFP instructions

Changes in v4:
- Rebased against dgibson/ppc-for-6.2
- Skipped patches that were already applied (v3 1-4)
- Changed divu128/divs128 to return the remainder (rth)
- Moved changes that drop nip updates to a separate patch (rth)

Changes in v3:
- Split the uabs64 patch in 2
- Included patch to fix missing zero-extension in divs128
- Folded divisor == 0 into the dhi == 0 case in divu128
- Moved udiv_qrnnd from softfloat-macros.h to host-utils.h
- Used udiv_qrnnd in divu128
- Replaced int with bool in divs128
- Added unit test to check the divisor normalization in divu128
- Removed 'inline' from times_* functions in ppc/translate.c
- Used uadd64_overflow in mulu128
- Removed unnecessary 'else' from decNumberIntegralToInt128

Changes in v2:
- Renamed abs64() to uabs64()

Bruno Larsen (1):
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

Fernando Valle (1):
  target/ppc: Introduce REQUIRE_FPU

Luis Pires (17):
  host-utils: move checks out of divu128/divs128
  host-utils: move udiv_qrnnd() to host-utils
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Do not update nip on DFP instructions
  target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree
  target/ppc: Move d{add,sub,mul,div,iex}[q] to decodetree
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree
  target/ppc: Move dquai[q], drint{x,n}[q] to decodetree
  target/ppc: Move dqua[q], drrnd[q] to decodetree
  target/ppc: Move dct{dp,qpq},dr{sp,dpq},dc{f,t}fix[q],dxex[q] to
decodetree
  target/ppc: Move ddedpd[q],denbcd[q],dscli[q],dscri[q] to decodetree

 include/fpu/softfloat-macros.h |  82 -
 include/hw/clock.h |   5 +-
 include/libdecnumber/decNumber.h   |   4 +
 include/libdecnumber/decNumberLocal.h  |   2 +-
 include/qemu/host-utils.h  | 157 +++--
 libdecnumber/decContext.c  |   7 +-
 libdecnumber/decNumber.c   | 131 
 target/ppc/dfp_helper.c| 168 +++---
 target/ppc/helper.h| 106 ---
 target/ppc/insn32.decode   | 171 ++
 target/ppc/int_helper.c|  23 +-
 target/ppc/translate.c |  23 +-
 target/ppc/translate/dfp-impl.c.inc| 419 -
 target/ppc/translate/dfp-ops.c.inc | 165 --
 target/ppc/translate/vector-impl.c.inc |  10 +-
 tests/unit/meson.build |   1 +
 tests/unit/test-div128.c   | 197 
 util/host-utils.c  | 137 +---
 18 files changed, 1148 insertions(+), 660 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc
 create mode 100644 tests/unit/test-div128.c

-- 
2.25.1




[PATCH v3 19/22] target/ppc: Move dquai[q], drint{x, n}[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
dquai:   DFP Quantize Immediate
dquaiq:  DFP Quantize Immediate Quad
drintx:  DFP Round to FP Integer With Inexact
drintxq: DFP Round to FP Integer With Inexact Quad
drintn:  DFP Round to FP Integer Without Inexact
drintnq: DFP Round to FP Integer Without Inexact Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 12 +++
 target/ppc/helper.h | 12 +++
 target/ppc/insn32.decode| 23 +
 target/ppc/translate/dfp-impl.c.inc | 52 +
 target/ppc/translate/dfp-ops.c.inc  | 18 --
 5 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b6634134d9..56d8846308 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -752,8 +752,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
+DFP_HELPER_QUAI(DQUAI, 64)
+DFP_HELPER_QUAI(DQUAIQ, 128)
 
 #define DFP_HELPER_QUA(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,\
@@ -874,8 +874,8 @@ static void RINTX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
+DFP_HELPER_RINT(DRINTX, RINTX_PPs, 64)
+DFP_HELPER_RINT(DRINTXQ, RINTX_PPs, 128)
 
 static void RINTN_PPs(struct PPC_DFP *dfp)
 {
@@ -883,8 +883,8 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
+DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
+DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 22bf167b15..520cce8378 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -718,16 +718,16 @@ DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_3(dctdp, void, env, fprp, fprp)
 DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
 DEF_HELPER_3(drsp, void, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index aaeccebca0..f0e17580e0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,6 +77,18 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
+%z23_frtp   22:4 !function=times_2
+%z23_frbp   12:4 !function=times_2
+@Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_te_tb  te frt frb rmc rc:bool
+@Z23_te_tb  .. frt:5 te:5 frb:5 rmc:2  rc:1 &Z23_te_tb
+
+@Z23_te_tbp .. 0 te:5 0 rmc:2  rc:1 &Z23_te_tb 
frt=%z23_frtp frb=%z23_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -194,6 +206,17 @@ DTSTSFQ 11 ... -- . . 1010100010 -  
@X_bf_a_bp
 DTSTSFI 111011 ... - .. . 1010100011 -  @X_bf_uim
 DTSTSFIQ11 ... - .. . 1010100011 -  @X_bf_uim_bp
 
+### Decimal Floating-Point Quantum Adjustment Instructions
+
+DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
+DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
+
+DRINTX  111011 .  . . .. 01100011 . @Z23_tb
+DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
+
+DRINTN  111011 .  . . .. 11100011 . @Z23_tb
+DRINTNQ 11 .  . . .. 11100011 . @Z23_t

[PATCH v3 17/22] target/ppc: Move d{add, sub, mul, div, iex}[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
dadd:  DFP Add
daddq: DFP Add Quad
dsub:  DFP Subtract
dsubq: DFP Subtract Quad
dmul:  DFP Multiply
dmulq: DFP Multiply Quad
ddiv:  DFP Divide
ddivq: DFP Divide Quad
diex:  DFP Insert Biased Exponent
diexq: DFP Insert Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 20 +-
 target/ppc/helper.h | 20 +-
 target/ppc/insn32.decode| 31 +++-
 target/ppc/translate/dfp-impl.c.inc | 57 ++---
 target/ppc/translate/dfp-ops.c.inc  | 19 --
 5 files changed, 76 insertions(+), 71 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b4945fe48f..14080cecc8 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -446,8 +446,8 @@ static void ADD_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_add(dfp);
 }
 
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
+DFP_HELPER_TAB(DADD, decNumberAdd, ADD_PPs, 64)
+DFP_HELPER_TAB(DADDQ, decNumberAdd, ADD_PPs, 128)
 
 static void SUB_PPs(struct PPC_DFP *dfp)
 {
@@ -459,8 +459,8 @@ static void SUB_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_subtract(dfp);
 }
 
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
+DFP_HELPER_TAB(DSUB, decNumberSubtract, SUB_PPs, 64)
+DFP_HELPER_TAB(DSUBQ, decNumberSubtract, SUB_PPs, 128)
 
 static void MUL_PPs(struct PPC_DFP *dfp)
 {
@@ -472,8 +472,8 @@ static void MUL_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIMZ(dfp);
 }
 
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
+DFP_HELPER_TAB(DMUL, decNumberMultiply, MUL_PPs, 64)
+DFP_HELPER_TAB(DMULQ, decNumberMultiply, MUL_PPs, 128)
 
 static void DIV_PPs(struct PPC_DFP *dfp)
 {
@@ -487,8 +487,8 @@ static void DIV_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIDI(dfp);
 }
 
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
+DFP_HELPER_TAB(DDIV, decNumberDivide, DIV_PPs, 64)
+DFP_HELPER_TAB(DDIVQ, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)
\
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)   
\
@@ -1299,8 +1299,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
+DFP_HELPER_IEX(DIEX, 64)
+DFP_HELPER_IEX(DIEXQ, 128)
 
 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 30e9247a5a..1f00e47b82 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -696,14 +696,14 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #define dh_alias_fprp ptr
 #define dh_ctype_fprp ppc_fprp_t *
 
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADD, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADDQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUB, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUBQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
@@ -744,8 +744,8 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
 DEF_HELPER_3(dxex, void, env, fprp, fprp)
 DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 38f8525d54..c4a8cc7ec5 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -37,6 +37,16 @@
 &X  rt ra rb
 @X  .. rt:5 ra:5 rb:5 .. .  &X
 
+&X_rc   rt ra rb rc:bool
+@X_rc   .. rt:5 ra:5 rb:5 .. rc:1   &X_rc
+
+%x_frtp 22:4 !function=times_2
+%x_frap 17:4 !function=times_2
+

[PATCH v3 15/22] target/ppc: Implement DCTFIXQQ

2021-09-10 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dctfixqq: DFP Convert To Fixed Quadword Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 53 +
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  5 +++
 target/ppc/translate/dfp-impl.c.inc | 17 +
 4 files changed, 76 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 01a7ead783..ef1c370c3c 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -51,6 +51,12 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 dfp[1].VsrD(0) = src->VsrD(1);
 }
 
+static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
+{
+dst->VsrD(0) = src->VsrD(0);
+dst->VsrD(1) = src->VsrD(1);
+}
+
 struct PPC_DFP {
 CPUPPCState *env;
 ppc_vsr_t vt, va, vb;
@@ -1019,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
+void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, 0, b, env);
+
+if (unlikely(decNumberIsSpecial(&dfp.b))) {
+uint64_t invalid_flags = FP_VX | FP_VXCVI;
+if (decNumberIsInfinite(&dfp.b)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+} else { /* NaN */
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+if (decNumberIsSNaN(&dfp.b)) {
+invalid_flags |= FP_VXSNAN;
+}
+}
+dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);
+} else if (unlikely(decNumberIsZero(&dfp.b))) {
+dfp.vt.VsrD(0) = 0;
+dfp.vt.VsrD(1) = 0;
+} else {
+decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);
+decNumberIntegralToInt128(&dfp.b, &dfp.context,
+&dfp.vt.VsrD(1), &dfp.vt.VsrD(0));
+if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);
+} else {
+dfp_check_for_XX(&dfp);
+}
+}
+
+set_dfp128_to_avr(t, &dfp.vt);
+}
+
 static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
 unsigned n)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fff7bd46ad..20041ce977 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -737,6 +737,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 92ea2d0739..6d97f9ae3b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -47,6 +47,10 @@
 %x_frtp 22:4 !function=times_2
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
+&X_vrt_frbp vrt frbp
+%x_frbp 12:4 !function=times_2
+@X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -128,6 +132,7 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+DCTFIXQQ11 . 1 . 100010 -   @X_vrt_frbp
 
 ## Vector Bit Manipulation Instruction
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index d5b66567a6..e149777481 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ 
*a)
 
 return true;
 }
+
+static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_avr_ptr(a->vrt);
+rb = gen_fprp_ptr(a->frbp);
+gen_helper_DCTFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v3 22/22] target/ppc: Move ddedpd[q], denbcd[q], dscli[q], dscri[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
ddedpd:  DFP Decode DPD To BCD
ddedpdq: DFP Decode DPD To BCD Quad
denbcd:  DFP Encode BCD To DPD
denbcdq: DFP Encode BCD To DPD Quad
dscli:   DFP Shift Significand Left Immediate
dscliq:  DFP Shift Significand Left Immediate Quad
dscri:   DFP Shift Significand Right Immediate
dscriq:  DFP Shift Significand Right Immediate Quad

Also deleted dfp-ops.c.inc, now that all PPC DFP instructions were
moved to decodetree.

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 16 -
 target/ppc/helper.h | 16 -
 target/ppc/insn32.decode| 28 +++
 target/ppc/translate.c  |  2 --
 target/ppc/translate/dfp-impl.c.inc | 54 +
 target/ppc/translate/dfp-ops.c.inc  | 40 -
 6 files changed, 68 insertions(+), 88 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 7bb394c02b..0dcb1249f7 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1131,8 +1131,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
+DFP_HELPER_DEDPD(DDEDPD, 64)
+DFP_HELPER_DEDPD(DDEDPDQ, 128)
 
 static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
@@ -1199,8 +1199,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 set_dfp##size(t, &dfp.vt);   \
 }
 
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
+DFP_HELPER_ENBCD(DENBCD, 64)
+DFP_HELPER_ENBCD(DENBCDQ, 128)
 
 #define DFP_HELPER_XEX(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
@@ -1387,7 +1387,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
+DFP_HELPER_SHIFT(DSCLI, 64, 1)
+DFP_HELPER_SHIFT(DSCLIQ, 128, 1)
+DFP_HELPER_SHIFT(DSCRI, 64, 0)
+DFP_HELPER_SHIFT(DSCRIQ, 128, 0)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4c2a349ce6..6fa3e15fe9 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -738,18 +738,18 @@ DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPDQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCDQ, void, env, fprp, fprp, i32)
 DEF_HELPER_3(DXEX, void, env, fprp, fprp)
 DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRIQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLIQ, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
 DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2ce8b0ab95..6aec1c0728 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -74,6 +74,16 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_tb_sp_rc rt rb sp rc:bool
+@X_tb_sp_rc .. rt:5 sp:2 ... rb:5 .. rc:1   &X_tb_sp_rc
+
+@X_tbp_sp_rc.. 0 sp:2 ... 0 .. rc:1 &X_tb_sp_rc 
rt=%x_frtp rb=%x_frbp
+
+&X_tb_s_rc  rt rb s:bool rc:bool
+@X_tb_s_rc  .. rt:5 s:1  rb:5 .. rc:1   &X_tb_s_rc
+
+@X_tbp_s_rc .. 0 s:1  0 .. rc:1 &X_tb_s_rc 
rt=%x_frtp rb=%x_frbp
+
 &X_frtp_vrb frtp vrb
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
@@ -86,6 +96,12 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z22_ta_sh_rc   rt ra sh rc:bool
+@Z22_ta_sh_rc   .. rt:5 ra:5 sh:6 . rc:1&Z22_ta

[PATCH v3 21/22] target/ppc: Move dct{dp, qpq}, dr{sp, dpq}, dc{f, t}fix[q], dxex[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
dctdp:   DFP Convert To DFP Long
dctqpq:  DFP Convert To DFP Extended
drsp:DFP Round To DFP Short
drdpq:   DFP Round To DFP Long
dcffix:  DFP Convert From Fixed
dcffixq: DFP Convert From Fixed Quad
dctfix:  DFP Convert To Fixed
dctfixq: DFP Convert To Fixed Quad
dxex:DFP Extract Biased Exponent
dxexq:   DFP Extract Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 23 
 target/ppc/translate/dfp-impl.c.inc | 55 ++---
 target/ppc/translate/dfp-ops.c.inc  | 22 
 5 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 9c75cbb79b..7bb394c02b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -886,7 +886,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
 DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTDP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -902,7 +902,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 dfp_set_FPRF_from_FRT(&dfp);
 }
 
-void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTQPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -917,7 +917,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp128(t, &dfp.vt);
 }
 
-void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRSP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 uint32_t t_short = 0;
@@ -935,7 +935,7 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp64(t, &vt);
 }
 
-void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRDPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 dfp_prepare_decimal128(&dfp, 0, b, env);
@@ -973,8 +973,8 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_XX(dfp);
 }
 
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
+DFP_HELPER_CFFIX(DCFFIX, 64)
+DFP_HELPER_CFFIX(DCFFIXQ, 128)
 
 void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
 {
@@ -1022,8 +1022,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 set_dfp64(t, &dfp.vt);\
 }
 
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
+DFP_HELPER_CTFIX(DCTFIX, 64)
+DFP_HELPER_CTFIX(DCTFIXQ, 128)
 
 void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
 {
@@ -1233,8 +1233,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b) \
 }  \
 }
 
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
+DFP_HELPER_XEX(DXEX, 64)
+DFP_HELPER_XEX(DXEXQ, 128)
 
 static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cb05cc168c..4c2a349ce6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -728,22 +728,22 @@ DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTDP, void, env, fprp, fprp)
+DEF_HELPER_3(DCTQPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DRSP, void, env, fprp, fprp)
+DEF_HELPER_3(DRDPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
+DEF_HELPER_3(DXEX, void, env, fprp, fprp)
+DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
diff --git

[PATCH v3 10/22] target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

2021-09-10 Thread Luis Pires
From: Bruno Larsen 

Move REQUIRE_ALTIVEC to translate.c and rename it to REQUIRE_VECTOR.

Signed-off-by: Bruno Larsen 
Signed-off-by: Matheus Ferst 
Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
---
 target/ppc/translate.c |  8 
 target/ppc/translate/vector-impl.c.inc | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 171b216e17..4749ecdaa9 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7453,6 +7453,14 @@ static int times_4(DisasContext *ctx, int x)
 # define REQUIRE_64BIT(CTX)  REQUIRE_INSNS_FLAGS(CTX, 64B)
 #endif
 
+#define REQUIRE_VECTOR(CTX) \
+do {\
+if (unlikely(!(CTX)->altivec_enabled)) {\
+gen_exception((CTX), POWERPC_EXCP_VPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
diff --git a/target/ppc/translate/vector-impl.c.inc 
b/target/ppc/translate/vector-impl.c.inc
index 117ce9b137..197e903337 100644
--- a/target/ppc/translate/vector-impl.c.inc
+++ b/target/ppc/translate/vector-impl.c.inc
@@ -17,20 +17,12 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define REQUIRE_ALTIVEC(CTX) \
-do {\
-if (unlikely(!(CTX)->altivec_enabled)) {\
-gen_exception((CTX), POWERPC_EXCP_VPU); \
-return true;\
-}   \
-} while (0)
-
 static bool trans_VCFUGED(DisasContext *ctx, arg_VX *a)
 {
 TCGv_i64 tgt, src, mask;
 
 REQUIRE_INSNS_FLAGS2(ctx, ISA310);
-REQUIRE_ALTIVEC(ctx);
+REQUIRE_VECTOR(ctx);
 
 tgt = tcg_temp_new_i64();
 src = tcg_temp_new_i64();
-- 
2.25.1




[PATCH v3 16/22] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
dtstdc:  DFP Test Data Class
dtstdcq: DFP Test Data Class Quad
dtstdg:  DFP Test Data Group
dtstdgq: DFP Test Data Group Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c |  8 +++
 target/ppc/helper.h |  8 +++
 target/ppc/insn32.decode| 14 +++
 target/ppc/translate/dfp-impl.c.inc | 36 -
 target/ppc/translate/dfp-ops.c.inc  | 10 
 5 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index ef1c370c3c..b4945fe48f 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -547,8 +547,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
+DFP_HELPER_TSTDC(DTSTDC, 64)
+DFP_HELPER_TSTDC(DTSTDCQ, 128)
 
 #define DFP_HELPER_TSTDG(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -602,8 +602,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
+DFP_HELPER_TSTDG(DTSTDG, 64)
+DFP_HELPER_TSTDG(DTSTDGQ, 128)
 
 #define DFP_HELPER_TSTEX(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 20041ce977..30e9247a5a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -708,10 +708,10 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
 DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6d97f9ae3b..38f8525d54 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -51,6 +51,12 @@
 %x_frbp 12:4 !function=times_2
 @X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
 
+&Z22_bf_fra bf fra dm
+@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   &Z22_bf_fra
+
+%z22_frap   17:4 !function=times_2
+@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -129,6 +135,14 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Test Instructions
+
+DTSTDC  111011 ... -- . .. 01110 -  @Z22_bf_fra
+DTSTDCQ 11 ... -- . .. 01110 -  @Z22_bf_frap
+
+DTSTDG  111011 ... -- . .. 011100010 -  @Z22_bf_fra
+DTSTDGQ 11 ... -- . .. 011100010 -  @Z22_bf_frap
+
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index e149777481..b9029841b3 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -63,22 +63,17 @@ static void gen_##name(DisasContext *ctx) \
 tcg_temp_free_ptr(rb);\
 }
 
-#define GEN_DFP_BF_A_DCM(name)\
-static void gen_##name(DisasContext *ctx) \
-{ \
-TCGv_ptr ra;  \
-TCGv_i32 dcm; \
-if (unlikely(!ctx->fpu_enabled)) {\
-gen_exception(ctx, POWERPC_EXCP_FPU); \
-return;   \
-} \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
-ra = gen_fprp_ptr(rA(ctx->opcode));   \
-dcm = tcg_const_i32(DCM(ctx->opcode));\
-gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
-  cpu_env, ra, dcm);  \
-tcg_temp_free_ptr(ra);\
-tcg_temp_free_i32(dcm);   \
+

[PATCH v3 18/22] target/ppc: Move dcmp{u, o}[q], dts{tex, tsf, tsfi}[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
dcmpu:DFP Compare Unordered
dcmpuq:   DFP Compare Unordered Quad
dcmpo:DFP Compare Ordered
dcmpoq:   DFP Compare Ordered Quad
dtstex:   DFP Test Exponent
dtstexq:  DFP Test Exponent Quad
dtstsf:   DFP Test Significance
dtstsfq:  DFP Test Significance Quad
dtstsfi:  DFP Test Significance Immediate
dtstsfiq: DFP Test Significance Immediate Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 20 
 target/ppc/helper.h | 20 
 target/ppc/insn32.decode| 29 +++
 target/ppc/translate/dfp-impl.c.inc | 76 +
 target/ppc/translate/dfp-ops.c.inc  | 31 
 5 files changed, 83 insertions(+), 93 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 14080cecc8..b6634134d9 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -508,8 +508,8 @@ static void CMPU_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
+DFP_HELPER_BF_AB(DCMPU, decNumberCompare, CMPU_PPs, 64)
+DFP_HELPER_BF_AB(DCMPUQ, decNumberCompare, CMPU_PPs, 128)
 
 static void CMPO_PPs(struct PPC_DFP *dfp)
 {
@@ -519,8 +519,8 @@ static void CMPO_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXVC(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
+DFP_HELPER_BF_AB(DCMPO, decNumberCompare, CMPO_PPs, 64)
+DFP_HELPER_BF_AB(DCMPOQ, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -634,8 +634,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
+DFP_HELPER_TSTEX(DTSTEX, 64)
+DFP_HELPER_TSTEX(DTSTEXQ, 128)
 
 #define DFP_HELPER_TSTSF(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
@@ -671,8 +671,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
+DFP_HELPER_TSTSF(DTSTSF, 64)
+DFP_HELPER_TSTSF(DTSTSFQ, 128)
 
 #define DFP_HELPER_TSTSFI(op, size) \
 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)   \
@@ -706,8 +706,8 @@ uint32_t helper_##op(CPUPPCState *env, uint32_t a, 
ppc_fprp_t *b)   \
 return dfp.crbf;\
 }
 
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
+DFP_HELPER_TSTSFI(DTSTSFI, 64)
+DFP_HELPER_TSTSFI(DTSTSFIQ, 128)
 
 static void QUA_PPs(struct PPC_DFP *dfp)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 1f00e47b82..22bf167b15 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -704,20 +704,20 @@ DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPO, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPOQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPU, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPUQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTEX, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTEXQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index c4a8cc7ec5..aaeccebca0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -50,6 +50,18 @@
 &X_bi   rt bi
 @X_bi   .. rt:5 bi:5 - .. - &X_bi
 
+&X_bf   bf ra rb
+@X_bf   .. bf:3 .. ra:5 rb:5 .. .

[PATCH v3 09/22] libdecnumber: introduce decNumberFrom[U]Int128

2021-09-10 Thread Luis Pires
This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h |  2 ++
 libdecnumber/decNumber.c | 36 
 2 files changed, 38 insertions(+)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed07..0cf69c7db2 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -116,6 +116,8 @@
   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
   decNumber *decNumberFromInt64(decNumber *, int64_t);
   decNumber *decNumberFromUInt64(decNumber *, uint64_t);
+  decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
+  decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
   char * decNumberToString(const decNumber *, char *);
   char * decNumberToEngString(const decNumber *, char *);
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 1ffe458ad8..75c09ba052 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -167,6 +167,7 @@
 /* -- */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "libdecnumber/dconfig.h"
 #include "libdecnumber/decNumber.h"
 #include "libdecnumber/decNumberLocal.h"
@@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
 return dn;
 } /* decNumberFromUInt64 */
 
+decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
+{
+uint64_t unsig_hi = hi;
+if (hi < 0) {
+if (lo == 0) {
+unsig_hi = -unsig_hi;
+} else {
+unsig_hi = ~unsig_hi;
+lo = -lo;
+}
+}
+
+decNumberFromUInt128(dn, lo, unsig_hi);
+if (hi < 0) {
+dn->bits = DECNEG;/* sign needed */
+}
+return dn;
+} /* decNumberFromInt128 */
+
+decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
+{
+uint64_t rem;
+Unit *up; /* work pointer */
+decNumberZero(dn);/* clean */
+if (lo == 0 && hi == 0) {
+return dn;/* [or decGetDigits bad call] */
+}
+for (up = dn->lsu; hi > 0 || lo > 0; up++) {
+divu128(&lo, &hi, &rem, DECDPUNMAX + 1);
+*up = (Unit)rem;
+}
+dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+return dn;
+} /* decNumberFromUInt128 */
+
 /* -- */
 /* to-int64 -- conversion to int64*/
 /**/
-- 
2.25.1




[PATCH v3 12/22] target/ppc: Implement DCFFIXQQ

2021-09-10 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dcffixqq: DFP Convert From Fixed Quadword Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 11 +++
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  8 
 target/ppc/translate.c  |  5 +
 target/ppc/translate/dfp-impl.c.inc | 17 +
 5 files changed, 42 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 07341a69f5..01a7ead783 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -970,6 +970,17 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
+void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, NULL, NULL, env);
+decNumberFromInt128(&dfp.t, (uint64_t)b->VsrD(1), (int64_t)b->VsrD(0));
+dfp_finalize_decimal128(&dfp);
+CFFIX_PPs(&dfp);
+
+set_dfp128(t, &dfp.vt);
+}
+
 #define DFP_HELPER_CTFIX(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)  \
 { \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fff7bd46ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -734,6 +734,7 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp)
 DEF_HELPER_3(drdpq, void, env, fprp, fprp)
 DEF_HELPER_3(dcffix, void, env, fprp, fprp)
 DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..92ea2d0739 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -43,6 +43,10 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_frtp_vrb frtp vrb
+%x_frtp 22:4 !function=times_2
+@X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -121,6 +125,10 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Conversion Instructions
+
+DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 5489b4b6e0..9e940a1a17 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7422,6 +7422,11 @@ static inline void set_avr64(int regno, TCGv_i64 src, 
bool high)
 /*
  * Helpers for decodetree used by !function for decoding arguments.
  */
+static int times_2(DisasContext *ctx, int x)
+{
+return x * 2;
+}
+
 static int times_4(DisasContext *ctx, int x)
 {
 return x * 4;
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 6c556dc2e1..d5b66567a6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -230,3 +230,20 @@ GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 #undef GEN_DFP_T_A_B_I32_Rc
 #undef GEN_DFP_T_B_Rc
 #undef GEN_DFP_T_FPR_I32_Rc
+
+static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_fprp_ptr(a->frtp);
+rb = gen_avr_ptr(a->vrb);
+gen_helper_DCFFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v3 14/22] libdecnumber: Introduce decNumberIntegralToInt128

2021-09-10 Thread Luis Pires
This will be used to implement PowerPC's dctfixqq.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/libdecnumber/decNumber.h  |  2 +
 include/libdecnumber/decNumberLocal.h |  2 +-
 libdecnumber/decContext.c |  7 +-
 libdecnumber/decNumber.c  | 95 +++
 4 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 0cf69c7db2..41bc2a0d36 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -124,6 +124,8 @@
   uint32_tdecNumberToUInt32(const decNumber *, decContext *);
   int32_t decNumberToInt32(const decNumber *, decContext *);
   int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
+  voiddecNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh);
   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
 
diff --git a/include/libdecnumber/decNumberLocal.h 
b/include/libdecnumber/decNumberLocal.h
index 4d53c077f2..6198ca8593 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
 
   /* Shared lookup tables*/
   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
-  extern const uLong  DECPOWERS[19];/* powers of ten table*/
+  extern const uLong  DECPOWERS[20];/* powers of ten table*/
   /* The following are included from decDPD.h*/
   extern const uShort DPD2BIN[1024];   /* DPD -> 0-999   */
   extern const uShort BIN2DPD[1000];   /* 0-999 -> DPD   */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 7d97a65ac5..1956edf0a7 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -53,12 +53,13 @@ static  const  Flag *mfctop=(Flag *)&mfcone; /* -> top 
byte */
 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
 
 /* -- */
-/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
 /* -- */
-const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100,
+const uLong DECPOWERS[20] = {1, 10, 100, 1000, 1, 10, 100,
   1000, 1, 10, 100ULL, 1000ULL,
   1ULL, 10ULL, 100ULL, 1000ULL,
-  1ULL, 10ULL, 100ULL, };
+  1ULL, 10ULL, 100ULL,
+  1000ULL,};
 
 /* -- */
 /* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 75c09ba052..6bb5e270ee 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -264,6 +264,7 @@ static decNumber * decTrim(decNumber *, decContext *, Flag, 
Int *);
 static IntdecUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
  Unit *, Int);
 static IntdecUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+static boolmulUInt128ByPowOf10(uLong *, uLong *, uInt);
 
 #if !DECSUBSET
 /* decFinish == decFinalize when no subset arithmetic needed */
@@ -542,6 +543,68 @@ Invalid:
 return 0;
 } /* decNumberIntegralToInt64 */
 
+/* -- */
+/* decNumberIntegralToInt128 -- conversion to int128  */
+/**/
+/*  dn is the decNumber to convert.  dn is assumed to have been   */
+/*rounded to a floating point integer value.  */
+/*  set is the context for reporting errors   */
+/*  returns the converted decNumber via plow and phigh*/
+/**/
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/
+/* range for a signed 128 bit integer.*/
+/* -- */
+
+void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh)
+{
+int d;/* work */
+const Unit *up;   /* .. */
+uint64_t lo = 0, hi = 0;
+
+if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+   (dn->digits + dn->exponent > 39)) {
+goto Invalid;
+}
+
+up = dn->lsu; /* -> lsu */
+

[PATCH v3 07/22] host-utils: add 128-bit quotient support to divu128/divs128

2021-09-10 Thread Luis Pires
These will be used to implement new decimal floating point
instructions from Power ISA 3.1.

A new argument, prem, was added to divu128/divs128 to receive the
remainder, freeing up phigh to receive the high 64 bits of the
quotient.

Signed-off-by: Luis Pires 
---
 include/hw/clock.h|   8 +--
 include/qemu/host-utils.h |  22 +--
 target/ppc/int_helper.c   |  13 ++--
 util/host-utils.c | 132 ++
 4 files changed, 115 insertions(+), 60 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 5a40a076aa..2f162f7a6f 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -319,12 +319,8 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 if (clk->period == 0) {
 return 0;
 }
-/*
- * BUG: when CONFIG_INT128 is not defined, the current implementation of
- * divu128 does not return a valid truncated quotient, so the result will
- * be wrong.
- */
-divu128(&lo, &hi, clk->period);
+
+divu128(&lo, &hi, NULL, clk->period);
 return lo;
 }
 
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 08a17e16e5..eee58c0874 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -56,26 +56,34 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t *prem,
+   uint64_t divisor)
 {
 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
 __uint128_t result = dividend / divisor;
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+if (prem) {
+*prem = dividend % divisor;
+}
 }
 
-static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem,
+   int64_t divisor)
 {
-__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
+__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
 __int128_t result = dividend / divisor;
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+if (prem) {
+*prem = dividend % divisor;
+}
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t *prem, uint64_t 
divisor);
+void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 510faf24cf..b3d302390a 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -108,7 +108,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 overflow = 1;
 rt = 0; /* Undefined */
 } else {
-divu128(&rt, &ra, rb);
+divu128(&rt, &ra, NULL, rb);
 }
 
 if (oe) {
@@ -120,7 +120,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 
 uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t 
oe)
 {
-int64_t rt = 0;
+uint64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
 int overflow = 0;
@@ -129,7 +129,7 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 overflow = 1;
 rt = 0; /* Undefined */
 } else {
-divs128(&rt, &ra, rb);
+divs128(&rt, &ra, NULL, rb);
 }
 
 if (oe) {
@@ -2506,6 +2506,7 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 int cr;
 uint64_t lo_value;
 uint64_t hi_value;
+uint64_t rem;
 ppc_avr_t ret = { .u64 = { 0, 0 } };
 
 if (b->VsrSD(0) < 0) {
@@ -2541,10 +2542,10 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
  * In that case, we leave r unchanged.
  */
 } else {
-divu128(&lo_value, &hi_value, 1000ULL);
+divu128(&lo_value, &hi_value, &rem, 1000ULL);
 
-for (i = 1; i < 16; hi_value /= 10, i++) {
-bcd_put_digit(&ret, hi_value % 10, i);
+for (i = 1; i < 16; rem /= 10, i++) {
+bcd_put_digit(&ret, rem % 10, i);
 }
 
 for (; i < 32; lo_value /= 10, i++) {
diff --git a/util/host-utils.c b/util/host-utils.c
index 701a371843..8834f3503f 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -87,72 +87,122 @@ void muls6

[PATCH v3 08/22] host-utils: add unit tests for divu128/divs128

2021-09-10 Thread Luis Pires
Signed-off-by: Luis Pires 
---
 tests/unit/meson.build   |   1 +
 tests/unit/test-div128.c | 197 +++
 2 files changed, 198 insertions(+)
 create mode 100644 tests/unit/test-div128.c

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 5736d285b2..96e3b23162 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -23,6 +23,7 @@ tests = {
   # all code tested by test-x86-cpuid is inside topology.h
   'test-x86-cpuid': [],
   'test-cutils': [],
+  'test-div128': [],
   'test-shift128': [],
   'test-mul64': [],
   # all code tested by test-int128 is inside int128.h
diff --git a/tests/unit/test-div128.c b/tests/unit/test-div128.c
new file mode 100644
index 00..1afe7f0748
--- /dev/null
+++ b/tests/unit/test-div128.c
@@ -0,0 +1,197 @@
+/*
+ * Test 128-bit division functions
+ *
+ * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+
+typedef struct {
+uint64_t high;
+uint64_t low;
+uint64_t rhigh;
+uint64_t rlow;
+uint64_t divisor;
+uint64_t remainder;
+} test_data_unsigned;
+
+typedef struct {
+int64_t high;
+uint64_t low;
+int64_t rhigh;
+uint64_t rlow;
+int64_t divisor;
+int64_t remainder;
+} test_data_signed;
+
+static const test_data_unsigned test_table_unsigned[] = {
+/* Dividend fits in 64 bits */
+{ 0xULL, 0xULL,
+  0xULL, 0xULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0001ULL,
+  0xULL, 0x0001ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0003ULL,
+  0xULL, 0x0001ULL,
+  0x0002ULL, 0x0001ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x8000ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0xa000ULL,
+  0xULL, 0x0002ULL,
+  0x4000ULL, 0x2000ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x0001ULL,
+  0x8000ULL, 0xULL},
+
+/* Dividend > 64 bits, with MSB 0 */
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0xULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0x000dULL,
+  0x123456789abcdefeULL, 0x03456789abcdf03bULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0123456789abcdefULL, 0xeefedcba98765432ULL,
+  0x0010ULL, 0x0001ULL},
+
+/* Dividend > 64 bits, with MSB 1 */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0feeddccbbaa9988ULL, 0x7766554433221100ULL,
+  0x0010ULL, 0x000fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x000eULL, 0x00f0f0f0f0f0f35aULL,
+  0x123456789abcdefeULL, 0x0f8922bc55ef90c3ULL},
+
+/**
+ * Divisor == 64 bits, with MSB 1
+ * and high 64 bits of dividend >= divisor
+ * (for testing normalization)
+ */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xfddbb9977553310aULL,
+  0x8001ULL, 0x78899aabbccddf05ULL},
+
+/* Dividend > 64 bits, divisor almost as big */
+{ 0x0001ULL, 0x23456789abcdef01ULL,
+  0xULL, 0x000fULL,
+ 

[PATCH v3 13/22] host-utils: Introduce mulu128

2021-09-10 Thread Luis Pires
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 include/qemu/host-utils.h | 36 
 1 file changed, 36 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index eee58c0874..8360146979 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -592,6 +592,42 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, 
uint64_t *ret)
 #endif
 }
 
+/*
+ * Unsigned 128x64 multiplication.
+ * Returns true if the result got truncated to 128 bits.
+ * Otherwise, returns false and the multiplication result via plow and phigh.
+ */
+static inline bool mulu128(uint64_t *plow, uint64_t *phigh, uint64_t factor)
+{
+#if defined(CONFIG_INT128) && \
+(__has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5)
+bool res;
+__uint128_t r;
+__uint128_t f = ((__uint128_t)*phigh << 64) | *plow;
+res = __builtin_mul_overflow(f, factor, &r);
+
+*plow = r;
+*phigh = r >> 64;
+
+return res;
+#else
+uint64_t dhi = *phigh;
+uint64_t dlo = *plow;
+uint64_t ahi;
+uint64_t blo, bhi;
+
+if (dhi == 0) {
+mulu64(plow, phigh, dlo, factor);
+return false;
+}
+
+mulu64(plow, &ahi, dlo, factor);
+mulu64(&blo, &bhi, dhi, factor);
+
+return uadd64_overflow(ahi, blo, phigh) || bhi != 0;
+#endif
+}
+
 /**
  * uadd64_carry - addition with carry-in and carry-out
  * @x, @y: addends
-- 
2.25.1




[PATCH v3 06/22] host-utils: move udiv_qrnnd() to host-utils

2021-09-10 Thread Luis Pires
Move udiv_qrnnd() from include/fpu/softfloat-macros.h to host-utils,
so it can be reused by divu128().

Signed-off-by: Luis Pires 
---
 include/fpu/softfloat-macros.h | 82 --
 include/qemu/host-utils.h  | 81 +
 2 files changed, 81 insertions(+), 82 deletions(-)

diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
index 81c3fe8256..f35cdbfa63 100644
--- a/include/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -8,7 +8,6 @@
  * so some portions are provided under:
  *  the SoftFloat-2a license
  *  the BSD license
- *  GPL-v2-or-later
  *
  * Any future contributions to this file after December 1st 2014 will be
  * taken to be licensed under the Softfloat-2a license unless specifically
@@ -75,10 +74,6 @@ this code that are retained.
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* Portions of this work are licensed under the terms of the GNU GPL,
- * version 2 or later. See the COPYING file in the top-level directory.
- */
-
 #ifndef FPU_SOFTFLOAT_MACROS_H
 #define FPU_SOFTFLOAT_MACROS_H
 
@@ -585,83 +580,6 @@ static inline uint64_t estimateDiv128To64(uint64_t a0, 
uint64_t a1, uint64_t b)
 
 }
 
-/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd
- * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
- *
- * Licensed under the GPLv2/LGPLv3
- */
-static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
-  uint64_t n0, uint64_t d)
-{
-#if defined(__x86_64__)
-uint64_t q;
-asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
-return q;
-#elif defined(__s390x__) && !defined(__clang__)
-/* Need to use a TImode type to get an even register pair for DLGR.  */
-unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
-asm("dlgr %0, %1" : "+r"(n) : "r"(d));
-*r = n >> 64;
-return n;
-#elif defined(_ARCH_PPC64) && defined(_ARCH_PWR7)
-/* From Power ISA 2.06, programming note for divdeu.  */
-uint64_t q1, q2, Q, r1, r2, R;
-asm("divdeu %0,%2,%4; divdu %1,%3,%4"
-: "=&r"(q1), "=r"(q2)
-: "r"(n1), "r"(n0), "r"(d));
-r1 = -(q1 * d); /* low part of (n1<<64) - (q1 * d) */
-r2 = n0 - (q2 * d);
-Q = q1 + q2;
-R = r1 + r2;
-if (R >= d || R < r2) { /* overflow implies R > d */
-Q += 1;
-R -= d;
-}
-*r = R;
-return Q;
-#else
-uint64_t d0, d1, q0, q1, r1, r0, m;
-
-d0 = (uint32_t)d;
-d1 = d >> 32;
-
-r1 = n1 % d1;
-q1 = n1 / d1;
-m = q1 * d0;
-r1 = (r1 << 32) | (n0 >> 32);
-if (r1 < m) {
-q1 -= 1;
-r1 += d;
-if (r1 >= d) {
-if (r1 < m) {
-q1 -= 1;
-r1 += d;
-}
-}
-}
-r1 -= m;
-
-r0 = r1 % d1;
-q0 = r1 / d1;
-m = q0 * d0;
-r0 = (r0 << 32) | (uint32_t)n0;
-if (r0 < m) {
-q0 -= 1;
-r0 += d;
-if (r0 >= d) {
-if (r0 < m) {
-q0 -= 1;
-r0 += d;
-}
-}
-}
-r0 -= m;
-
-*r = r0;
-return (q1 << 32) | q0;
-#endif
-}
-
 /*
 | Returns an approximation to the square root of the 32-bit significand given
 | by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index e82e6239af..08a17e16e5 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -23,6 +23,10 @@
  * THE SOFTWARE.
  */
 
+/* Portions of this work are licensed under the terms of the GNU GPL,
+ * version 2 or later. See the COPYING file in the top-level directory.
+ */
+
 #ifndef HOST_UTILS_H
 #define HOST_UTILS_H
 
@@ -726,4 +730,81 @@ void urshift(uint64_t *plow, uint64_t *phigh, int32_t 
shift);
  */
 void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow);
 
+/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd
+ * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
+ *
+ * Licensed under the GPLv2/LGPLv3
+ */
+static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1,
+  uint64_t n0, uint64_t d)
+{
+#if defined(__x86_64__)
+uint64_t q;
+asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d));
+return q;
+#elif defined(__s390x__) && !defined(__clang__)
+/* Need to use a TImode type to get an even register pair for DLGR.  */
+unsigned __int128 n = (unsigned __int128)n1 << 64 | n0;
+asm("dlgr %0, %1" : "+r"(n) : "r"(d));
+*r = 

[PATCH v3 20/22] target/ppc: Move dqua[q], drrnd[q] to decodetree

2021-09-10 Thread Luis Pires
Move the following instructions to decodetree:
dqua:   DFP Quantize
dquaq:  DFP Quantize Quad
drrnd:  DFP Reround
drrndq: DFP Reround Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c |  8 ++---
 target/ppc/helper.h |  8 ++---
 target/ppc/insn32.decode| 18 --
 target/ppc/translate/dfp-impl.c.inc | 51 +
 target/ppc/translate/dfp-ops.c.inc  | 25 --
 5 files changed, 47 insertions(+), 63 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 56d8846308..9c75cbb79b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -770,8 +770,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
+DFP_HELPER_QUA(DQUA, 64)
+DFP_HELPER_QUA(DQUAQ, 128)
 
 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
  struct PPC_DFP *dfp)
@@ -848,8 +848,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
+DFP_HELPER_RRND(DRRND, 64)
+DFP_HELPER_RRND(DRRNDQ, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)   
\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,   
\
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 520cce8378..cb05cc168c 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -720,10 +720,10 @@ DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUA, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUAQ, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRND, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRNDQ, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index f0e17580e0..86dbdada47 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,11 +77,19 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
-&Z23_tb frt frb r:bool rmc rc:bool
-@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+&Z23_tabfrt fra frb rmc rc:bool
+@Z23_tab.. frt:5 fra:5 frb:5 rmc:2  rc:1&Z23_tab
 
 %z23_frtp   22:4 !function=times_2
+%z23_frap   17:4 !function=times_2
 %z23_frbp   12:4 !function=times_2
+@Z23_tabp   .. 0 0 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp fra=%z23_frap frb=%z23_frbp
+
+@Z23_tp_a_bp.. 0 fra:5 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
 @Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
 
 &Z23_te_tb  te frt frb rmc rc:bool
@@ -211,6 +219,12 @@ DTSTSFIQ11 ... - .. . 1010100011 -  
@X_bf_uim_bp
 DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
 DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
 
+DQUA111011 . . . .. 0011 .  @Z23_tab
+DQUAQ   11 . . . .. 0011 .  @Z23_tabp
+
+DRRND   111011 . . . .. 00100011 .  @Z23_tab
+DRRNDQ  11 . . . .. 00100011 .  @Z23_tp_a_bp
+
 DRINTX  111011 .  . . .. 01100011 . @Z23_tb
 DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index a499b17e7c..73c8906b45 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -86,29 +86,25 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  
 \
 return true; \
 }
 
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)   \
-static void gen_##name(DisasContext *ctx)\
-{\
-TCGv_ptr rt, ra, rb; \
-TCGv_i32 i32; 

[PATCH v3 11/22] target/ppc: Introduce REQUIRE_FPU

2021-09-10 Thread Luis Pires
From: Fernando Valle 

Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 target/ppc/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4749ecdaa9..5489b4b6e0 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7461,6 +7461,14 @@ static int times_4(DisasContext *ctx, int x)
 }   \
 } while (0)
 
+#define REQUIRE_FPU(ctx)\
+do {\
+if (unlikely(!(ctx)->fpu_enabled)) {\
+gen_exception((ctx), POWERPC_EXCP_FPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
-- 
2.25.1




[PATCH v3 01/22] host-utils: Fix overflow detection in divu128()

2021-09-10 Thread Luis Pires
The previous code didn't detect overflows if the high 64-bit
of the dividend were equal to the 64-bit divisor. In that case,
64 bits wouldn't be enough to hold the quotient.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
---
 util/host-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/host-utils.c b/util/host-utils.c
index 7b9322071d..a789a11b46 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -102,7 +102,7 @@ int divu128(uint64_t *plow, uint64_t *phigh, uint64_t 
divisor)
 *plow  = dlo / divisor;
 *phigh = dlo % divisor;
 return 0;
-} else if (dhi > divisor) {
+} else if (dhi >= divisor) {
 return 1;
 } else {
 
-- 
2.25.1




[PATCH v3 04/22] i386/kvm: Replace abs64() with uabs64() from host-utils

2021-09-10 Thread Luis Pires
Drop abs64() and use uabs64() from host-utils, which avoids
an undefined behavior when taking abs of the most negative value.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
Reviewed-by: Eduardo Habkost 
---
 hw/i386/kvm/i8254.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index fa68669e8a..191a26fa57 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -59,11 +59,6 @@ struct KVMPITClass {
 DeviceRealize parent_realize;
 };
 
-static int64_t abs64(int64_t v)
-{
-return v < 0 ? -v : v;
-}
-
 static void kvm_pit_update_clock_offset(KVMPITState *s)
 {
 int64_t offset, clock_offset;
@@ -81,7 +76,7 @@ static void kvm_pit_update_clock_offset(KVMPITState *s)
 clock_gettime(CLOCK_MONOTONIC, &ts);
 offset -= ts.tv_nsec;
 offset -= (int64_t)ts.tv_sec * 10;
-if (abs64(offset) < abs64(clock_offset)) {
+if (uabs64(offset) < uabs64(clock_offset)) {
 clock_offset = offset;
 }
 }
-- 
2.25.1




[PATCH v3 02/22] host-utils: fix missing zero-extension in divs128

2021-09-10 Thread Luis Pires
*plow (lower 64 bits of the dividend) is passed into divs128() as
a signed 64-bit integer. When building an __int128_t from it, it
must be zero-extended, instead of sign-extended.

Suggested-by: Richard Henderson 
Signed-off-by: Luis Pires 
---
 include/qemu/host-utils.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 711b221704..753b9fb89f 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -70,7 +70,7 @@ static inline int divs128(int64_t *plow, int64_t *phigh, 
int64_t divisor)
 if (divisor == 0) {
 return 1;
 } else {
-__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
+__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
 __int128_t result = dividend / divisor;
 *plow = result;
 *phigh = dividend % divisor;
-- 
2.25.1




[PATCH v3 03/22] host-utils: introduce uabs64()

2021-09-10 Thread Luis Pires
Introduce uabs64(), a function that returns the absolute value of
a 64-bit int as an unsigned value. This avoids the undefined behavior
for common abs implementations, where abs of the most negative value is
undefined.

Signed-off-by: Luis Pires 
Reviewed-by: Richard Henderson 
Reviewed-by: Eduardo Habkost 
---
 include/qemu/host-utils.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 753b9fb89f..ca9f3f021b 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -357,6 +357,14 @@ static inline uint64_t revbit64(uint64_t x)
 #endif
 }
 
+/**
+ * Return the absolute value of a 64-bit integer as an unsigned 64-bit value
+ */
+static inline uint64_t uabs64(int64_t v)
+{
+return v < 0 ? -v : v;
+}
+
 /**
  * sadd32_overflow - addition with overflow indication
  * @x, @y: addends
-- 
2.25.1




[PATCH v3 05/22] host-utils: move checks out of divu128/divs128

2021-09-10 Thread Luis Pires
In preparation for changing the divu128/divs128 implementations
to allow for quotients larger than 64 bits, move the div-by-zero
and overflow checks to the callers.

Signed-off-by: Luis Pires 
---
 include/hw/clock.h|  5 +++--
 include/qemu/host-utils.h | 36 +--
 target/ppc/int_helper.c   | 14 +-
 util/host-utils.c | 40 ++-
 4 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index a7187eab95..5a40a076aa 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -320,8 +320,9 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 return 0;
 }
 /*
- * Ignore divu128() return value as we've caught div-by-zero and don't
- * need different behaviour for overflow.
+ * BUG: when CONFIG_INT128 is not defined, the current implementation of
+ * divu128 does not return a valid truncated quotient, so the result will
+ * be wrong.
  */
 divu128(&lo, &hi, clk->period);
 return lo;
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index ca9f3f021b..e82e6239af 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,36 +52,26 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
-{
-if (divisor == 0) {
-return 1;
-} else {
-__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
-__uint128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result > UINT64_MAX;
-}
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
+__uint128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 
-static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
 {
-if (divisor == 0) {
-return 1;
-} else {
-__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
-__int128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result != *plow;
-}
+__int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
+__int128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f5dac3aa87..510faf24cf 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -104,10 +104,11 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 uint64_t rt = 0;
 int overflow = 0;
 
-overflow = divu128(&rt, &ra, rb);
-
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || ra >= rb)) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divu128(&rt, &ra, rb);
 }
 
 if (oe) {
@@ -122,10 +123,13 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 int64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
-int overflow = divs128(&rt, &ra, rb);
+int overflow = 0;
 
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || uabs64(ra) >= uabs64(rb))) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divs128(&rt, &ra, rb);
 }
 
 if (oe) {
diff --git a/util/host-utils.c b/util/host-utils.c
index a789a11b46..701a371843 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -86,24 +86,23 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 *phigh = rh;
 }
 
-/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
-/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
-/* remainder via phigh. */
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+/*
+ * Unsigned 128-by-64 division. Returns quotient via plow and
+ * remainder via phigh.
+ * The result must fit in 64 bits (plow) - otherwise, the result
+ * is undefined.
+ * This function will cause a division by zero if passed a zero divisor.
+ */
+void divu128(uint64_t *plow, uint6

[PATCH v3 00/22] target/ppc: DFP instructions using decodetree

2021-09-10 Thread Luis Pires
This series moves all existing DFP instructions to decodetree and
implements the 2 new instructions (dcffixqq and dctfixqq) from
Power ISA 3.1.

In order to implement dcffixqq, divu128/divs128 were modified to
support 128-bit quotients (previously, they were limited to 64-bit
quotients), along with adjustments being made to their existing callers.
libdecnumber was also expanded to allow creating decimal numbers from
128-bit integers.

Similarly, for dctfixqq, mulu128 (host-utils) and decNumberIntegralToInt128
(libdecnumber) were introduced to support 128-bit integers.

The remaining patches of this series move all of the already existing
DFP instructions to decodetree, and end up removing dfp-ops.c.inc, which
is no longer needed.

NOTE 1: The previous, non-decodetree code, was updating ctx->nip for all the
DFP instructions. I've removed that, but it would be great if someone could
confirm that updating nip really wasn't necessary.

NOTE 2: Some arithmetic function support for 128-bit integers was added,
for now, still using 64-bit pairs. In the near future, I think we should
modify all of them to use Int128 (and introduce UInt128). But I'll send
out an RFC to discuss how to do that in another patch series.

NOTE 3: The helper names are in uppercase, to match the instruction
names and to simplify the macros that define trans* functions.
Previously, this wasn't the case, as we were using lowercase instruction
names in the pre-decodetree code. Another standalone patch will be sent
later on, changing to uppercase the other new (decodetree) helpers whose
names are directly related to instruction names, eventually making PPC
helper names consistent.

Based-on: 20210823150235.35759-1-luis.pi...@eldorado.org.br
(target/ppc: fix setting of CR flags in bcdcfsq)
This series assumes bcdcfsq's fix is already in.

Changes in v3:
- Split the uabs64 patch in 2
- Included patch to fix missing zero-extension in divs128
- Folded divisor == 0 into the dhi == 0 case in divu128
- Moved udiv_qrnnd from softfloat-macros.h to host-utils.h
- Used udiv_qrnnd in divu128
- Replaced int with bool in divs128
- Added unit test to check the divisor normalization in divu128
- Removed 'inline' from times_* functions in ppc/translate.c
- Used uadd64_overflow in mulu128
- Removed unnecessary 'else' from decNumberIntegralToInt128

Changes in v2:
- Renamed abs64() to uabs64()

Patches missing review:
  host-utils: fix missing zero-extension in divs128
  host-utils: move checks out of divu128/divs128
  host-utils: move udiv_qrnnd() to host-utils
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  target/ppc: Implement DCFFIXQQ
  target/ppc: Implement DCTFIXQQ
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>

Bruno Larsen (1):
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

Fernando Valle (1):
  target/ppc: Introduce REQUIRE_FPU

Luis Pires (20):
  host-utils: Fix overflow detection in divu128()
  host-utils: fix missing zero-extension in divs128
  host-utils: introduce uabs64()
  i386/kvm: Replace abs64() with uabs64() from host-utils
  host-utils: move checks out of divu128/divs128
  host-utils: move udiv_qrnnd() to host-utils
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree
  target/ppc: Move d{add,sub,mul,div,iex}[q] to decodetree
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree
  target/ppc: Move dquai[q], drint{x,n}[q] to decodetree
  target/ppc: Move dqua[q], drrnd[q] to decodetree
  target/ppc: Move dct{dp,qpq},dr{sp,dpq},dc{f,t}fix[q],dxex[q] to
decodetree
  target/ppc: Move ddedpd[q],denbcd[q],dscli[q],dscri[q] to decodetree

 hw/i386/kvm/i8254.c|   7 +-
 include/fpu/softfloat-macros.h |  82 -
 include/hw/clock.h |   7 +-
 include/libdecnumber/decNumber.h   |   4 +
 include/libdecnumber/decNumberLocal.h  |   2 +-
 include/qemu/host-utils.h  | 163 --
 libdecnumber/decContext.c  |   7 +-
 libdecnumber/decNumber.c   | 131 
 target/ppc/dfp_helper.c| 168 +++---
 target/ppc/helper.h| 106 ---
 target/ppc/insn32.decode   | 171 ++
 target/ppc/int_helper.c|  23 +-
 target/ppc/translate.c |  23 +-
 target/ppc/translate/dfp-impl.c.inc| 419 -
 target/ppc/translate/dfp-ops.c.inc | 165 --
 target/ppc/transl

[PATCH v2 17/19] target/ppc: Move dqua[q], drrnd[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
dqua:   DFP Quantize
dquaq:  DFP Quantize Quad
drrnd:  DFP Reround
drrndq: DFP Reround Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c |  8 ++---
 target/ppc/helper.h |  8 ++---
 target/ppc/insn32.decode| 18 --
 target/ppc/translate/dfp-impl.c.inc | 51 +
 target/ppc/translate/dfp-ops.c.inc  | 25 --
 5 files changed, 47 insertions(+), 63 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 56d8846308..9c75cbb79b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -770,8 +770,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
+DFP_HELPER_QUA(DQUA, 64)
+DFP_HELPER_QUA(DQUAQ, 128)
 
 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
  struct PPC_DFP *dfp)
@@ -848,8 +848,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
+DFP_HELPER_RRND(DRRND, 64)
+DFP_HELPER_RRND(DRRNDQ, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)   
\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,   
\
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 520cce8378..cb05cc168c 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -720,10 +720,10 @@ DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUA, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUAQ, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRND, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRNDQ, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index f0e17580e0..86dbdada47 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,11 +77,19 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
-&Z23_tb frt frb r:bool rmc rc:bool
-@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+&Z23_tabfrt fra frb rmc rc:bool
+@Z23_tab.. frt:5 fra:5 frb:5 rmc:2  rc:1&Z23_tab
 
 %z23_frtp   22:4 !function=times_2
+%z23_frap   17:4 !function=times_2
 %z23_frbp   12:4 !function=times_2
+@Z23_tabp   .. 0 0 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp fra=%z23_frap frb=%z23_frbp
+
+@Z23_tp_a_bp.. 0 fra:5 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
 @Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
 
 &Z23_te_tb  te frt frb rmc rc:bool
@@ -211,6 +219,12 @@ DTSTSFIQ11 ... - .. . 1010100011 -  
@X_bf_uim_bp
 DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
 DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
 
+DQUA111011 . . . .. 0011 .  @Z23_tab
+DQUAQ   11 . . . .. 0011 .  @Z23_tabp
+
+DRRND   111011 . . . .. 00100011 .  @Z23_tab
+DRRNDQ  11 . . . .. 00100011 .  @Z23_tp_a_bp
+
 DRINTX  111011 .  . . .. 01100011 . @Z23_tb
 DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index a499b17e7c..73c8906b45 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -86,29 +86,25 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  
 \
 return true; \
 }
 
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)   \
-static void gen_##name(DisasContext *ctx)\
-{\
-TCGv_ptr rt, ra, rb; \
-TCGv_i32 i32; 

[PATCH v2 15/19] target/ppc: Move dcmp{u, o}[q], dts{tex, tsf, tsfi}[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
dcmpu:DFP Compare Unordered
dcmpuq:   DFP Compare Unordered Quad
dcmpo:DFP Compare Ordered
dcmpoq:   DFP Compare Ordered Quad
dtstex:   DFP Test Exponent
dtstexq:  DFP Test Exponent Quad
dtstsf:   DFP Test Significance
dtstsfq:  DFP Test Significance Quad
dtstsfi:  DFP Test Significance Immediate
dtstsfiq: DFP Test Significance Immediate Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 20 
 target/ppc/helper.h | 20 
 target/ppc/insn32.decode| 29 +++
 target/ppc/translate/dfp-impl.c.inc | 76 +
 target/ppc/translate/dfp-ops.c.inc  | 31 
 5 files changed, 83 insertions(+), 93 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 14080cecc8..b6634134d9 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -508,8 +508,8 @@ static void CMPU_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
+DFP_HELPER_BF_AB(DCMPU, decNumberCompare, CMPU_PPs, 64)
+DFP_HELPER_BF_AB(DCMPUQ, decNumberCompare, CMPU_PPs, 128)
 
 static void CMPO_PPs(struct PPC_DFP *dfp)
 {
@@ -519,8 +519,8 @@ static void CMPO_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXVC(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
+DFP_HELPER_BF_AB(DCMPO, decNumberCompare, CMPO_PPs, 64)
+DFP_HELPER_BF_AB(DCMPOQ, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -634,8 +634,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
+DFP_HELPER_TSTEX(DTSTEX, 64)
+DFP_HELPER_TSTEX(DTSTEXQ, 128)
 
 #define DFP_HELPER_TSTSF(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
@@ -671,8 +671,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
+DFP_HELPER_TSTSF(DTSTSF, 64)
+DFP_HELPER_TSTSF(DTSTSFQ, 128)
 
 #define DFP_HELPER_TSTSFI(op, size) \
 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)   \
@@ -706,8 +706,8 @@ uint32_t helper_##op(CPUPPCState *env, uint32_t a, 
ppc_fprp_t *b)   \
 return dfp.crbf;\
 }
 
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
+DFP_HELPER_TSTSFI(DTSTSFI, 64)
+DFP_HELPER_TSTSFI(DTSTSFIQ, 128)
 
 static void QUA_PPs(struct PPC_DFP *dfp)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 1f00e47b82..22bf167b15 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -704,20 +704,20 @@ DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPO, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPOQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPU, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPUQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTEX, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTEXQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index c4a8cc7ec5..aaeccebca0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -50,6 +50,18 @@
 &X_bi   rt bi
 @X_bi   .. rt:5 bi:5 - .. - &X_bi
 
+&X_bf   bf ra rb
+@X_bf   .. bf:3 .. ra:5 rb:5 .. .

[PATCH v2 19/19] target/ppc: Move ddedpd[q], denbcd[q], dscli[q], dscri[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
ddedpd:  DFP Decode DPD To BCD
ddedpdq: DFP Decode DPD To BCD Quad
denbcd:  DFP Encode BCD To DPD
denbcdq: DFP Encode BCD To DPD Quad
dscli:   DFP Shift Significand Left Immediate
dscliq:  DFP Shift Significand Left Immediate Quad
dscri:   DFP Shift Significand Right Immediate
dscriq:  DFP Shift Significand Right Immediate Quad

Also deleted dfp-ops.c.inc, now that all PPC DFP instructions were
moved to decodetree.

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 16 -
 target/ppc/helper.h | 16 -
 target/ppc/insn32.decode| 28 +++
 target/ppc/translate.c  |  2 --
 target/ppc/translate/dfp-impl.c.inc | 54 +
 target/ppc/translate/dfp-ops.c.inc  | 40 -
 6 files changed, 68 insertions(+), 88 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 7bb394c02b..0dcb1249f7 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1131,8 +1131,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
+DFP_HELPER_DEDPD(DDEDPD, 64)
+DFP_HELPER_DEDPD(DDEDPDQ, 128)
 
 static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
@@ -1199,8 +1199,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 set_dfp##size(t, &dfp.vt);   \
 }
 
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
+DFP_HELPER_ENBCD(DENBCD, 64)
+DFP_HELPER_ENBCD(DENBCDQ, 128)
 
 #define DFP_HELPER_XEX(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
@@ -1387,7 +1387,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
+DFP_HELPER_SHIFT(DSCLI, 64, 1)
+DFP_HELPER_SHIFT(DSCLIQ, 128, 1)
+DFP_HELPER_SHIFT(DSCRI, 64, 0)
+DFP_HELPER_SHIFT(DSCRIQ, 128, 0)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4c2a349ce6..6fa3e15fe9 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -738,18 +738,18 @@ DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPDQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCDQ, void, env, fprp, fprp, i32)
 DEF_HELPER_3(DXEX, void, env, fprp, fprp)
 DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRIQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLIQ, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
 DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2ce8b0ab95..6aec1c0728 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -74,6 +74,16 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_tb_sp_rc rt rb sp rc:bool
+@X_tb_sp_rc .. rt:5 sp:2 ... rb:5 .. rc:1   &X_tb_sp_rc
+
+@X_tbp_sp_rc.. 0 sp:2 ... 0 .. rc:1 &X_tb_sp_rc 
rt=%x_frtp rb=%x_frbp
+
+&X_tb_s_rc  rt rb s:bool rc:bool
+@X_tb_s_rc  .. rt:5 s:1  rb:5 .. rc:1   &X_tb_s_rc
+
+@X_tbp_s_rc .. 0 s:1  0 .. rc:1 &X_tb_s_rc 
rt=%x_frtp rb=%x_frbp
+
 &X_frtp_vrb frtp vrb
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
@@ -86,6 +96,12 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z22_ta_sh_rc   rt ra sh rc:bool
+@Z22_ta_sh_rc   .. rt:5 ra:5 sh:6 . rc:1&Z22_ta

[PATCH v2 14/19] target/ppc: Move d{add, sub, mul, div, iex}[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
dadd:  DFP Add
daddq: DFP Add Quad
dsub:  DFP Subtract
dsubq: DFP Subtract Quad
dmul:  DFP Multiply
dmulq: DFP Multiply Quad
ddiv:  DFP Divide
ddivq: DFP Divide Quad
diex:  DFP Insert Biased Exponent
diexq: DFP Insert Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 20 +-
 target/ppc/helper.h | 20 +-
 target/ppc/insn32.decode| 31 +++-
 target/ppc/translate/dfp-impl.c.inc | 57 ++---
 target/ppc/translate/dfp-ops.c.inc  | 19 --
 5 files changed, 76 insertions(+), 71 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b4945fe48f..14080cecc8 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -446,8 +446,8 @@ static void ADD_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_add(dfp);
 }
 
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
+DFP_HELPER_TAB(DADD, decNumberAdd, ADD_PPs, 64)
+DFP_HELPER_TAB(DADDQ, decNumberAdd, ADD_PPs, 128)
 
 static void SUB_PPs(struct PPC_DFP *dfp)
 {
@@ -459,8 +459,8 @@ static void SUB_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_subtract(dfp);
 }
 
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
+DFP_HELPER_TAB(DSUB, decNumberSubtract, SUB_PPs, 64)
+DFP_HELPER_TAB(DSUBQ, decNumberSubtract, SUB_PPs, 128)
 
 static void MUL_PPs(struct PPC_DFP *dfp)
 {
@@ -472,8 +472,8 @@ static void MUL_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIMZ(dfp);
 }
 
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
+DFP_HELPER_TAB(DMUL, decNumberMultiply, MUL_PPs, 64)
+DFP_HELPER_TAB(DMULQ, decNumberMultiply, MUL_PPs, 128)
 
 static void DIV_PPs(struct PPC_DFP *dfp)
 {
@@ -487,8 +487,8 @@ static void DIV_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIDI(dfp);
 }
 
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
+DFP_HELPER_TAB(DDIV, decNumberDivide, DIV_PPs, 64)
+DFP_HELPER_TAB(DDIVQ, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)
\
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)   
\
@@ -1299,8 +1299,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
+DFP_HELPER_IEX(DIEX, 64)
+DFP_HELPER_IEX(DIEXQ, 128)
 
 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 30e9247a5a..1f00e47b82 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -696,14 +696,14 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #define dh_alias_fprp ptr
 #define dh_ctype_fprp ppc_fprp_t *
 
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADD, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADDQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUB, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUBQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
@@ -744,8 +744,8 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
 DEF_HELPER_3(dxex, void, env, fprp, fprp)
 DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 38f8525d54..c4a8cc7ec5 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -37,6 +37,16 @@
 &X  rt ra rb
 @X  .. rt:5 ra:5 rb:5 .. .  &X
 
+&X_rc   rt ra rb rc:bool
+@X_rc   .. rt:5 ra:5 rb:5 .. rc:1   &X_rc
+
+%x_frtp 22:4 !function=times_2
+%x_frap 17:4 !function=times_2
+

[PATCH v2 18/19] target/ppc: Move dct{dp, qpq}, dr{sp, dpq}, dc{f, t}fix[q], dxex[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
dctdp:   DFP Convert To DFP Long
dctqpq:  DFP Convert To DFP Extended
drsp:DFP Round To DFP Short
drdpq:   DFP Round To DFP Long
dcffix:  DFP Convert From Fixed
dcffixq: DFP Convert From Fixed Quad
dctfix:  DFP Convert To Fixed
dctfixq: DFP Convert To Fixed Quad
dxex:DFP Extract Biased Exponent
dxexq:   DFP Extract Biased Exponent Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 23 
 target/ppc/translate/dfp-impl.c.inc | 55 ++---
 target/ppc/translate/dfp-ops.c.inc  | 22 
 5 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 9c75cbb79b..7bb394c02b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -886,7 +886,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
 DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTDP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -902,7 +902,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 dfp_set_FPRF_from_FRT(&dfp);
 }
 
-void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTQPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -917,7 +917,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp128(t, &dfp.vt);
 }
 
-void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRSP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 uint32_t t_short = 0;
@@ -935,7 +935,7 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp64(t, &vt);
 }
 
-void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRDPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 dfp_prepare_decimal128(&dfp, 0, b, env);
@@ -973,8 +973,8 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_XX(dfp);
 }
 
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
+DFP_HELPER_CFFIX(DCFFIX, 64)
+DFP_HELPER_CFFIX(DCFFIXQ, 128)
 
 void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
 {
@@ -1022,8 +1022,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 set_dfp64(t, &dfp.vt);\
 }
 
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
+DFP_HELPER_CTFIX(DCTFIX, 64)
+DFP_HELPER_CTFIX(DCTFIXQ, 128)
 
 void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
 {
@@ -1233,8 +1233,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b) \
 }  \
 }
 
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
+DFP_HELPER_XEX(DXEX, 64)
+DFP_HELPER_XEX(DXEXQ, 128)
 
 static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cb05cc168c..4c2a349ce6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -728,22 +728,22 @@ DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTDP, void, env, fprp, fprp)
+DEF_HELPER_3(DCTQPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DRSP, void, env, fprp, fprp)
+DEF_HELPER_3(DRDPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
+DEF_HELPER_3(DXEX, void, env, fprp, fprp)
+DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
diff --git

[PATCH v2 13/19] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
dtstdc:  DFP Test Data Class
dtstdcq: DFP Test Data Class Quad
dtstdg:  DFP Test Data Group
dtstdgq: DFP Test Data Group Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c |  8 +++
 target/ppc/helper.h |  8 +++
 target/ppc/insn32.decode| 14 +++
 target/ppc/translate/dfp-impl.c.inc | 36 -
 target/ppc/translate/dfp-ops.c.inc  | 10 
 5 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index ef1c370c3c..b4945fe48f 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -547,8 +547,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
+DFP_HELPER_TSTDC(DTSTDC, 64)
+DFP_HELPER_TSTDC(DTSTDCQ, 128)
 
 #define DFP_HELPER_TSTDG(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -602,8 +602,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
+DFP_HELPER_TSTDG(DTSTDG, 64)
+DFP_HELPER_TSTDG(DTSTDGQ, 128)
 
 #define DFP_HELPER_TSTEX(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 20041ce977..30e9247a5a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -708,10 +708,10 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
 DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6d97f9ae3b..38f8525d54 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -51,6 +51,12 @@
 %x_frbp 12:4 !function=times_2
 @X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
 
+&Z22_bf_fra bf fra dm
+@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   &Z22_bf_fra
+
+%z22_frap   17:4 !function=times_2
+@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -129,6 +135,14 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Test Instructions
+
+DTSTDC  111011 ... -- . .. 01110 -  @Z22_bf_fra
+DTSTDCQ 11 ... -- . .. 01110 -  @Z22_bf_frap
+
+DTSTDG  111011 ... -- . .. 011100010 -  @Z22_bf_fra
+DTSTDGQ 11 ... -- . .. 011100010 -  @Z22_bf_frap
+
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index e149777481..b9029841b3 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -63,22 +63,17 @@ static void gen_##name(DisasContext *ctx) \
 tcg_temp_free_ptr(rb);\
 }
 
-#define GEN_DFP_BF_A_DCM(name)\
-static void gen_##name(DisasContext *ctx) \
-{ \
-TCGv_ptr ra;  \
-TCGv_i32 dcm; \
-if (unlikely(!ctx->fpu_enabled)) {\
-gen_exception(ctx, POWERPC_EXCP_FPU); \
-return;   \
-} \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
-ra = gen_fprp_ptr(rA(ctx->opcode));   \
-dcm = tcg_const_i32(DCM(ctx->opcode));\
-gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
-  cpu_env, ra, dcm);  \
-tcg_temp_free_ptr(ra);\
-tcg_temp_free_i32(dcm);   \
+

[PATCH v2 16/19] target/ppc: Move dquai[q], drint{x, n}[q] to decodetree

2021-08-31 Thread Luis Pires
Move the following instructions to decodetree:
dquai:   DFP Quantize Immediate
dquaiq:  DFP Quantize Immediate Quad
drintx:  DFP Round to FP Integer With Inexact
drintxq: DFP Round to FP Integer With Inexact Quad
drintn:  DFP Round to FP Integer Without Inexact
drintnq: DFP Round to FP Integer Without Inexact Quad

Signed-off-by: Luis Pires 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/ppc/dfp_helper.c | 12 +++
 target/ppc/helper.h | 12 +++
 target/ppc/insn32.decode| 23 +
 target/ppc/translate/dfp-impl.c.inc | 52 +
 target/ppc/translate/dfp-ops.c.inc  | 18 --
 5 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b6634134d9..56d8846308 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -752,8 +752,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
+DFP_HELPER_QUAI(DQUAI, 64)
+DFP_HELPER_QUAI(DQUAIQ, 128)
 
 #define DFP_HELPER_QUA(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,\
@@ -874,8 +874,8 @@ static void RINTX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
+DFP_HELPER_RINT(DRINTX, RINTX_PPs, 64)
+DFP_HELPER_RINT(DRINTXQ, RINTX_PPs, 128)
 
 static void RINTN_PPs(struct PPC_DFP *dfp)
 {
@@ -883,8 +883,8 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
+DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
+DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 22bf167b15..520cce8378 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -718,16 +718,16 @@ DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_3(dctdp, void, env, fprp, fprp)
 DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
 DEF_HELPER_3(drsp, void, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index aaeccebca0..f0e17580e0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,6 +77,18 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
+%z23_frtp   22:4 !function=times_2
+%z23_frbp   12:4 !function=times_2
+@Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_te_tb  te frt frb rmc rc:bool
+@Z23_te_tb  .. frt:5 te:5 frb:5 rmc:2  rc:1 &Z23_te_tb
+
+@Z23_te_tbp .. 0 te:5 0 rmc:2  rc:1 &Z23_te_tb 
frt=%z23_frtp frb=%z23_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -194,6 +206,17 @@ DTSTSFQ 11 ... -- . . 1010100010 -  
@X_bf_a_bp
 DTSTSFI 111011 ... - .. . 1010100011 -  @X_bf_uim
 DTSTSFIQ11 ... - .. . 1010100011 -  @X_bf_uim_bp
 
+### Decimal Floating-Point Quantum Adjustment Instructions
+
+DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
+DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
+
+DRINTX  111011 .  . . .. 01100011 . @Z23_tb
+DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
+
+DRINTN  111011 .  . . .. 11100011 . @Z23_tb
+DRINTNQ 11 .  . . .. 11100011 . @Z23_t

[PATCH v2 12/19] target/ppc: Implement DCTFIXQQ

2021-08-31 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dctfixqq: DFP Convert To Fixed Quadword Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 53 +
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  5 +++
 target/ppc/translate/dfp-impl.c.inc | 17 +
 4 files changed, 76 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 01a7ead783..ef1c370c3c 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -51,6 +51,12 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 dfp[1].VsrD(0) = src->VsrD(1);
 }
 
+static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
+{
+dst->VsrD(0) = src->VsrD(0);
+dst->VsrD(1) = src->VsrD(1);
+}
+
 struct PPC_DFP {
 CPUPPCState *env;
 ppc_vsr_t vt, va, vb;
@@ -1019,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
+void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, 0, b, env);
+
+if (unlikely(decNumberIsSpecial(&dfp.b))) {
+uint64_t invalid_flags = FP_VX | FP_VXCVI;
+if (decNumberIsInfinite(&dfp.b)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+} else { /* NaN */
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+if (decNumberIsSNaN(&dfp.b)) {
+invalid_flags |= FP_VXSNAN;
+}
+}
+dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);
+} else if (unlikely(decNumberIsZero(&dfp.b))) {
+dfp.vt.VsrD(0) = 0;
+dfp.vt.VsrD(1) = 0;
+} else {
+decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);
+decNumberIntegralToInt128(&dfp.b, &dfp.context,
+&dfp.vt.VsrD(1), &dfp.vt.VsrD(0));
+if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);
+} else {
+dfp_check_for_XX(&dfp);
+}
+}
+
+set_dfp128_to_avr(t, &dfp.vt);
+}
+
 static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
 unsigned n)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fff7bd46ad..20041ce977 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -737,6 +737,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 92ea2d0739..6d97f9ae3b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -47,6 +47,10 @@
 %x_frtp 22:4 !function=times_2
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
+&X_vrt_frbp vrt frbp
+%x_frbp 12:4 !function=times_2
+@X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -128,6 +132,7 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+DCTFIXQQ11 . 1 . 100010 -   @X_vrt_frbp
 
 ## Vector Bit Manipulation Instruction
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index d5b66567a6..e149777481 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ 
*a)
 
 return true;
 }
+
+static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_avr_ptr(a->vrt);
+rb = gen_fprp_ptr(a->frbp);
+gen_helper_DCTFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v2 07/19] target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

2021-08-31 Thread Luis Pires
From: Bruno Larsen 

Move REQUIRE_ALTIVEC to translate.c and rename it to REQUIRE_VECTOR.

Signed-off-by: Bruno Larsen 
Signed-off-by: Matheus Ferst 
Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
---
 target/ppc/translate.c |  8 
 target/ppc/translate/vector-impl.c.inc | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 171b216e17..4749ecdaa9 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7453,6 +7453,14 @@ static int times_4(DisasContext *ctx, int x)
 # define REQUIRE_64BIT(CTX)  REQUIRE_INSNS_FLAGS(CTX, 64B)
 #endif
 
+#define REQUIRE_VECTOR(CTX) \
+do {\
+if (unlikely(!(CTX)->altivec_enabled)) {\
+gen_exception((CTX), POWERPC_EXCP_VPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
diff --git a/target/ppc/translate/vector-impl.c.inc 
b/target/ppc/translate/vector-impl.c.inc
index 117ce9b137..197e903337 100644
--- a/target/ppc/translate/vector-impl.c.inc
+++ b/target/ppc/translate/vector-impl.c.inc
@@ -17,20 +17,12 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define REQUIRE_ALTIVEC(CTX) \
-do {\
-if (unlikely(!(CTX)->altivec_enabled)) {\
-gen_exception((CTX), POWERPC_EXCP_VPU); \
-return true;\
-}   \
-} while (0)
-
 static bool trans_VCFUGED(DisasContext *ctx, arg_VX *a)
 {
 TCGv_i64 tgt, src, mask;
 
 REQUIRE_INSNS_FLAGS2(ctx, ISA310);
-REQUIRE_ALTIVEC(ctx);
+REQUIRE_VECTOR(ctx);
 
 tgt = tcg_temp_new_i64();
 src = tcg_temp_new_i64();
-- 
2.25.1




[PATCH v2 11/19] libdecnumber: Introduce decNumberIntegralToInt128

2021-08-31 Thread Luis Pires
This will be used to implement PowerPC's dctfixqq.

Signed-off-by: Luis Pires 
---
 include/libdecnumber/decNumber.h  |  2 +
 include/libdecnumber/decNumberLocal.h |  2 +-
 libdecnumber/decContext.c |  7 +-
 libdecnumber/decNumber.c  | 94 +++
 4 files changed, 101 insertions(+), 4 deletions(-)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 0cf69c7db2..41bc2a0d36 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -124,6 +124,8 @@
   uint32_tdecNumberToUInt32(const decNumber *, decContext *);
   int32_t decNumberToInt32(const decNumber *, decContext *);
   int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
+  voiddecNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh);
   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
 
diff --git a/include/libdecnumber/decNumberLocal.h 
b/include/libdecnumber/decNumberLocal.h
index 4d53c077f2..6198ca8593 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
 
   /* Shared lookup tables*/
   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
-  extern const uLong  DECPOWERS[19];/* powers of ten table*/
+  extern const uLong  DECPOWERS[20];/* powers of ten table*/
   /* The following are included from decDPD.h*/
   extern const uShort DPD2BIN[1024];   /* DPD -> 0-999   */
   extern const uShort BIN2DPD[1000];   /* 0-999 -> DPD   */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 7d97a65ac5..1956edf0a7 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -53,12 +53,13 @@ static  const  Flag *mfctop=(Flag *)&mfcone; /* -> top 
byte */
 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
 
 /* -- */
-/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
 /* -- */
-const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100,
+const uLong DECPOWERS[20] = {1, 10, 100, 1000, 1, 10, 100,
   1000, 1, 10, 100ULL, 1000ULL,
   1ULL, 10ULL, 100ULL, 1000ULL,
-  1ULL, 10ULL, 100ULL, };
+  1ULL, 10ULL, 100ULL,
+  1000ULL,};
 
 /* -- */
 /* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 75c09ba052..4474f0dd11 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -264,6 +264,7 @@ static decNumber * decTrim(decNumber *, decContext *, Flag, 
Int *);
 static IntdecUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
  Unit *, Int);
 static IntdecUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+static boolmulUInt128ByPowOf10(uLong *, uLong *, uInt);
 
 #if !DECSUBSET
 /* decFinish == decFinalize when no subset arithmetic needed */
@@ -542,6 +543,67 @@ Invalid:
 return 0;
 } /* decNumberIntegralToInt64 */
 
+/* -- */
+/* decNumberIntegralToInt128 -- conversion to int128  */
+/**/
+/*  dn is the decNumber to convert.  dn is assumed to have been   */
+/*rounded to a floating point integer value.  */
+/*  set is the context for reporting errors   */
+/*  returns the converted decNumber via plow and phigh*/
+/**/
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/
+/* range for a signed 128 bit integer.*/
+/* -- */
+
+void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh)
+{
+if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+   (dn->digits + dn->exponent > 39)) {
+goto Invalid;
+} else {
+int d;/* work */
+const Unit *up;   /* .. */
+uint64_t lo = 0, hi = 0;
+up = dn->lsu; /* -> lsu */
+
+   

[PATCH v2 10/19] host-utils: Introduce mulu128

2021-08-31 Thread Luis Pires
Signed-off-by: Luis Pires 
---
 include/qemu/host-utils.h | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 6f18b29921..9f40077083 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -588,6 +588,44 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, 
uint64_t *ret)
 #endif
 }
 
+/*
+ * Unsigned 128x64 multiplication.
+ * Returns true if the result got truncated to 128 bits.
+ * Otherwise, returns false and the multiplication result via plow and phigh.
+ */
+static inline bool mulu128(uint64_t *plow, uint64_t *phigh, uint64_t factor)
+{
+#if defined(CONFIG_INT128) && \
+(__has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5)
+bool res;
+__uint128_t r;
+__uint128_t f = ((__uint128_t)*phigh << 64) | *plow;
+res = __builtin_mul_overflow(f, factor, &r);
+
+*plow = r;
+*phigh = r >> 64;
+
+return res;
+#else
+uint64_t dhi = *phigh;
+uint64_t dlo = *plow;
+uint64_t ahi;
+uint64_t blo, bhi;
+
+if (dhi == 0) {
+mulu64(plow, phigh, dlo, factor);
+return false;
+}
+
+mulu64(plow, &ahi, dlo, factor);
+mulu64(&blo, &bhi, dhi, factor);
+
+*phigh = ahi + blo;
+
+return (bhi > 0) || (*phigh < ahi);
+#endif
+}
+
 /**
  * uadd64_carry - addition with carry-in and carry-out
  * @x, @y: addends
-- 
2.25.1




[PATCH v2 05/19] host-utils: add unit tests for divu128/divs128

2021-08-31 Thread Luis Pires
Signed-off-by: Luis Pires 
---
 tests/unit/meson.build   |   1 +
 tests/unit/test-div128.c | 185 +++
 2 files changed, 186 insertions(+)
 create mode 100644 tests/unit/test-div128.c

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 5736d285b2..96e3b23162 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -23,6 +23,7 @@ tests = {
   # all code tested by test-x86-cpuid is inside topology.h
   'test-x86-cpuid': [],
   'test-cutils': [],
+  'test-div128': [],
   'test-shift128': [],
   'test-mul64': [],
   # all code tested by test-int128 is inside int128.h
diff --git a/tests/unit/test-div128.c b/tests/unit/test-div128.c
new file mode 100644
index 00..5dc39fe6d1
--- /dev/null
+++ b/tests/unit/test-div128.c
@@ -0,0 +1,185 @@
+/*
+ * Test 128-bit division functions
+ *
+ * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+
+typedef struct {
+uint64_t high;
+uint64_t low;
+uint64_t rhigh;
+uint64_t rlow;
+uint64_t divisor;
+uint64_t remainder;
+} test_data_unsigned;
+
+typedef struct {
+int64_t high;
+uint64_t low;
+int64_t rhigh;
+uint64_t rlow;
+int64_t divisor;
+int64_t remainder;
+} test_data_signed;
+
+static const test_data_unsigned test_table_unsigned[] = {
+/* Dividend fits in 64 bits */
+{ 0xULL, 0xULL,
+  0xULL, 0xULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0001ULL,
+  0xULL, 0x0001ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0003ULL,
+  0xULL, 0x0001ULL,
+  0x0002ULL, 0x0001ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x8000ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0xa000ULL,
+  0xULL, 0x0002ULL,
+  0x4000ULL, 0x2000ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x0001ULL,
+  0x8000ULL, 0xULL},
+
+/* Dividend > 64 bits, with MSB 0 */
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0xULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0x000dULL,
+  0x123456789abcdefeULL, 0x03456789abcdf03bULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0123456789abcdefULL, 0xeefedcba98765432ULL,
+  0x0010ULL, 0x0001ULL},
+
+/* Dividend > 64 bits, with MSB 1 */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0feeddccbbaa9988ULL, 0x7766554433221100ULL,
+  0x0010ULL, 0x000fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x000eULL, 0x00f0f0f0f0f0f35aULL,
+  0x123456789abcdefeULL, 0x0f8922bc55ef90c3ULL},
+
+/* Dividend > 64 bits, divisor almost as big */
+{ 0x0001ULL, 0x23456789abcdef01ULL,
+  0xULL, 0x000fULL,
+  0x123456789abcdefeULL, 0x123456789abcde1fULL},
+};
+
+static const test_data_signed test_table_signed[] = {
+/* Positive dividend, positive/negative divisors */
+{ 0xLL, 0x00bc614eULL,
+  0xLL, 0x00bc614eULL,
+  0x0001LL, 0xLL},
+{ 0xLL, 0x00bc614eULL,
+  0xLL, 0xff439eb2ULL,
+  0xLL, 0x000

[PATCH v2 08/19] target/ppc: Introduce REQUIRE_FPU

2021-08-31 Thread Luis Pires
From: Fernando Valle 

Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
Reviewed-by: David Gibson 
---
 target/ppc/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4749ecdaa9..5489b4b6e0 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7461,6 +7461,14 @@ static int times_4(DisasContext *ctx, int x)
 }   \
 } while (0)
 
+#define REQUIRE_FPU(ctx)\
+do {\
+if (unlikely(!(ctx)->fpu_enabled)) {\
+gen_exception((ctx), POWERPC_EXCP_FPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
-- 
2.25.1




[PATCH v2 09/19] target/ppc: Implement DCFFIXQQ

2021-08-31 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dcffixqq: DFP Convert From Fixed Quadword Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 11 +++
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  8 
 target/ppc/translate.c  |  7 ++-
 target/ppc/translate/dfp-impl.c.inc | 17 +
 5 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 07341a69f5..01a7ead783 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -970,6 +970,17 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
+void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, NULL, NULL, env);
+decNumberFromInt128(&dfp.t, (uint64_t)b->VsrD(1), (int64_t)b->VsrD(0));
+dfp_finalize_decimal128(&dfp);
+CFFIX_PPs(&dfp);
+
+set_dfp128(t, &dfp.vt);
+}
+
 #define DFP_HELPER_CTFIX(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)  \
 { \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fff7bd46ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -734,6 +734,7 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp)
 DEF_HELPER_3(drdpq, void, env, fprp, fprp)
 DEF_HELPER_3(dcffix, void, env, fprp, fprp)
 DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..92ea2d0739 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -43,6 +43,10 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_frtp_vrb frtp vrb
+%x_frtp 22:4 !function=times_2
+@X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -121,6 +125,10 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Conversion Instructions
+
+DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 5489b4b6e0..c3739f7370 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7422,7 +7422,12 @@ static inline void set_avr64(int regno, TCGv_i64 src, 
bool high)
 /*
  * Helpers for decodetree used by !function for decoding arguments.
  */
-static int times_4(DisasContext *ctx, int x)
+static inline int times_2(DisasContext *ctx, int x)
+{
+return x * 2;
+}
+
+static inline int times_4(DisasContext *ctx, int x)
 {
 return x * 4;
 }
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 6c556dc2e1..d5b66567a6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -230,3 +230,20 @@ GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 #undef GEN_DFP_T_A_B_I32_Rc
 #undef GEN_DFP_T_B_Rc
 #undef GEN_DFP_T_FPR_I32_Rc
+
+static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_fprp_ptr(a->frtp);
+rb = gen_avr_ptr(a->vrb);
+gen_helper_DCFFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH v2 04/19] host-utils: add 128-bit quotient support to divu128/divs128

2021-08-31 Thread Luis Pires
These will be used to implement new decimal floating point
instructions from Power ISA 3.1.

A new argument, prem, was added to divu128/divs128 to receive the
remainder, freeing up phigh to receive the high 64 bits of the
quotient.

For scenarios supported by the previous implementation
(<= 64-bit quotient) with large (> 64-bit) dividends, testing showed
that:
- when dividend >> divisor, the performance of the new implementation
is equivalent to the old one.
- as the dividend and the divisor get closer (e.g. 65-bit dividend and
64-bit divisor), the performance is significantly improved, due to the
smaller number of shift-subtract iterations.

Signed-off-by: Luis Pires 
---
 include/hw/clock.h|   8 +--
 include/qemu/host-utils.h |  20 --
 target/ppc/int_helper.c   |  13 ++--
 util/host-utils.c | 128 +++---
 4 files changed, 113 insertions(+), 56 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 5a40a076aa..2f162f7a6f 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -319,12 +319,8 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 if (clk->period == 0) {
 return 0;
 }
-/*
- * BUG: when CONFIG_INT128 is not defined, the current implementation of
- * divu128 does not return a valid truncated quotient, so the result will
- * be wrong.
- */
-divu128(&lo, &hi, clk->period);
+
+divu128(&lo, &hi, NULL, clk->period);
 return lo;
 }
 
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 3648ca6759..6f18b29921 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,26 +52,34 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t *prem,
+   uint64_t divisor)
 {
 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
 __uint128_t result = dividend / divisor;
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+if (prem) {
+*prem = dividend % divisor;
+}
 }
 
-static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem,
+   int64_t divisor)
 {
 __int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
 __int128_t result = dividend / divisor;
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+if (prem) {
+*prem = dividend % divisor;
+}
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t *prem, uint64_t 
divisor);
+void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 510faf24cf..b3d302390a 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -108,7 +108,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 overflow = 1;
 rt = 0; /* Undefined */
 } else {
-divu128(&rt, &ra, rb);
+divu128(&rt, &ra, NULL, rb);
 }
 
 if (oe) {
@@ -120,7 +120,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 
 uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t 
oe)
 {
-int64_t rt = 0;
+uint64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
 int overflow = 0;
@@ -129,7 +129,7 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 overflow = 1;
 rt = 0; /* Undefined */
 } else {
-divs128(&rt, &ra, rb);
+divs128(&rt, &ra, NULL, rb);
 }
 
 if (oe) {
@@ -2506,6 +2506,7 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 int cr;
 uint64_t lo_value;
 uint64_t hi_value;
+uint64_t rem;
 ppc_avr_t ret = { .u64 = { 0, 0 } };
 
 if (b->VsrSD(0) < 0) {
@@ -2541,10 +2542,10 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
  * In that case, we leave r unchanged.
  */
 } else {
-divu128(&lo_value, &hi_value, 1000ULL);
+divu128(&lo_value, &hi_value, &rem, 1000ULL);
 
-for (i = 1; i < 16; hi_value /= 10, i++) {
-bcd_put_

[PATCH v2 02/19] host-utils: move abs64() to host-utils as uabs64()

2021-08-31 Thread Luis Pires
Move abs64 to host-utils as uabs64, so it can be used elsewhere.
The function was renamed to uabs64 and modified to return an
unsigned value. This avoids the undefined behavior for common
abs implementations, where abs of the most negative value is
undefined.

Signed-off-by: Luis Pires 
---
 hw/i386/kvm/i8254.c   | 7 +--
 include/qemu/host-utils.h | 8 
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index fa68669e8a..191a26fa57 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -59,11 +59,6 @@ struct KVMPITClass {
 DeviceRealize parent_realize;
 };
 
-static int64_t abs64(int64_t v)
-{
-return v < 0 ? -v : v;
-}
-
 static void kvm_pit_update_clock_offset(KVMPITState *s)
 {
 int64_t offset, clock_offset;
@@ -81,7 +76,7 @@ static void kvm_pit_update_clock_offset(KVMPITState *s)
 clock_gettime(CLOCK_MONOTONIC, &ts);
 offset -= ts.tv_nsec;
 offset -= (int64_t)ts.tv_sec * 10;
-if (abs64(offset) < abs64(clock_offset)) {
+if (uabs64(offset) < uabs64(clock_offset)) {
 clock_offset = offset;
 }
 }
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 711b221704..0c6715774c 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -357,6 +357,14 @@ static inline uint64_t revbit64(uint64_t x)
 #endif
 }
 
+/**
+ * Return the absolute value of a 64-bit integer as an unsigned 64-bit value
+ */
+static inline uint64_t uabs64(int64_t v)
+{
+return v < 0 ? -v : v;
+}
+
 /**
  * sadd32_overflow - addition with overflow indication
  * @x, @y: addends
-- 
2.25.1




[PATCH v2 03/19] host-utils: move checks out of divu128/divs128

2021-08-31 Thread Luis Pires
In preparation for changing the divu128/divs128 implementations
to allow for quotients larger than 64 bits, move the div-by-zero
and overflow checks to the callers.

Signed-off-by: Luis Pires 
---
 include/hw/clock.h|  5 +++--
 include/qemu/host-utils.h | 36 +---
 target/ppc/int_helper.c   | 14 +-
 util/host-utils.c | 39 +++
 4 files changed, 44 insertions(+), 50 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index a7187eab95..5a40a076aa 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -320,8 +320,9 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 return 0;
 }
 /*
- * Ignore divu128() return value as we've caught div-by-zero and don't
- * need different behaviour for overflow.
+ * BUG: when CONFIG_INT128 is not defined, the current implementation of
+ * divu128 does not return a valid truncated quotient, so the result will
+ * be wrong.
  */
 divu128(&lo, &hi, clk->period);
 return lo;
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 0c6715774c..3648ca6759 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,36 +52,26 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
-{
-if (divisor == 0) {
-return 1;
-} else {
-__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
-__uint128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result > UINT64_MAX;
-}
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
+__uint128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 
-static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
 {
-if (divisor == 0) {
-return 1;
-} else {
-__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
-__int128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result != *plow;
-}
+__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
+__int128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f5dac3aa87..510faf24cf 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -104,10 +104,11 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 uint64_t rt = 0;
 int overflow = 0;
 
-overflow = divu128(&rt, &ra, rb);
-
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || ra >= rb)) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divu128(&rt, &ra, rb);
 }
 
 if (oe) {
@@ -122,10 +123,13 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 int64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
-int overflow = divs128(&rt, &ra, rb);
+int overflow = 0;
 
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || uabs64(ra) >= uabs64(rb))) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divs128(&rt, &ra, rb);
 }
 
 if (oe) {
diff --git a/util/host-utils.c b/util/host-utils.c
index a789a11b46..ff75fdf1e1 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -86,10 +86,14 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 *phigh = rh;
 }
 
-/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
-/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
-/* remainder via phigh. */
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+/*
+ * Unsigned 128-by-64 division. Returns quotient via plow and
+ * remainder via phigh.
+ * The result must fit in 64 bits (plow) - otherwise, the result
+ * is undefined.
+ * This function will cause a division by zero if passed a zero divisor.
+ */
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_

[PATCH v2 06/19] libdecnumber: introduce decNumberFrom[U]Int128

2021-08-31 Thread Luis Pires
This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires 
---
 include/libdecnumber/decNumber.h |  2 ++
 libdecnumber/decNumber.c | 36 
 2 files changed, 38 insertions(+)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed07..0cf69c7db2 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -116,6 +116,8 @@
   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
   decNumber *decNumberFromInt64(decNumber *, int64_t);
   decNumber *decNumberFromUInt64(decNumber *, uint64_t);
+  decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
+  decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
   char * decNumberToString(const decNumber *, char *);
   char * decNumberToEngString(const decNumber *, char *);
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 1ffe458ad8..75c09ba052 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -167,6 +167,7 @@
 /* -- */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "libdecnumber/dconfig.h"
 #include "libdecnumber/decNumber.h"
 #include "libdecnumber/decNumberLocal.h"
@@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
 return dn;
 } /* decNumberFromUInt64 */
 
+decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
+{
+uint64_t unsig_hi = hi;
+if (hi < 0) {
+if (lo == 0) {
+unsig_hi = -unsig_hi;
+} else {
+unsig_hi = ~unsig_hi;
+lo = -lo;
+}
+}
+
+decNumberFromUInt128(dn, lo, unsig_hi);
+if (hi < 0) {
+dn->bits = DECNEG;/* sign needed */
+}
+return dn;
+} /* decNumberFromInt128 */
+
+decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
+{
+uint64_t rem;
+Unit *up; /* work pointer */
+decNumberZero(dn);/* clean */
+if (lo == 0 && hi == 0) {
+return dn;/* [or decGetDigits bad call] */
+}
+for (up = dn->lsu; hi > 0 || lo > 0; up++) {
+divu128(&lo, &hi, &rem, DECDPUNMAX + 1);
+*up = (Unit)rem;
+}
+dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+return dn;
+} /* decNumberFromUInt128 */
+
 /* -- */
 /* to-int64 -- conversion to int64*/
 /**/
-- 
2.25.1




[PATCH v2 01/19] host-utils: Fix overflow detection in divu128()

2021-08-31 Thread Luis Pires
The previous code didn't detect overflows if the high 64-bit
of the dividend were equal to the 64-bit divisor. In that case,
64 bits wouldn't be enough to hold the quotient.

Signed-off-by: Luis Pires 
---
 util/host-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/host-utils.c b/util/host-utils.c
index 7b9322071d..a789a11b46 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -102,7 +102,7 @@ int divu128(uint64_t *plow, uint64_t *phigh, uint64_t 
divisor)
 *plow  = dlo / divisor;
 *phigh = dlo % divisor;
 return 0;
-} else if (dhi > divisor) {
+} else if (dhi >= divisor) {
 return 1;
 } else {
 
-- 
2.25.1




[PATCH v2 00/19] target/ppc: DFP instructions using decodetree

2021-08-31 Thread Luis Pires
This series moves all existing DFP instructions to decodetree and
implements the 2 new instructions (dcffixqq and dctfixqq) from
Power ISA 3.1.

In order to implement dcffixqq, divu128/divs128 were modified to
support 128-bit quotients (previously, they were limited to 64-bit
quotients), along with adjustments being made to its existing callers.
libdecnumber was also expanded to allow creating decimal numbers from
128-bit integers.

Similarly, for dctfixqq, mulu128 (host-utils) and decNumberIntegralToInt128
(libdecnumber) were introduced to support 128-bit integers.

The remaining patches of this series move all of the already existing
DFP instructions to decodetree, and end up removing dfp-ops.c.inc, which
is no longer needed.

NOTE 1: The previous, non-decodetree code, was updating ctx->nip for all the
DFP instructions. I've removed that, but it would be great if someone could
confirm that updating nip really wasn't necessary.

NOTE 2: Some arithmetic function support for 128-bit integers was added,
for now, still using 64-bit pairs. In the near future, I think we should
modify all of them to use Int128 (and introduce UInt128). But that
should be done in another patch series.

Based-on: 20210823150235.35759-1-luis.pi...@eldorado.org.br
(target/ppc: fix setting of CR flags in bcdcfsq)
This series assumes bcdcfsq's fix is already in.

Changes in v2:
- Renamed abs64() to uabs64()

Patches missing review:
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c
  host-utils: Fix overflow detection in divu128()
  host-utils: move abs64() to host-utils as uabs64()
  host-utils: move checks out of divu128/divs128
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>

Bruno Larsen (1):
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

Fernando Valle (1):
  target/ppc: Introduce REQUIRE_FPU

Luis Pires (17):
  host-utils: Fix overflow detection in divu128()
  host-utils: move abs64() to host-utils as uabs64()
  host-utils: move checks out of divu128/divs128
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree
  target/ppc: Move d{add,sub,mul,div,iex}[q] to decodetree
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree
  target/ppc: Move dquai[q], drint{x,n}[q] to decodetree
  target/ppc: Move dqua[q], drrnd[q] to decodetree
  target/ppc: Move dct{dp,qpq},dr{sp,dpq},dc{f,t}fix[q],dxex[q] to
decodetree
  target/ppc: Move ddedpd[q],denbcd[q],dscli[q],dscri[q] to decodetree

 hw/i386/kvm/i8254.c|   7 +-
 include/hw/clock.h |   7 +-
 include/libdecnumber/decNumber.h   |   4 +
 include/libdecnumber/decNumberLocal.h  |   2 +-
 include/qemu/host-utils.h  |  86 +++--
 libdecnumber/decContext.c  |   7 +-
 libdecnumber/decNumber.c   | 130 
 target/ppc/dfp_helper.c| 168 +++---
 target/ppc/helper.h| 106 ---
 target/ppc/insn32.decode   | 171 ++
 target/ppc/int_helper.c|  23 +-
 target/ppc/translate.c |  25 +-
 target/ppc/translate/dfp-impl.c.inc| 419 -
 target/ppc/translate/dfp-ops.c.inc | 165 --
 target/ppc/translate/vector-impl.c.inc |  10 +-
 tests/unit/meson.build |   1 +
 tests/unit/test-div128.c   | 185 +++
 util/host-utils.c  | 137 +---
 18 files changed, 1073 insertions(+), 580 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc
 create mode 100644 tests/unit/test-div128.c

-- 
2.25.1




[PATCH 19/19] target/ppc: Move ddedpd[q], denbcd[q], dscli[q], dscri[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
ddedpd:  DFP Decode DPD To BCD
ddedpdq: DFP Decode DPD To BCD Quad
denbcd:  DFP Encode BCD To DPD
denbcdq: DFP Encode BCD To DPD Quad
dscli:   DFP Shift Significand Left Immediate
dscliq:  DFP Shift Significand Left Immediate Quad
dscri:   DFP Shift Significand Right Immediate
dscriq:  DFP Shift Significand Right Immediate Quad

Also deleted dfp-ops.c.inc, now that all PPC DFP instructions were
moved to decodetree.

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 16 -
 target/ppc/helper.h | 16 -
 target/ppc/insn32.decode| 28 +++
 target/ppc/translate.c  |  2 --
 target/ppc/translate/dfp-impl.c.inc | 54 +
 target/ppc/translate/dfp-ops.c.inc  | 40 -
 6 files changed, 68 insertions(+), 88 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 7bb394c02b..0dcb1249f7 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1131,8 +1131,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
+DFP_HELPER_DEDPD(DDEDPD, 64)
+DFP_HELPER_DEDPD(DDEDPDQ, 128)
 
 static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
 {
@@ -1199,8 +1199,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 set_dfp##size(t, &dfp.vt);   \
 }
 
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
+DFP_HELPER_ENBCD(DENBCD, 64)
+DFP_HELPER_ENBCD(DENBCDQ, 128)
 
 #define DFP_HELPER_XEX(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
@@ -1387,7 +1387,7 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
+DFP_HELPER_SHIFT(DSCLI, 64, 1)
+DFP_HELPER_SHIFT(DSCLIQ, 128, 1)
+DFP_HELPER_SHIFT(DSCRI, 64, 0)
+DFP_HELPER_SHIFT(DSCRIQ, 128, 0)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4c2a349ce6..6fa3e15fe9 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -738,18 +738,18 @@ DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DDEDPDQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCD, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DENBCDQ, void, env, fprp, fprp, i32)
 DEF_HELPER_3(DXEX, void, env, fprp, fprp)
 DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCRIQ, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLI, void, env, fprp, fprp, i32)
+DEF_HELPER_4(DSCLIQ, void, env, fprp, fprp, i32)
 
 DEF_HELPER_1(tbegin, void, env)
 DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 2ce8b0ab95..6aec1c0728 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -74,6 +74,16 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_tb_sp_rc rt rb sp rc:bool
+@X_tb_sp_rc .. rt:5 sp:2 ... rb:5 .. rc:1   &X_tb_sp_rc
+
+@X_tbp_sp_rc.. 0 sp:2 ... 0 .. rc:1 &X_tb_sp_rc 
rt=%x_frtp rb=%x_frbp
+
+&X_tb_s_rc  rt rb s:bool rc:bool
+@X_tb_s_rc  .. rt:5 s:1  rb:5 .. rc:1   &X_tb_s_rc
+
+@X_tbp_s_rc .. 0 s:1  0 .. rc:1 &X_tb_s_rc 
rt=%x_frtp rb=%x_frbp
+
 &X_frtp_vrb frtp vrb
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
@@ -86,6 +96,12 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z22_ta_sh_rc   rt ra sh rc:bool
+@Z22_ta_sh_rc   .. rt:5 ra:5 sh:6 . rc:1&Z22_ta_sh_rc
+
+%z22_frtp   22:4 !function

[PATCH 17/19] target/ppc: Move dqua[q], drrnd[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
dqua:   DFP Quantize
dquaq:  DFP Quantize Quad
drrnd:  DFP Reround
drrndq: DFP Reround Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c |  8 ++---
 target/ppc/helper.h |  8 ++---
 target/ppc/insn32.decode| 18 --
 target/ppc/translate/dfp-impl.c.inc | 51 +
 target/ppc/translate/dfp-ops.c.inc  | 25 --
 5 files changed, 47 insertions(+), 63 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 56d8846308..9c75cbb79b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -770,8 +770,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
+DFP_HELPER_QUA(DQUA, 64)
+DFP_HELPER_QUA(DQUAQ, 128)
 
 static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
  struct PPC_DFP *dfp)
@@ -848,8 +848,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
+DFP_HELPER_RRND(DRRND, 64)
+DFP_HELPER_RRND(DRRNDQ, 128)
 
 #define DFP_HELPER_RINT(op, postprocs, size)   
\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b,   
\
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 520cce8378..cb05cc168c 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -720,10 +720,10 @@ DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUA, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DQUAQ, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRND, void, env, fprp, fprp, fprp, i32)
+DEF_HELPER_5(DRRNDQ, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index f0e17580e0..86dbdada47 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,11 +77,19 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
-&Z23_tb frt frb r:bool rmc rc:bool
-@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+&Z23_tabfrt fra frb rmc rc:bool
+@Z23_tab.. frt:5 fra:5 frb:5 rmc:2  rc:1&Z23_tab
 
 %z23_frtp   22:4 !function=times_2
+%z23_frap   17:4 !function=times_2
 %z23_frbp   12:4 !function=times_2
+@Z23_tabp   .. 0 0 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp fra=%z23_frap frb=%z23_frbp
+
+@Z23_tp_a_bp.. 0 fra:5 0 rmc:2  rc:1&Z23_tab 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
 @Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
 
 &Z23_te_tb  te frt frb rmc rc:bool
@@ -211,6 +219,12 @@ DTSTSFIQ11 ... - .. . 1010100011 -  
@X_bf_uim_bp
 DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
 DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
 
+DQUA111011 . . . .. 0011 .  @Z23_tab
+DQUAQ   11 . . . .. 0011 .  @Z23_tabp
+
+DRRND   111011 . . . .. 00100011 .  @Z23_tab
+DRRNDQ  11 . . . .. 00100011 .  @Z23_tp_a_bp
+
 DRINTX  111011 .  . . .. 01100011 . @Z23_tb
 DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index a499b17e7c..73c8906b45 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -86,29 +86,25 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  
 \
 return true; \
 }
 
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)   \
-static void gen_##name(DisasContext *ctx)\
-{\
-TCGv_ptr rt, ra, rb; \
-TCGv_i32 i32;\
-if (unlikely(!ctx->

[PATCH 18/19] target/ppc: Move dct{dp, qpq}, dr{sp, dpq}, dc{f, t}fix[q], dxex[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
dctdp:   DFP Convert To DFP Long
dctqpq:  DFP Convert To DFP Extended
drsp:DFP Round To DFP Short
drdpq:   DFP Round To DFP Long
dcffix:  DFP Convert From Fixed
dcffixq: DFP Convert From Fixed Quad
dctfix:  DFP Convert To Fixed
dctfixq: DFP Convert To Fixed Quad
dxex:DFP Extract Biased Exponent
dxexq:   DFP Extract Biased Exponent Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 20 +--
 target/ppc/helper.h | 20 +--
 target/ppc/insn32.decode| 23 
 target/ppc/translate/dfp-impl.c.inc | 55 ++---
 target/ppc/translate/dfp-ops.c.inc  | 22 
 5 files changed, 69 insertions(+), 71 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 9c75cbb79b..7bb394c02b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -886,7 +886,7 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
 DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
-void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTDP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -902,7 +902,7 @@ void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 dfp_set_FPRF_from_FRT(&dfp);
 }
 
-void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DCTQPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 ppc_vsr_t vb;
@@ -917,7 +917,7 @@ void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp128(t, &dfp.vt);
 }
 
-void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRSP(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 uint32_t t_short = 0;
@@ -935,7 +935,7 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)
 set_dfp64(t, &vt);
 }
 
-void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
+void helper_DRDPQ(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
 struct PPC_DFP dfp;
 dfp_prepare_decimal128(&dfp, 0, b, env);
@@ -973,8 +973,8 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_XX(dfp);
 }
 
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
+DFP_HELPER_CFFIX(DCFFIX, 64)
+DFP_HELPER_CFFIX(DCFFIXQ, 128)
 
 void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
 {
@@ -1022,8 +1022,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 set_dfp64(t, &dfp.vt);\
 }
 
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
+DFP_HELPER_CTFIX(DCTFIX, 64)
+DFP_HELPER_CTFIX(DCTFIXQ, 128)
 
 void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
 {
@@ -1233,8 +1233,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b) \
 }  \
 }
 
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
+DFP_HELPER_XEX(DXEX, 64)
+DFP_HELPER_XEX(DXEXQ, 128)
 
 static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cb05cc168c..4c2a349ce6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -728,22 +728,22 @@ DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTDP, void, env, fprp, fprp)
+DEF_HELPER_3(DCTQPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DRSP, void, env, fprp, fprp)
+DEF_HELPER_3(DRDPQ, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIX, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQ, void, env, fprp, fprp)
 DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
+DEF_HELPER_3(DXEX, void, env, fprp, fprp)
+DEF_HELPER_3(DXEXQ, void, env, fprp, fprp)
 DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/targ

[PATCH 13/19] target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
dtstdc:  DFP Test Data Class
dtstdcq: DFP Test Data Class Quad
dtstdg:  DFP Test Data Group
dtstdgq: DFP Test Data Group Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c |  8 +++
 target/ppc/helper.h |  8 +++
 target/ppc/insn32.decode| 14 +++
 target/ppc/translate/dfp-impl.c.inc | 36 -
 target/ppc/translate/dfp-ops.c.inc  | 10 
 5 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index ef1c370c3c..b4945fe48f 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -547,8 +547,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
+DFP_HELPER_TSTDC(DTSTDC, 64)
+DFP_HELPER_TSTDC(DTSTDCQ, 128)
 
 #define DFP_HELPER_TSTDG(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -602,8 +602,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
uint32_t dcm)  \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
+DFP_HELPER_TSTDG(DTSTDG, 64)
+DFP_HELPER_TSTDG(DTSTDGQ, 128)
 
 #define DFP_HELPER_TSTEX(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 20041ce977..30e9247a5a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -708,10 +708,10 @@ DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
+DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
 DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
 DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6d97f9ae3b..38f8525d54 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -51,6 +51,12 @@
 %x_frbp 12:4 !function=times_2
 @X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
 
+&Z22_bf_fra bf fra dm
+@Z22_bf_fra .. bf:3 .. fra:5 dm:6 . .   &Z22_bf_fra
+
+%z22_frap   17:4 !function=times_2
+@Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -129,6 +135,14 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Test Instructions
+
+DTSTDC  111011 ... -- . .. 01110 -  @Z22_bf_fra
+DTSTDCQ 11 ... -- . .. 01110 -  @Z22_bf_frap
+
+DTSTDG  111011 ... -- . .. 011100010 -  @Z22_bf_fra
+DTSTDGQ 11 ... -- . .. 011100010 -  @Z22_bf_frap
+
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index e149777481..b9029841b3 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -63,22 +63,17 @@ static void gen_##name(DisasContext *ctx) \
 tcg_temp_free_ptr(rb);\
 }
 
-#define GEN_DFP_BF_A_DCM(name)\
-static void gen_##name(DisasContext *ctx) \
-{ \
-TCGv_ptr ra;  \
-TCGv_i32 dcm; \
-if (unlikely(!ctx->fpu_enabled)) {\
-gen_exception(ctx, POWERPC_EXCP_FPU); \
-return;   \
-} \
-gen_update_nip(ctx, ctx->base.pc_next - 4);   \
-ra = gen_fprp_ptr(rA(ctx->opcode));   \
-dcm = tcg_const_i32(DCM(ctx->opcode));\
-gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
-  cpu_env, ra, dcm);  \
-tcg_temp_free_ptr(ra);\
-tcg_temp_free_i32(dcm);   \
+#define TRANS_DFP_BF_A_DCM(NAME)   

[PATCH 11/19] libdecnumber: Introduce decNumberIntegralToInt128

2021-08-24 Thread Luis Pires
This will be used to implement PowerPC's dctfixqq.

Signed-off-by: Luis Pires 
---
 include/libdecnumber/decNumber.h  |  2 +
 include/libdecnumber/decNumberLocal.h |  2 +-
 libdecnumber/decContext.c |  7 +-
 libdecnumber/decNumber.c  | 94 +++
 4 files changed, 101 insertions(+), 4 deletions(-)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 0cf69c7db2..41bc2a0d36 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -124,6 +124,8 @@
   uint32_tdecNumberToUInt32(const decNumber *, decContext *);
   int32_t decNumberToInt32(const decNumber *, decContext *);
   int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
+  voiddecNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh);
   uint8_t   * decNumberGetBCD(const decNumber *, uint8_t *);
   decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
 
diff --git a/include/libdecnumber/decNumberLocal.h 
b/include/libdecnumber/decNumberLocal.h
index 4d53c077f2..6198ca8593 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
 
   /* Shared lookup tables*/
   extern const uByte  DECSTICKYTAB[10]; /* re-round digits if sticky  */
-  extern const uLong  DECPOWERS[19];/* powers of ten table*/
+  extern const uLong  DECPOWERS[20];/* powers of ten table*/
   /* The following are included from decDPD.h*/
   extern const uShort DPD2BIN[1024];   /* DPD -> 0-999   */
   extern const uShort BIN2DPD[1000];   /* 0-999 -> DPD   */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 7d97a65ac5..1956edf0a7 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -53,12 +53,13 @@ static  const  Flag *mfctop=(Flag *)&mfcone; /* -> top 
byte */
 const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
 
 /* -- */
-/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
+/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
 /* -- */
-const uLong DECPOWERS[19] = {1, 10, 100, 1000, 1, 10, 100,
+const uLong DECPOWERS[20] = {1, 10, 100, 1000, 1, 10, 100,
   1000, 1, 10, 100ULL, 1000ULL,
   1ULL, 10ULL, 100ULL, 1000ULL,
-  1ULL, 10ULL, 100ULL, };
+  1ULL, 10ULL, 100ULL,
+  1000ULL,};
 
 /* -- */
 /* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 75c09ba052..4474f0dd11 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -264,6 +264,7 @@ static decNumber * decTrim(decNumber *, decContext *, Flag, 
Int *);
 static IntdecUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
  Unit *, Int);
 static IntdecUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+static boolmulUInt128ByPowOf10(uLong *, uLong *, uInt);
 
 #if !DECSUBSET
 /* decFinish == decFinalize when no subset arithmetic needed */
@@ -542,6 +543,67 @@ Invalid:
 return 0;
 } /* decNumberIntegralToInt64 */
 
+/* -- */
+/* decNumberIntegralToInt128 -- conversion to int128  */
+/**/
+/*  dn is the decNumber to convert.  dn is assumed to have been   */
+/*rounded to a floating point integer value.  */
+/*  set is the context for reporting errors   */
+/*  returns the converted decNumber via plow and phigh*/
+/**/
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of*/
+/* range for a signed 128 bit integer.*/
+/* -- */
+
+void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
+uint64_t *plow, uint64_t *phigh)
+{
+if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+   (dn->digits + dn->exponent > 39)) {
+goto Invalid;
+} else {
+int d;/* work */
+const Unit *up;   /* .. */
+uint64_t lo = 0, hi = 0;
+up = dn->lsu; /* -> lsu */
+
+   

[PATCH 16/19] target/ppc: Move dquai[q], drint{x,n}[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
dquai:   DFP Quantize Immediate
dquaiq:  DFP Quantize Immediate Quad
drintx:  DFP Round to FP Integer With Inexact
drintxq: DFP Round to FP Integer With Inexact Quad
drintn:  DFP Round to FP Integer Without Inexact
drintnq: DFP Round to FP Integer Without Inexact Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 12 +++
 target/ppc/helper.h | 12 +++
 target/ppc/insn32.decode| 23 +
 target/ppc/translate/dfp-impl.c.inc | 52 +
 target/ppc/translate/dfp-ops.c.inc  | 18 --
 5 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b6634134d9..56d8846308 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -752,8 +752,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b,\
 set_dfp##size(t, &dfp.vt);  \
 }
 
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
+DFP_HELPER_QUAI(DQUAI, 64)
+DFP_HELPER_QUAI(DQUAIQ, 128)
 
 #define DFP_HELPER_QUA(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a,\
@@ -874,8 +874,8 @@ static void RINTX_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
+DFP_HELPER_RINT(DRINTX, RINTX_PPs, 64)
+DFP_HELPER_RINT(DRINTXQ, RINTX_PPs, 128)
 
 static void RINTN_PPs(struct PPC_DFP *dfp)
 {
@@ -883,8 +883,8 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
+DFP_HELPER_RINT(DRINTN, RINTN_PPs, 64)
+DFP_HELPER_RINT(DRINTNQ, RINTN_PPs, 128)
 
 void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 22bf167b15..520cce8378 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -718,16 +718,16 @@ DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
 DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAI, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DQUAIQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
 DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTX, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTXQ, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTN, void, env, fprp, fprp, i32, i32)
+DEF_HELPER_5(DRINTNQ, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_3(dctdp, void, env, fprp, fprp)
 DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
 DEF_HELPER_3(drsp, void, env, fprp, fprp)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index aaeccebca0..f0e17580e0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -77,6 +77,18 @@
 %z22_frap   17:4 !function=times_2
 @Z22_bf_frap.. bf:3 .. 0 dm:6 . .   &Z22_bf_fra 
fra=%z22_frap
 
+&Z23_tb frt frb r:bool rmc rc:bool
+@Z23_tb .. frt:5  r:1 frb:5 rmc:2  rc:1 &Z23_tb
+
+%z23_frtp   22:4 !function=times_2
+%z23_frbp   12:4 !function=times_2
+@Z23_tbp.. 0  r:1 0 rmc:2  rc:1 &Z23_tb 
frt=%z23_frtp frb=%z23_frbp
+
+&Z23_te_tb  te frt frb rmc rc:bool
+@Z23_te_tb  .. frt:5 te:5 frb:5 rmc:2  rc:1 &Z23_te_tb
+
+@Z23_te_tbp .. 0 te:5 0 rmc:2  rc:1 &Z23_te_tb 
frt=%z23_frtp frb=%z23_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -194,6 +206,17 @@ DTSTSFQ 11 ... -- . . 1010100010 -  
@X_bf_a_bp
 DTSTSFI 111011 ... - .. . 1010100011 -  @X_bf_uim
 DTSTSFIQ11 ... - .. . 1010100011 -  @X_bf_uim_bp
 
+### Decimal Floating-Point Quantum Adjustment Instructions
+
+DQUAI   111011 . . . .. 0111 .  @Z23_te_tb
+DQUAIQ  11 . . . .. 0111 .  @Z23_te_tbp
+
+DRINTX  111011 .  . . .. 01100011 . @Z23_tb
+DRINTXQ 11 .  . . .. 01100011 . @Z23_tbp
+
+DRINTN  111011 .  . . .. 11100011 . @Z23_tb
+DRINTNQ 11 .  . . .. 11100011 . @Z23_tbp
+
 ### Decimal Floating-Point Con

[PATCH 10/19] host-utils: Introduce mulu128

2021-08-24 Thread Luis Pires
Signed-off-by: Luis Pires 
---
 include/qemu/host-utils.h | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 8e8cab9a3e..2e3b5ad989 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -588,6 +588,44 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, 
uint64_t *ret)
 #endif
 }
 
+/*
+ * Unsigned 128x64 multiplication.
+ * Returns true if the result got truncated to 128 bits.
+ * Otherwise, returns false and the multiplication result via plow and phigh.
+ */
+static inline bool mulu128(uint64_t *plow, uint64_t *phigh, uint64_t factor)
+{
+#if defined(CONFIG_INT128) && \
+(__has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5)
+bool res;
+__uint128_t r;
+__uint128_t f = ((__uint128_t)*phigh << 64) | *plow;
+res = __builtin_mul_overflow(f, factor, &r);
+
+*plow = r;
+*phigh = r >> 64;
+
+return res;
+#else
+uint64_t dhi = *phigh;
+uint64_t dlo = *plow;
+uint64_t ahi;
+uint64_t blo, bhi;
+
+if (dhi == 0) {
+mulu64(plow, phigh, dlo, factor);
+return false;
+}
+
+mulu64(plow, &ahi, dlo, factor);
+mulu64(&blo, &bhi, dhi, factor);
+
+*phigh = ahi + blo;
+
+return (bhi > 0) || (*phigh < ahi);
+#endif
+}
+
 /**
  * uadd64_carry - addition with carry-in and carry-out
  * @x, @y: addends
-- 
2.25.1




[PATCH 09/19] target/ppc: Implement DCFFIXQQ

2021-08-24 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dcffixqq: DFP Convert From Fixed Quadword Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 11 +++
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  8 
 target/ppc/translate.c  |  7 ++-
 target/ppc/translate/dfp-impl.c.inc | 17 +
 5 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 07341a69f5..01a7ead783 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -970,6 +970,17 @@ static void CFFIX_PPs(struct PPC_DFP *dfp)
 DFP_HELPER_CFFIX(dcffix, 64)
 DFP_HELPER_CFFIX(dcffixq, 128)
 
+void helper_DCFFIXQQ(CPUPPCState *env, ppc_fprp_t *t, ppc_avr_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, NULL, NULL, env);
+decNumberFromInt128(&dfp.t, (uint64_t)b->VsrD(1), (int64_t)b->VsrD(0));
+dfp_finalize_decimal128(&dfp);
+CFFIX_PPs(&dfp);
+
+set_dfp128(t, &dfp.vt);
+}
+
 #define DFP_HELPER_CTFIX(op, size)\
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)  \
 { \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 4076aa281e..fff7bd46ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -734,6 +734,7 @@ DEF_HELPER_3(drsp, void, env, fprp, fprp)
 DEF_HELPER_3(drdpq, void, env, fprp, fprp)
 DEF_HELPER_3(dcffix, void, env, fprp, fprp)
 DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b817..92ea2d0739 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -43,6 +43,10 @@
 &X_bfl  bf l:bool ra rb
 @X_bfl  .. bf:3 - l:1 ra:5 rb:5 ..- &X_bfl
 
+&X_frtp_vrb frtp vrb
+%x_frtp 22:4 !function=times_2
+@X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -121,6 +125,10 @@ SETBCR  01 . . - 011010 -   
@X_bi
 SETNBC  01 . . - 011100 -   @X_bi
 SETNBCR 01 . . - 00 -   @X_bi
 
+### Decimal Floating-Point Conversion Instructions
+
+DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+
 ## Vector Bit Manipulation Instruction
 
 VCFUGED 000100 . . . 10101001101@VX
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 5489b4b6e0..c3739f7370 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7422,7 +7422,12 @@ static inline void set_avr64(int regno, TCGv_i64 src, 
bool high)
 /*
  * Helpers for decodetree used by !function for decoding arguments.
  */
-static int times_4(DisasContext *ctx, int x)
+static inline int times_2(DisasContext *ctx, int x)
+{
+return x * 2;
+}
+
+static inline int times_4(DisasContext *ctx, int x)
 {
 return x * 4;
 }
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index 6c556dc2e1..d5b66567a6 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -230,3 +230,20 @@ GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 #undef GEN_DFP_T_A_B_I32_Rc
 #undef GEN_DFP_T_B_Rc
 #undef GEN_DFP_T_FPR_I32_Rc
+
+static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_fprp_ptr(a->frtp);
+rb = gen_avr_ptr(a->vrb);
+gen_helper_DCFFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH 14/19] target/ppc: Move d{add, sub, mul, div, iex}[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
dadd:  DFP Add
daddq: DFP Add Quad
dsub:  DFP Subtract
dsubq: DFP Subtract Quad
dmul:  DFP Multiply
dmulq: DFP Multiply Quad
ddiv:  DFP Divide
ddivq: DFP Divide Quad
diex:  DFP Insert Biased Exponent
diexq: DFP Insert Biased Exponent Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 20 +-
 target/ppc/helper.h | 20 +-
 target/ppc/insn32.decode| 31 +++-
 target/ppc/translate/dfp-impl.c.inc | 57 ++---
 target/ppc/translate/dfp-ops.c.inc  | 19 --
 5 files changed, 76 insertions(+), 71 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index b4945fe48f..14080cecc8 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -446,8 +446,8 @@ static void ADD_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_add(dfp);
 }
 
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
+DFP_HELPER_TAB(DADD, decNumberAdd, ADD_PPs, 64)
+DFP_HELPER_TAB(DADDQ, decNumberAdd, ADD_PPs, 128)
 
 static void SUB_PPs(struct PPC_DFP *dfp)
 {
@@ -459,8 +459,8 @@ static void SUB_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXISI_subtract(dfp);
 }
 
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
+DFP_HELPER_TAB(DSUB, decNumberSubtract, SUB_PPs, 64)
+DFP_HELPER_TAB(DSUBQ, decNumberSubtract, SUB_PPs, 128)
 
 static void MUL_PPs(struct PPC_DFP *dfp)
 {
@@ -472,8 +472,8 @@ static void MUL_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIMZ(dfp);
 }
 
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
+DFP_HELPER_TAB(DMUL, decNumberMultiply, MUL_PPs, 64)
+DFP_HELPER_TAB(DMULQ, decNumberMultiply, MUL_PPs, 128)
 
 static void DIV_PPs(struct PPC_DFP *dfp)
 {
@@ -487,8 +487,8 @@ static void DIV_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXIDI(dfp);
 }
 
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
+DFP_HELPER_TAB(DDIV, decNumberDivide, DIV_PPs, 64)
+DFP_HELPER_TAB(DDIVQ, decNumberDivide, DIV_PPs, 128)
 
 #define DFP_HELPER_BF_AB(op, dnop, postprocs, size)
\
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b)   
\
@@ -1299,8 +1299,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *a,  \
 set_dfp##size(t, &dfp.vt);\
 }
 
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
+DFP_HELPER_IEX(DIEX, 64)
+DFP_HELPER_IEX(DIEXQ, 128)
 
 static void dfp_clear_lmd_from_g5msb(uint64_t *t)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 30e9247a5a..1f00e47b82 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -696,14 +696,14 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
 #define dh_alias_fprp ptr
 #define dh_ctype_fprp ppc_fprp_t *
 
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADD, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DADDQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUB, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DSUBQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
 DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
@@ -744,8 +744,8 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
 DEF_HELPER_3(dxex, void, env, fprp, fprp)
 DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEX, void, env, fprp, fprp, fprp)
+DEF_HELPER_4(DIEXQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 38f8525d54..c4a8cc7ec5 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -37,6 +37,16 @@
 &X  rt ra rb
 @X  .. rt:5 ra:5 rb:5 .. .  &X
 
+&X_rc   rt ra rb rc:bool
+@X_rc   .. rt:5 ra:5 rb:5 .. rc:1   &X_rc
+
+%x_frtp 22:4 !function=times_2
+%x_frap 17:4 !function=times_2
+%x_frbp 12:4 !function=tim

[PATCH 15/19] target/ppc: Move dcmp{u, o}[q], dts{tex, tsf, tsfi}[q] to decodetree

2021-08-24 Thread Luis Pires
Move the following instructions to decodetree:
dcmpu:DFP Compare Unordered
dcmpuq:   DFP Compare Unordered Quad
dcmpo:DFP Compare Ordered
dcmpoq:   DFP Compare Ordered Quad
dtstex:   DFP Test Exponent
dtstexq:  DFP Test Exponent Quad
dtstsf:   DFP Test Significance
dtstsfq:  DFP Test Significance Quad
dtstsfi:  DFP Test Significance Immediate
dtstsfiq: DFP Test Significance Immediate Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 20 
 target/ppc/helper.h | 20 
 target/ppc/insn32.decode| 29 +++
 target/ppc/translate/dfp-impl.c.inc | 76 +
 target/ppc/translate/dfp-ops.c.inc  | 31 
 5 files changed, 83 insertions(+), 93 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 14080cecc8..b6634134d9 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -508,8 +508,8 @@ static void CMPU_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXSNAN(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
+DFP_HELPER_BF_AB(DCMPU, decNumberCompare, CMPU_PPs, 64)
+DFP_HELPER_BF_AB(DCMPUQ, decNumberCompare, CMPU_PPs, 128)
 
 static void CMPO_PPs(struct PPC_DFP *dfp)
 {
@@ -519,8 +519,8 @@ static void CMPO_PPs(struct PPC_DFP *dfp)
 dfp_check_for_VXVC(dfp);
 }
 
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
+DFP_HELPER_BF_AB(DCMPO, decNumberCompare, CMPO_PPs, 64)
+DFP_HELPER_BF_AB(DCMPOQ, decNumberCompare, CMPO_PPs, 128)
 
 #define DFP_HELPER_TSTDC(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm)  \
@@ -634,8 +634,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
+DFP_HELPER_TSTEX(DTSTEX, 64)
+DFP_HELPER_TSTEX(DTSTEXQ, 128)
 
 #define DFP_HELPER_TSTSF(op, size)   \
 uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
@@ -671,8 +671,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, 
ppc_fprp_t *b) \
 return dfp.crbf; \
 }
 
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
+DFP_HELPER_TSTSF(DTSTSF, 64)
+DFP_HELPER_TSTSF(DTSTSFQ, 128)
 
 #define DFP_HELPER_TSTSFI(op, size) \
 uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b)   \
@@ -706,8 +706,8 @@ uint32_t helper_##op(CPUPPCState *env, uint32_t a, 
ppc_fprp_t *b)   \
 return dfp.crbf;\
 }
 
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
+DFP_HELPER_TSTSFI(DTSTSFI, 64)
+DFP_HELPER_TSTSFI(DTSTSFIQ, 128)
 
 static void QUA_PPs(struct PPC_DFP *dfp)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 1f00e47b82..22bf167b15 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -704,20 +704,20 @@ DEF_HELPER_4(DMUL, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DMULQ, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIV, void, env, fprp, fprp, fprp)
 DEF_HELPER_4(DDIVQ, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPO, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPOQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPU, i32, env, fprp, fprp)
+DEF_HELPER_3(DCMPUQ, i32, env, fprp, fprp)
 DEF_HELPER_3(DTSTDC, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDCQ, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDG, i32, env, fprp, i32)
 DEF_HELPER_3(DTSTDGQ, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTEX, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTEXQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSF, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFQ, i32, env, fprp, fprp)
+DEF_HELPER_3(DTSTSFI, i32, env, i32, fprp)
+DEF_HELPER_3(DTSTSFIQ, i32, env, i32, fprp)
 DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
 DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index c4a8cc7ec5..aaeccebca0 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -50,6 +50,18 @@
 &X_bi   rt bi
 @X_bi   .. rt:5 bi:5 - .. - &X_bi
 
+&X_bf   bf ra rb
+@X_bf   .. bf:3 .. ra:5 rb:5 .. .

[PATCH 07/19] target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

2021-08-24 Thread Luis Pires
From: Bruno Larsen 

Move REQUIRE_ALTIVEC to translate.c and rename it to REQUIRE_VECTOR.

Signed-off-by: Bruno Larsen 
Signed-off-by: Matheus Ferst 
Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
---
 target/ppc/translate.c |  8 
 target/ppc/translate/vector-impl.c.inc | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 171b216e17..4749ecdaa9 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7453,6 +7453,14 @@ static int times_4(DisasContext *ctx, int x)
 # define REQUIRE_64BIT(CTX)  REQUIRE_INSNS_FLAGS(CTX, 64B)
 #endif
 
+#define REQUIRE_VECTOR(CTX) \
+do {\
+if (unlikely(!(CTX)->altivec_enabled)) {\
+gen_exception((CTX), POWERPC_EXCP_VPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
diff --git a/target/ppc/translate/vector-impl.c.inc 
b/target/ppc/translate/vector-impl.c.inc
index 117ce9b137..197e903337 100644
--- a/target/ppc/translate/vector-impl.c.inc
+++ b/target/ppc/translate/vector-impl.c.inc
@@ -17,20 +17,12 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#define REQUIRE_ALTIVEC(CTX) \
-do {\
-if (unlikely(!(CTX)->altivec_enabled)) {\
-gen_exception((CTX), POWERPC_EXCP_VPU); \
-return true;\
-}   \
-} while (0)
-
 static bool trans_VCFUGED(DisasContext *ctx, arg_VX *a)
 {
 TCGv_i64 tgt, src, mask;
 
 REQUIRE_INSNS_FLAGS2(ctx, ISA310);
-REQUIRE_ALTIVEC(ctx);
+REQUIRE_VECTOR(ctx);
 
 tgt = tcg_temp_new_i64();
 src = tcg_temp_new_i64();
-- 
2.25.1




[PATCH 08/19] target/ppc: Introduce REQUIRE_FPU

2021-08-24 Thread Luis Pires
From: Fernando Valle 

Signed-off-by: Fernando Valle 
Signed-off-by: Luis Pires 
---
 target/ppc/translate.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4749ecdaa9..5489b4b6e0 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7461,6 +7461,14 @@ static int times_4(DisasContext *ctx, int x)
 }   \
 } while (0)
 
+#define REQUIRE_FPU(ctx)\
+do {\
+if (unlikely(!(ctx)->fpu_enabled)) {\
+gen_exception((ctx), POWERPC_EXCP_FPU); \
+return true;\
+}   \
+} while (0)
+
 /*
  * Helpers for implementing sets of trans_* functions.
  * Defer the implementation of NAME to FUNC, with optional extra arguments.
-- 
2.25.1




[PATCH 12/19] target/ppc: Implement DCTFIXQQ

2021-08-24 Thread Luis Pires
Implement the following PowerISA v3.1 instruction:
dctfixqq: DFP Convert To Fixed Quadword Quad

Signed-off-by: Luis Pires 
---
 target/ppc/dfp_helper.c | 53 +
 target/ppc/helper.h |  1 +
 target/ppc/insn32.decode|  5 +++
 target/ppc/translate/dfp-impl.c.inc | 17 +
 4 files changed, 76 insertions(+)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 01a7ead783..ef1c370c3c 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -51,6 +51,12 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
 dfp[1].VsrD(0) = src->VsrD(1);
 }
 
+static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
+{
+dst->VsrD(0) = src->VsrD(0);
+dst->VsrD(1) = src->VsrD(1);
+}
+
 struct PPC_DFP {
 CPUPPCState *env;
 ppc_vsr_t vt, va, vb;
@@ -1019,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b)  \
 DFP_HELPER_CTFIX(dctfix, 64)
 DFP_HELPER_CTFIX(dctfixq, 128)
 
+void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
+{
+struct PPC_DFP dfp;
+dfp_prepare_decimal128(&dfp, 0, b, env);
+
+if (unlikely(decNumberIsSpecial(&dfp.b))) {
+uint64_t invalid_flags = FP_VX | FP_VXCVI;
+if (decNumberIsInfinite(&dfp.b)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+} else { /* NaN */
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+if (decNumberIsSNaN(&dfp.b)) {
+invalid_flags |= FP_VXSNAN;
+}
+}
+dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);
+} else if (unlikely(decNumberIsZero(&dfp.b))) {
+dfp.vt.VsrD(0) = 0;
+dfp.vt.VsrD(1) = 0;
+} else {
+decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);
+decNumberIntegralToInt128(&dfp.b, &dfp.context,
+&dfp.vt.VsrD(1), &dfp.vt.VsrD(0));
+if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {
+if (decNumberIsNegative(&dfp.b)) {
+dfp.vt.VsrD(0) = INT64_MIN;
+dfp.vt.VsrD(1) = 0;
+} else {
+dfp.vt.VsrD(0) = INT64_MAX;
+dfp.vt.VsrD(1) = UINT64_MAX;
+}
+dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);
+} else {
+dfp_check_for_XX(&dfp);
+}
+}
+
+set_dfp128_to_avr(t, &dfp.vt);
+}
+
 static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
 unsigned n)
 {
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fff7bd46ad..20041ce977 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -737,6 +737,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
 DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
 DEF_HELPER_3(dctfix, void, env, fprp, fprp)
 DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
+DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
 DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
 DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
 DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 92ea2d0739..6d97f9ae3b 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -47,6 +47,10 @@
 %x_frtp 22:4 !function=times_2
 @X_frtp_vrb .. 0 . vrb:5 .. .   &X_frtp_vrb 
frtp=%x_frtp
 
+&X_vrt_frbp vrt frbp
+%x_frbp 12:4 !function=times_2
+@X_vrt_frbp .. vrt:5 . 0 .. .   &X_vrt_frbp 
frbp=%x_frbp
+
 ### Fixed-Point Load Instructions
 
 LBZ 100010 . .  @D
@@ -128,6 +132,7 @@ SETNBCR 01 . . - 00 -   
@X_bi
 ### Decimal Floating-Point Conversion Instructions
 
 DCFFIXQQ11 . 0 . 100010 -   @X_frtp_vrb
+DCTFIXQQ11 . 1 . 100010 -   @X_vrt_frbp
 
 ## Vector Bit Manipulation Instruction
 
diff --git a/target/ppc/translate/dfp-impl.c.inc 
b/target/ppc/translate/dfp-impl.c.inc
index d5b66567a6..e149777481 100644
--- a/target/ppc/translate/dfp-impl.c.inc
+++ b/target/ppc/translate/dfp-impl.c.inc
@@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ 
*a)
 
 return true;
 }
+
+static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
+{
+TCGv_ptr rt, rb;
+
+REQUIRE_INSNS_FLAGS2(ctx, DFP);
+REQUIRE_FPU(ctx);
+REQUIRE_VECTOR(ctx);
+
+rt = gen_avr_ptr(a->vrt);
+rb = gen_fprp_ptr(a->frbp);
+gen_helper_DCTFIXQQ(cpu_env, rt, rb);
+tcg_temp_free_ptr(rt);
+tcg_temp_free_ptr(rb);
+
+return true;
+}
-- 
2.25.1




[PATCH 03/19] host-utils: move checks out of divu128/divs128

2021-08-24 Thread Luis Pires
In preparation for changing the divu128/divs128 implementations
to allow for quotients larger than 64 bits, move the div-by-zero
and overflow checks to the callers.

Signed-off-by: Luis Pires 
---
 include/hw/clock.h|  5 +++--
 include/qemu/host-utils.h | 36 +---
 target/ppc/int_helper.c   | 14 +-
 util/host-utils.c | 39 +++
 4 files changed, 44 insertions(+), 50 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index a7187eab95..5a40a076aa 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -320,8 +320,9 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 return 0;
 }
 /*
- * Ignore divu128() return value as we've caught div-by-zero and don't
- * need different behaviour for overflow.
+ * BUG: when CONFIG_INT128 is not defined, the current implementation of
+ * divu128 does not return a valid truncated quotient, so the result will
+ * be wrong.
  */
 divu128(&lo, &hi, clk->period);
 return lo;
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 5fec44a9c4..97a3fbb06a 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,36 +52,26 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
-{
-if (divisor == 0) {
-return 1;
-} else {
-__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
-__uint128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result > UINT64_MAX;
-}
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+__uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
+__uint128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 
-static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
 {
-if (divisor == 0) {
-return 1;
-} else {
-__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
-__int128_t result = dividend / divisor;
-*plow = result;
-*phigh = dividend % divisor;
-return result != *plow;
-}
+__int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
+__int128_t result = dividend / divisor;
+*plow = result;
+*phigh = dividend % divisor;
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index de56056429..227e2ce0ec 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -104,10 +104,11 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 uint64_t rt = 0;
 int overflow = 0;
 
-overflow = divu128(&rt, &ra, rb);
-
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || ra >= rb)) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divu128(&rt, &ra, rb);
 }
 
 if (oe) {
@@ -122,10 +123,13 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 int64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
-int overflow = divs128(&rt, &ra, rb);
+int overflow = 0;
 
-if (unlikely(overflow)) {
+if (unlikely(rb == 0 || (uint64_t)abs64(ra) >= (uint64_t)abs64(rb))) {
+overflow = 1;
 rt = 0; /* Undefined */
+} else {
+divs128(&rt, &ra, rb);
 }
 
 if (oe) {
diff --git a/util/host-utils.c b/util/host-utils.c
index a789a11b46..ff75fdf1e1 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -86,10 +86,14 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, 
int64_t b)
 *phigh = rh;
 }
 
-/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
-/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
-/* remainder via phigh. */
-int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+/*
+ * Unsigned 128-by-64 division. Returns quotient via plow and
+ * remainder via phigh.
+ * The result must fit in 64 bits (plow) - otherwise, the result
+ * is undefined.
+ * This function will cause a division by zero if passed a zero divisor.
+ */
+void divu128(uint64_t *plow, uint6

[PATCH 05/19] host-utils: add unit tests for divu128/divs128

2021-08-24 Thread Luis Pires
Signed-off-by: Luis Pires 
---
 tests/unit/meson.build   |   1 +
 tests/unit/test-div128.c | 185 +++
 2 files changed, 186 insertions(+)
 create mode 100644 tests/unit/test-div128.c

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 5736d285b2..96e3b23162 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -23,6 +23,7 @@ tests = {
   # all code tested by test-x86-cpuid is inside topology.h
   'test-x86-cpuid': [],
   'test-cutils': [],
+  'test-div128': [],
   'test-shift128': [],
   'test-mul64': [],
   # all code tested by test-int128 is inside int128.h
diff --git a/tests/unit/test-div128.c b/tests/unit/test-div128.c
new file mode 100644
index 00..5dc39fe6d1
--- /dev/null
+++ b/tests/unit/test-div128.c
@@ -0,0 +1,185 @@
+/*
+ * Test 128-bit division functions
+ *
+ * Copyright (c) 2021 Instituto de Pesquisas Eldorado (eldorado.org.br)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+
+typedef struct {
+uint64_t high;
+uint64_t low;
+uint64_t rhigh;
+uint64_t rlow;
+uint64_t divisor;
+uint64_t remainder;
+} test_data_unsigned;
+
+typedef struct {
+int64_t high;
+uint64_t low;
+int64_t rhigh;
+uint64_t rlow;
+int64_t divisor;
+int64_t remainder;
+} test_data_signed;
+
+static const test_data_unsigned test_table_unsigned[] = {
+/* Dividend fits in 64 bits */
+{ 0xULL, 0xULL,
+  0xULL, 0xULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0001ULL,
+  0xULL, 0x0001ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0x0003ULL,
+  0xULL, 0x0001ULL,
+  0x0002ULL, 0x0001ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x8000ULL,
+  0x0001ULL, 0xULL},
+{ 0xULL, 0xa000ULL,
+  0xULL, 0x0002ULL,
+  0x4000ULL, 0x2000ULL},
+{ 0xULL, 0x8000ULL,
+  0xULL, 0x0001ULL,
+  0x8000ULL, 0xULL},
+
+/* Dividend > 64 bits, with MSB 0 */
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0xULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0001ULL, 0x000dULL,
+  0x123456789abcdefeULL, 0x03456789abcdf03bULL},
+{ 0x123456789abcdefeULL, 0xefedcba987654321ULL,
+  0x0123456789abcdefULL, 0xeefedcba98765432ULL,
+  0x0010ULL, 0x0001ULL},
+
+/* Dividend > 64 bits, with MSB 1 */
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0001ULL, 0xULL,
+  0xfeeddccbbaa99887ULL, 0x766554433221100fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x0feeddccbbaa9988ULL, 0x7766554433221100ULL,
+  0x0010ULL, 0x000fULL},
+{ 0xfeeddccbbaa99887ULL, 0x766554433221100fULL,
+  0x000eULL, 0x00f0f0f0f0f0f35aULL,
+  0x123456789abcdefeULL, 0x0f8922bc55ef90c3ULL},
+
+/* Dividend > 64 bits, divisor almost as big */
+{ 0x0001ULL, 0x23456789abcdef01ULL,
+  0xULL, 0x000fULL,
+  0x123456789abcdefeULL, 0x123456789abcde1fULL},
+};
+
+static const test_data_signed test_table_signed[] = {
+/* Positive dividend, positive/negative divisors */
+{ 0xLL, 0x00bc614eULL,
+  0xLL, 0x00bc614eULL,
+  0x0001LL, 0xLL},
+{ 0xLL, 0x00bc614eULL,
+  0xLL, 0xff439eb2ULL,
+  0xLL, 0x000

[PATCH 06/19] libdecnumber: introduce decNumberFrom[U]Int128

2021-08-24 Thread Luis Pires
This will be used to implement PowerPC's dcffixqq.

Signed-off-by: Luis Pires 
---
 include/libdecnumber/decNumber.h |  2 ++
 libdecnumber/decNumber.c | 36 
 2 files changed, 38 insertions(+)

diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed07..0cf69c7db2 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -116,6 +116,8 @@
   decNumber * decNumberFromUInt32(decNumber *, uint32_t);
   decNumber *decNumberFromInt64(decNumber *, int64_t);
   decNumber *decNumberFromUInt64(decNumber *, uint64_t);
+  decNumber *decNumberFromInt128(decNumber *, uint64_t, int64_t);
+  decNumber *decNumberFromUInt128(decNumber *, uint64_t, uint64_t);
   decNumber * decNumberFromString(decNumber *, const char *, decContext *);
   char * decNumberToString(const decNumber *, char *);
   char * decNumberToEngString(const decNumber *, char *);
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 1ffe458ad8..75c09ba052 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -167,6 +167,7 @@
 /* -- */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "libdecnumber/dconfig.h"
 #include "libdecnumber/decNumber.h"
 #include "libdecnumber/decNumberLocal.h"
@@ -462,6 +463,41 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
 return dn;
 } /* decNumberFromUInt64 */
 
+decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
+{
+uint64_t unsig_hi = hi;
+if (hi < 0) {
+if (lo == 0) {
+unsig_hi = -unsig_hi;
+} else {
+unsig_hi = ~unsig_hi;
+lo = -lo;
+}
+}
+
+decNumberFromUInt128(dn, lo, unsig_hi);
+if (hi < 0) {
+dn->bits = DECNEG;/* sign needed */
+}
+return dn;
+} /* decNumberFromInt128 */
+
+decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
+{
+uint64_t rem;
+Unit *up; /* work pointer */
+decNumberZero(dn);/* clean */
+if (lo == 0 && hi == 0) {
+return dn;/* [or decGetDigits bad call] */
+}
+for (up = dn->lsu; hi > 0 || lo > 0; up++) {
+divu128(&lo, &hi, &rem, DECDPUNMAX + 1);
+*up = (Unit)rem;
+}
+dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
+return dn;
+} /* decNumberFromUInt128 */
+
 /* -- */
 /* to-int64 -- conversion to int64*/
 /**/
-- 
2.25.1




[PATCH 02/19] host-utils: move abs64() to host-utils

2021-08-24 Thread Luis Pires
Move abs64 to host-utils so it can be reused elsewhere.
Also made it inline.

Signed-off-by: Luis Pires 
---
 hw/i386/kvm/i8254.c   | 5 -
 include/qemu/host-utils.h | 8 
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index fa68669e8a..761034743b 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -59,11 +59,6 @@ struct KVMPITClass {
 DeviceRealize parent_realize;
 };
 
-static int64_t abs64(int64_t v)
-{
-return v < 0 ? -v : v;
-}
-
 static void kvm_pit_update_clock_offset(KVMPITState *s)
 {
 int64_t offset, clock_offset;
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 711b221704..5fec44a9c4 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -357,6 +357,14 @@ static inline uint64_t revbit64(uint64_t x)
 #endif
 }
 
+/**
+ * Return the absolute value of a 64-bit integer
+ */
+static inline int64_t abs64(int64_t v)
+{
+return v < 0 ? -v : v;
+}
+
 /**
  * sadd32_overflow - addition with overflow indication
  * @x, @y: addends
-- 
2.25.1




[PATCH 04/19] host-utils: add 128-bit quotient support to divu128/divs128

2021-08-24 Thread Luis Pires
These will be used to implement new decimal floating point
instructions from Power ISA 3.1.

A new argument, prem, was added to divu128/divs128 to receive the
remainder, freeing up phigh to receive the high 64 bits of the
quotient.

For scenarios supported by the previous implementation
(<= 64-bit quotient) with large (> 64-bit) dividends, testing showed
that:
- when dividend >> divisor, the performance of the new implementation
is equivalent to the old one.
- as the dividend and the divisor get closer (e.g. 65-bit dividend and
64-bit divisor), the performance is significantly improved, due to the
smaller number of shift-subtract iterations.

Signed-off-by: Luis Pires 
---
 include/hw/clock.h|   8 +--
 include/qemu/host-utils.h |  20 --
 target/ppc/int_helper.c   |  13 ++--
 util/host-utils.c | 128 +++---
 4 files changed, 113 insertions(+), 56 deletions(-)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index 5a40a076aa..2f162f7a6f 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -319,12 +319,8 @@ static inline uint64_t clock_ns_to_ticks(const Clock *clk, 
uint64_t ns)
 if (clk->period == 0) {
 return 0;
 }
-/*
- * BUG: when CONFIG_INT128 is not defined, the current implementation of
- * divu128 does not return a valid truncated quotient, so the result will
- * be wrong.
- */
-divu128(&lo, &hi, clk->period);
+
+divu128(&lo, &hi, NULL, clk->period);
 return lo;
 }
 
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 97a3fbb06a..8e8cab9a3e 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -52,26 +52,34 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 return (__int128_t)a * b / c;
 }
 
-static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t *prem,
+   uint64_t divisor)
 {
 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
 __uint128_t result = dividend / divisor;
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+if (prem) {
+*prem = dividend % divisor;
+}
 }
 
-static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+static inline void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem,
+   int64_t divisor)
 {
 __int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
 __int128_t result = dividend / divisor;
 *plow = result;
-*phigh = dividend % divisor;
+*phigh = result >> 64;
+if (prem) {
+*prem = dividend % divisor;
+}
 }
 #else
 void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
 void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
-void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
-void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
+void divu128(uint64_t *plow, uint64_t *phigh, uint64_t *prem, uint64_t 
divisor);
+void divs128(uint64_t *plow, int64_t *phigh, int64_t *prem, int64_t divisor);
 
 static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 227e2ce0ec..53b234d808 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -108,7 +108,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 overflow = 1;
 rt = 0; /* Undefined */
 } else {
-divu128(&rt, &ra, rb);
+divu128(&rt, &ra, NULL, rb);
 }
 
 if (oe) {
@@ -120,7 +120,7 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
 
 uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t 
oe)
 {
-int64_t rt = 0;
+uint64_t rt = 0;
 int64_t ra = (int64_t)rau;
 int64_t rb = (int64_t)rbu;
 int overflow = 0;
@@ -129,7 +129,7 @@ uint64_t helper_divde(CPUPPCState *env, uint64_t rau, 
uint64_t rbu, uint32_t oe)
 overflow = 1;
 rt = 0; /* Undefined */
 } else {
-divs128(&rt, &ra, rb);
+divs128(&rt, &ra, NULL, rb);
 }
 
 if (oe) {
@@ -2524,6 +2524,7 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 int cr;
 uint64_t lo_value;
 uint64_t hi_value;
+uint64_t rem;
 ppc_avr_t ret = { .u64 = { 0, 0 } };
 
 if (b->VsrSD(0) < 0) {
@@ -2559,10 +2560,10 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
  * In that case, we leave r unchanged.
  */
 } else {
-divu128(&lo_value, &hi_value, 1000ULL);
+divu128(&lo_value, &hi_value, &rem, 1000ULL);
 
-for (i = 1; i < 16; hi_value /= 10, i++) {
-bcd_put_

[PATCH 01/19] host-utils: Fix overflow detection in divu128()

2021-08-24 Thread Luis Pires
The previous code didn't detect overflows if the high 64-bit
of the dividend were equal to the 64-bit divisor. In that case,
64 bits wouldn't be enough to hold the quotient.

Signed-off-by: Luis Pires 
---
 util/host-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/host-utils.c b/util/host-utils.c
index 7b9322071d..a789a11b46 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -102,7 +102,7 @@ int divu128(uint64_t *plow, uint64_t *phigh, uint64_t 
divisor)
 *plow  = dlo / divisor;
 *phigh = dlo % divisor;
 return 0;
-} else if (dhi > divisor) {
+} else if (dhi >= divisor) {
 return 1;
 } else {
 
-- 
2.25.1




[PATCH 00/19] target/ppc: DFP instructions using decodetree

2021-08-24 Thread Luis Pires
This series moves all existing DFP instructions to decodetree and
implements the 2 new instructions (dcffixqq and dctfixqq) from
Power ISA 3.1.

In order to implement dcffixqq, divu128/divs128 were modified to
support 128-bit quotients (previously, they were limited to 64-bit
quotients), along with adjustments being made to its existing callers.
libdecnumber was also expanded to allow creating decimal numbers from
128-bit integers.

Similarly, for dctfixqq, mulu128 (host-utils) and decNumberIntegralToInt128
(libdecnumber) were introduced to support 128-bit integers.

The remaining patches of this series move all of the already existing
DFP instructions to decodetree, and end up removing dfp-ops.c.inc, which
is no longer needed.

NOTE 1: The previous, non-decodetree code, was updating ctx->nip for all the
DFP instructions. I've removed that, but it would be great if someone could
confirm that updating nip really wasn't necessary.

NOTE 2: Some arithmetic function support for 128-bit integers was added,
for now, still using 64-bit pairs. In the near future, I think we should
modify all of them to use Int128 (and introduce UInt128). But that
should be done in another patch series.

Based-on: 20210823150235.35759-1-luis.pi...@eldorado.org.br
(target/ppc: fix setting of CR flags in bcdcfsq)

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>


Bruno Larsen (1):
  target/ppc: Move REQUIRE_ALTIVEC/VECTOR to translate.c

Fernando Valle (1):
  target/ppc: Introduce REQUIRE_FPU

Luis Pires (17):
  host-utils: Fix overflow detection in divu128()
  host-utils: move abs64() to host-utils
  host-utils: move checks out of divu128/divs128
  host-utils: add 128-bit quotient support to divu128/divs128
  host-utils: add unit tests for divu128/divs128
  libdecnumber: introduce decNumberFrom[U]Int128
  target/ppc: Implement DCFFIXQQ
  host-utils: Introduce mulu128
  libdecnumber: Introduce decNumberIntegralToInt128
  target/ppc: Implement DCTFIXQQ
  target/ppc: Move dtstdc[q]/dtstdg[q] to decodetree
  target/ppc: Move d{add,sub,mul,div,iex}[q] to decodetree
  target/ppc: Move dcmp{u,o}[q],dts{tex,tsf,tsfi}[q] to decodetree
  target/ppc: Move dquai[q], drint{x,n}[q] to decodetree
  target/ppc: Move dqua[q], drrnd[q] to decodetree
  target/ppc: Move dct{dp,qpq},dr{sp,dpq},dc{f,t}fix[q],dxex[q] to
decodetree
  target/ppc: Move ddedpd[q],denbcd[q],dscli[q],dscri[q] to decodetree

 hw/i386/kvm/i8254.c|   5 -
 include/hw/clock.h |   7 +-
 include/libdecnumber/decNumber.h   |   4 +
 include/libdecnumber/decNumberLocal.h  |   2 +-
 include/qemu/host-utils.h  |  86 +++--
 libdecnumber/decContext.c  |   7 +-
 libdecnumber/decNumber.c   | 130 
 target/ppc/dfp_helper.c| 168 +++---
 target/ppc/helper.h| 106 ---
 target/ppc/insn32.decode   | 171 ++
 target/ppc/int_helper.c|  23 +-
 target/ppc/translate.c |  25 +-
 target/ppc/translate/dfp-impl.c.inc| 419 -
 target/ppc/translate/dfp-ops.c.inc | 165 --
 target/ppc/translate/vector-impl.c.inc |  10 +-
 tests/unit/meson.build |   1 +
 tests/unit/test-div128.c   | 185 +++
 util/host-utils.c  | 137 +---
 18 files changed, 1072 insertions(+), 579 deletions(-)
 delete mode 100644 target/ppc/translate/dfp-ops.c.inc
 create mode 100644 tests/unit/test-div128.c

-- 
2.25.1




[PATCH] target/ppc: fix setting of CR flags in bcdcfsq

2021-08-23 Thread Luis Pires
According to the ISA, CR should be set based on the source value, and
not on the packed decimal result.
The way this was implemented would cause GT, LT and EQ to be set
incorrectly when the source value was too large and the 31 least
significant digits of the packed decimal result ended up being all zero.
This would happen for source values of +/-10^31, +/-10^32, etc.

The new implementation fixes this and also skips the result calculation
altogether in case of src overflow.

Signed-off-by: Luis Pires 
---
 target/ppc/int_helper.c | 61 -
 1 file changed, 48 insertions(+), 13 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index efa833ef64..de56056429 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -2498,10 +2498,26 @@ uint32_t helper_bcdctz(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 return cr;
 }
 
+/**
+ * Compare 2 128-bit unsigned integers, passed in as unsigned 64-bit pairs
+ *
+ * Returns:
+ * > 0 if ahi|alo > bhi|blo,
+ * 0 if ahi|alo == bhi|blo,
+ * < 0 if ahi|alo < bhi|blo
+ */
+static inline int ucmp128(uint64_t alo, uint64_t ahi,
+  uint64_t blo, uint64_t bhi)
+{
+return (ahi == bhi) ?
+(alo > blo ? 1 : (alo == blo ? 0 : -1)) :
+(ahi > bhi ? 1 : -1);
+}
+
 uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
 {
 int i;
-int cr = 0;
+int cr;
 uint64_t lo_value;
 uint64_t hi_value;
 ppc_avr_t ret = { .u64 = { 0, 0 } };
@@ -2510,28 +2526,47 @@ uint32_t helper_bcdcfsq(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 lo_value = -b->VsrSD(1);
 hi_value = ~b->VsrD(0) + !lo_value;
 bcd_put_digit(&ret, 0xD, 0);
+
+cr = CRF_LT;
 } else {
 lo_value = b->VsrD(1);
 hi_value = b->VsrD(0);
 bcd_put_digit(&ret, bcd_preferred_sgn(0, ps), 0);
-}
 
-if (divu128(&lo_value, &hi_value, 1000ULL) ||
-lo_value > ULL) {
-cr = CRF_SO;
+if (hi_value == 0 && lo_value == 0) {
+cr = CRF_EQ;
+} else {
+cr = CRF_GT;
+}
 }
 
-for (i = 1; i < 16; hi_value /= 10, i++) {
-bcd_put_digit(&ret, hi_value % 10, i);
-}
+/*
+ * Check src limits: abs(src) <= 10^31 - 1
+ *
+ * 10^31 - 1 = 0x007e37be2022 c0914b267fff
+ */
+if (ucmp128(lo_value, hi_value,
+0xc0914b267fffULL, 0x7e37be2022ULL) > 0) {
+cr |= CRF_SO;
 
-for (; i < 32; lo_value /= 10, i++) {
-bcd_put_digit(&ret, lo_value % 10, i);
-}
+/*
+ * According to the ISA, if src wouldn't fit in the destination
+ * register, the result is undefined.
+ * In that case, we leave r unchanged.
+ */
+} else {
+divu128(&lo_value, &hi_value, 1000ULL);
 
-cr |= bcd_cmp_zero(&ret);
+for (i = 1; i < 16; hi_value /= 10, i++) {
+bcd_put_digit(&ret, hi_value % 10, i);
+}
 
-*r = ret;
+for (; i < 32; lo_value /= 10, i++) {
+bcd_put_digit(&ret, lo_value % 10, i);
+}
+
+*r = ret;
+}
 
 return cr;
 }
-- 
2.25.1




  1   2   >