On 09/08/2016 03:31 PM, Michael Rolnik wrote:
+#define CPU_IMM(env)    ((env)->r[62])
+#define CPU_PCL(env)    ((env)->r[63])


You don't need to represent these as actual registers. These are better considered placeholder regnums to be filled in with actual values during translation.

+struct CPUARCState {
+    uint32_t        r[64];
+
+    struct {
+        uint32_t    Lf;
+        uint32_t    Zf;     /*  zero                    */
+        uint32_t    Nf;     /*  negative                */
+        uint32_t    Cf;     /*  carry                   */
+        uint32_t    Vf;     /*  overflow                */
+        uint32_t    Uf;
+
+        uint32_t    DEf;
+        uint32_t    AEf;
+        uint32_t    A2f;    /*  interrupt 1 is active   */
+        uint32_t    A1f;    /*  interrupt 2 is active   */
+        uint32_t    E2f;    /*  interrupt 1 mask        */
+        uint32_t    E1f;    /*  interrupt 2 mask        */
+        uint32_t    Hf;     /*  halt                    */
+    } stat, stat_l1, stat_l2, stat_er;

There is no reason to represent each bit as a whole word, and even less to have four copies.

Only the current NZCV bits are relevant for expansion to a word, and even then you should consider not canonicalizing N, Z and V to a pure boolean value.

+
+    struct {
+        uint32_t    S2;
+        uint32_t    S1;
+        uint32_t    CS;
+    } macmod;

Does CS really need to be represented at all? It appears to me to be a field that you write to that clears S1 and S2.

+    switch (n) {
+        case 0x00 ... 0x3f: {
+            val = env->r[n];
+            break;
+        }

Please use the proper format for all switch statements.

    switch (n) {
    case 0x00 ... 0x3f:
        val = env->r[n];
        break;

+
+TCGv_env cpu_env;
+
+TCGv     cpu_gp;        /*  Global Pointer                      */
+TCGv     cpu_fp;        /*  Frame Pointer                       */
+TCGv     cpu_sp;        /*  Stack Pointer                       */
+TCGv     cpu_ilink1;    /*  Level 1 interrupt link register     */
+TCGv     cpu_ilink2;    /*  Level 2 interrupt link register     */
+TCGv     cpu_blink;     /*  Branch link register                */
+TCGv     cpu_mlo;       /*  Multiply low 32 bits, read only     */
+TCGv     cpu_mmi;       /*  Multiply middle 32 bits, read only  */
+TCGv     cpu_mhi;       /*  Multiply high 32 bits, read only    */

Why are these separate variables? They overlap cpu_r[N]. If you want them as names for clarity in translation, #define seems good enough.

+int arc_gen_INVALID(DisasCtxt *ctx)
+{
+    printf("invalid inst @:%08x\n", ctx->cpc);

No printf.  It's not useful, even temporarily.

+    ctx.zero = tcg_const_local_i32(0);
+    ctx.one = tcg_const_local_i32(1);
+    ctx.msb32 = tcg_const_local_i32(0x80000000);
+    ctx.msb16 = tcg_const_local_i32(0x00008000);
+    ctx.smax16 = tcg_const_local_i32(0x7fffffff);
+    ctx.smax32 = tcg_const_local_i32(0x00007fff);
+    ctx.smax5 = tcg_const_local_i32(0x0000001f);
+    ctx.smin5 = tcg_const_local_i32(0xffffffe1);

Why are you creating all of these? Creating local temps containing immediates is a horrible waste.

+        if (ctx.npc == env->lpe) {

You can't look at the contents of ENV during translation.

You'll need to implement this feature similar to how it's done for xtensa. See helper_wsr_lbeg, helper_wsr_lend, and gen_check_loop_end.


r~

Reply via email to