[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 048/118] target-ppc: Introduce DFP Encode BCD to DPD
From: |
Alexander Graf |
Subject: |
[Qemu-ppc] [PULL 048/118] target-ppc: Introduce DFP Encode BCD to DPD |
Date: |
Wed, 4 Jun 2014 14:43:49 +0200 |
From: Tom Musta <address@hidden>
Add emulation of the PowerPC Decimal Floating Point Encode Binary
Coded Decimal to Densely Packed Decimal instructions denbcd[q][.].
Signed-off-by: Tom Musta <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
target-ppc/dfp_helper.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
target-ppc/helper.h | 2 ++
target-ppc/translate.c | 4 +++
3 files changed, 78 insertions(+)
diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c
index df40da7..c6c104b 100644
--- a/target-ppc/dfp_helper.c
+++ b/target-ppc/dfp_helper.c
@@ -1049,3 +1049,75 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t
*b, uint32_t sp) \
DFP_HELPER_DEDPD(ddedpd, 64)
DFP_HELPER_DEDPD(ddedpdq, 128)
+
+static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
+{
+ return *t >> ((n << 2) & 63) & 15;
+}
+
+static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
+{
+ return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
+}
+
+#define DFP_HELPER_ENBCD(op, size) \
+void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \
+{ \
+ struct PPC_DFP dfp; \
+ uint8_t digits[32]; \
+ int n = 0, offset = 0, sgn = 0, nonzero = 0; \
+ \
+ dfp_prepare_decimal##size(&dfp, 0, b, env); \
+ \
+ decNumberZero(&dfp.t); \
+ \
+ if (s) { \
+ uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
+ switch (sgnNibble) { \
+ case 0xD: \
+ case 0xB: \
+ sgn = 1; \
+ break; \
+ case 0xC: \
+ case 0xF: \
+ case 0xA: \
+ case 0xE: \
+ sgn = 0; \
+ break; \
+ default: \
+ dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \
+ return; \
+ } \
+ } \
+ \
+ while (offset < (size)/4) { \
+ n++; \
+ digits[(size)/4-n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
+ if (digits[(size)/4-n] > 10) { \
+ dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \
+ return; \
+ } else { \
+ nonzero |= (digits[(size)/4-n] > 0); \
+ } \
+ } \
+ \
+ if (nonzero) { \
+ decNumberSetBCD(&dfp.t, digits+((size)/4)-n, n); \
+ } \
+ \
+ if (s && sgn) { \
+ dfp.t.bits |= DECNEG; \
+ } \
+ decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
+ &dfp.context); \
+ dfp_set_FPRF_from_FRT(&dfp); \
+ if ((size) == 64) { \
+ t[0] = dfp.t64[0]; \
+ } else if ((size) == 128) { \
+ t[0] = dfp.t64[HI_IDX]; \
+ t[1] = dfp.t64[LO_IDX]; \
+ } \
+}
+
+DFP_HELPER_ENBCD(denbcd, 64)
+DFP_HELPER_ENBCD(denbcdq, 128)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index d4e73f2..1b40ce5 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -656,3 +656,5 @@ 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)
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)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 0de657a..6aa2df6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -8395,6 +8395,8 @@ GEN_DFP_T_B_Rc(dctfix)
GEN_DFP_T_B_Rc(dctfixq)
GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
+GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
+GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
/*** SPE extension ***/
/* Register moves */
@@ -11362,6 +11364,8 @@ GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09),
GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09),
GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a),
GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a),
+GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
+GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
#undef GEN_SPE
#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type,
PPC_NONE)
--
1.8.1.4
- [Qemu-ppc] [PULL 040/118] target-ppc: Introduce DFP Quantize, (continued)
- [Qemu-ppc] [PULL 040/118] target-ppc: Introduce DFP Quantize, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 044/118] target-ppc: Introduce Round to DFP Short/Long, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 041/118] target-ppc: Introduce DFP Reround, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 047/118] target-ppc: Introduce DFP Decode DPD to BCD, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 034/118] target-ppc: Introduce DFP Divide, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 046/118] target-ppc: Introduce DFP Convert to Fixed, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 054/118] util: Add AES ShiftRows and InvShiftRows Tables, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 056/118] target-i386: Use Common ShiftRows and InvShiftRows Tables, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 052/118] spapr_pci: fix MSI limit, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 053/118] util: Add S-Box and InvS-Box Arrays to Common AES Utils, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 048/118] target-ppc: Introduce DFP Encode BCD to DPD,
Alexander Graf <=
- [Qemu-ppc] [PULL 071/118] PPC: Add u-boot firmware for e500, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 015/118] libdecnumber: Introduce libdecnumber Code, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 057/118] target-arm: Use Common Tables in AES Instructions, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 059/118] KVM: PPC: Don't secretly add 1T segment feature to CPU, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 066/118] PPC: Fix SPR access control of L1CFG0, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 074/118] spapr: Add ibm, chip-id property in device tree, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 073/118] spapr: Add support for time base offset migration, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 027/118] target-ppc: Introduce Generator Macros for DFP Arithmetic Forms, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 061/118] PPC: e500: implement PCI INTx routing, Alexander Graf, 2014/06/04
- [Qemu-ppc] [PULL 064/118] PPC: Make all e500 CPUs SVR aware, Alexander Graf, 2014/06/04