diff mbox

[v1,7/9] target-arm: Add the ARMInsnSyndrome type

Message ID 1455287642-28166-8-git-send-email-edgar.iglesias@gmail.com
State New
Headers show

Commit Message

Edgar E. Iglesias Feb. 12, 2016, 2:34 p.m. UTC
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Add the ARMInsnSyndrome type including helper functions to
encode and decode it into an u32. This is in preparation for
Instruction Syndrome generation for Data Aborts.

No functional change.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 target-arm/cpu.h       | 22 +++++++++++++++++++
 target-arm/translate.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

Comments

Peter Maydell Feb. 16, 2016, 7:11 p.m. UTC | #1
On 12 February 2016 at 14:34, Edgar E. Iglesias
<edgar.iglesias@gmail.com> wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
>
> Add the ARMInsnSyndrome type including helper functions to
> encode and decode it into an u32. This is in preparation for
> Instruction Syndrome generation for Data Aborts.
>
> No functional change.

I find this patch confusing -- syndromes are already 32 bits,
so why is the encoding of the syndrome information into 32 bits
not just the syndrome register format ?

thanks
-- PMM
diff mbox

Patch

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5137632..a00a121 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -123,6 +123,28 @@  typedef struct {
     uint32_t base_mask;
 } TCR;
 
+/* Holds the state needed to create an instruction syndrome.  */
+typedef struct ARMInsnSyndrome {
+    /* Data Abort section.  */
+    struct {
+        bool valid;
+        unsigned int sas;
+        bool sse;
+        unsigned int srt;
+        bool sf;
+        bool ar;
+    } dabt;
+
+    /* SWStep section.  */
+    struct {
+        /* True if the insn just emitted was a load-exclusive instruction
+         * (necessary for syndrome information for single step exceptions),
+         * ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
+         */
+        bool ex;
+    } swstep;
+} ARMInsnSyndrome;
+
 typedef struct CPUARMState {
     /* Regs for current mode.  */
     uint32_t regs[16];
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 53ef971..a94e17e 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -151,4 +151,61 @@  void arm_free_cc(DisasCompare *cmp);
 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
 void arm_gen_test_cc(int cc, TCGLabel *label);
 
+
+/* The following describes the packing and unpacking of the Data Abort
+ * section of an ARMInsnSyndrome from/into an u32.
+ */
+
+/* Field widths.  */
+#define ISYN_WIDTH_valid 1
+#define ISYN_WIDTH_sas 2
+#define ISYN_WIDTH_sse 1
+#define ISYN_WIDTH_srt 5
+#define ISYN_WIDTH_sf  1
+#define ISYN_WIDTH_ar  1
+
+/* We use 64bit deposit to allow for overflow checking.  */
+#define ISYN_SHIFT_IN(val, isyn, field)                      \
+    {                                                        \
+        unsigned int width = xglue(ISYN_WIDTH_, field);      \
+        val <<= width;                                       \
+        val = deposit64(val, 0, width, (isyn).field);        \
+    } while (0)
+
+#define ISYN_SHIFT_OUT(val, isyn, field)                     \
+    {                                                        \
+        unsigned int width = xglue(ISYN_WIDTH_, field);      \
+        (isyn).field = extract32(val, 0, width);             \
+        val >>= width;                                       \
+    } while (0)
+
+static inline uint32_t arm_encode_dabt_isyn_u32(ARMInsnSyndrome *isyn)
+{
+    uint64_t v = 0;
+    uint32_t v32;
+
+    ISYN_SHIFT_IN(v, isyn->dabt, valid);
+    ISYN_SHIFT_IN(v, isyn->dabt, sas);
+    ISYN_SHIFT_IN(v, isyn->dabt, sse);
+    ISYN_SHIFT_IN(v, isyn->dabt, srt);
+    ISYN_SHIFT_IN(v, isyn->dabt, sf);
+    ISYN_SHIFT_IN(v, isyn->dabt, ar);
+    /* Check for overflows.  */
+    v32 = v;
+    assert(v32 == v);
+    return v32;
+}
+
+static inline void arm_decode_dabt_isyn_u32(ARMInsnSyndrome *isyn, uint32_t v)
+{
+    /* The fields must be shifted out in reverse order.  */
+    ISYN_SHIFT_OUT(v, isyn->dabt, ar);
+    ISYN_SHIFT_OUT(v, isyn->dabt, sf);
+    ISYN_SHIFT_OUT(v, isyn->dabt, srt);
+    ISYN_SHIFT_OUT(v, isyn->dabt, sse);
+    ISYN_SHIFT_OUT(v, isyn->dabt, sas);
+    ISYN_SHIFT_OUT(v, isyn->dabt, valid);
+    assert(v == 0);
+}
+
 #endif /* TARGET_ARM_TRANSLATE_H */