Patchwork [RFC,11/28] target-xtensa: implement RST3 group

login
register
mail settings
Submitter Max Filippov
Date May 4, 2011, 12:59 a.m.
Message ID <1304470768-16924-11-git-send-email-jcmvbkbc@gmail.com>
Download mbox | patch
Permalink /patch/93951/
State New
Headers show

Comments

Max Filippov - May 4, 2011, 12:59 a.m.
- access to Special Registers (wsr, rsr);
- access to User Registers (wur, rur);
- misc. operations option (value clamp, sign extension, min, max);
- conditional moves.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 target-xtensa/translate.c |  147 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 147 insertions(+), 0 deletions(-)
Richard Henderson - May 4, 2011, 3:51 p.m.
On 05/03/2011 05:59 PM, Max Filippov wrote:
> +            case 2: /*SEXTu*/
> +                HAS_OPTION(XTENSA_OPTION_MISC_OP);
> +                {
> +                    TCGv_i32 tmp = tcg_temp_new_i32();
> +                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 24 - RRR_T);
> +                    tcg_gen_sari_i32(cpu_R[RRR_R], tmp, 24 - RRR_T);
> +                    tcg_temp_free(tmp);

It's probably worth special-casing extensions from bit 7 and 15
as normal 8 and 16-bit sign-extensions.  Those are likely to be
99% of all extension operations actually performed.


r~

Patch

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index f1f01bc..031873e 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -102,6 +102,32 @@  void xtensa_translate_init(void)
     }
 }
 
+static void gen_rsr(TCGv_i32 d, int sr)
+{
+    if (sregnames[sr]) {
+        tcg_gen_mov_i32(d, cpu_SR[sr]);
+    } else {
+        printf("SR %d not implemented, ", sr);
+    }
+}
+
+static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
+{
+    static void (* const wsr_handler[256])(DisasContext *dc,
+            uint32_t sr, TCGv_i32 v) = {
+    };
+
+    if (sregnames[sr]) {
+        if (wsr_handler[sr]) {
+            wsr_handler[sr](dc, sr, s);
+        } else {
+            tcg_gen_mov_i32(cpu_SR[sr], s);
+        }
+    } else {
+        printf("SR %d not implemented, ", sr);
+    }
+}
+
 static void gen_exception(int excp)
 {
     TCGv_i32 tmp = tcg_const_i32(excp);
@@ -172,6 +198,8 @@  static void disas_xtensa_insn(DisasContext *dc)
 #define BRI8_IMM8 RRI8_IMM8
 #define BRI8_IMM8_SE RRI8_IMM8_SE
 
+#define RSR_SR (_b1)
+
     uint8_t _b0 = ldub_code(dc->pc);
     uint8_t _b1 = ldub_code(dc->pc + 1);
     uint8_t _b2 = ldub_code(dc->pc + 2);
@@ -336,6 +364,125 @@  static void disas_xtensa_insn(DisasContext *dc)
             break;
 
         case 3: /*RST3*/
+            switch (_OP2) {
+            case 0: /*RSR*/
+                gen_rsr(cpu_R[RRR_T], RSR_SR);
+                break;
+
+            case 1: /*WSR*/
+                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
+                break;
+
+            case 2: /*SEXTu*/
+                HAS_OPTION(XTENSA_OPTION_MISC_OP);
+                {
+                    TCGv_i32 tmp = tcg_temp_new_i32();
+                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 24 - RRR_T);
+                    tcg_gen_sari_i32(cpu_R[RRR_R], tmp, 24 - RRR_T);
+                    tcg_temp_free(tmp);
+                }
+                break;
+
+            case 3: /*CLAMPSu*/
+                HAS_OPTION(XTENSA_OPTION_MISC_OP);
+                {
+                    TCGv_i32 tmp1 = tcg_temp_new_i32();
+                    TCGv_i32 tmp2 = tcg_temp_new_i32();
+                    int label = gen_new_label();
+
+                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
+                    tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
+                    tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
+                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
+                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
+
+                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
+                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
+                            0xffffffff >> (25 - RRR_T));
+
+                    gen_set_label(label);
+
+                    tcg_temp_free(tmp1);
+                    tcg_temp_free(tmp2);
+                }
+                break;
+
+            case 4: /*MINu*/
+            case 5: /*MAXu*/
+            case 6: /*MINUu*/
+            case 7: /*MAXUu*/
+                HAS_OPTION(XTENSA_OPTION_MISC_OP);
+                {
+                    static const TCGCond cond[] = {
+                        TCG_COND_LE,
+                        TCG_COND_GE,
+                        TCG_COND_LEU,
+                        TCG_COND_GEU
+                    };
+                    int label = gen_new_label();
+
+                    if (RRR_R != RRR_T) {
+                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
+                        tcg_gen_brcond_i32(cond[_OP2 - 4],
+                                cpu_R[RRR_S], cpu_R[RRR_T], label);
+                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
+                    } else {
+                        tcg_gen_brcond_i32(cond[_OP2 - 4],
+                                cpu_R[RRR_T], cpu_R[RRR_S], label);
+                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
+                    }
+                    gen_set_label(label);
+                }
+                break;
+
+            case 8: /*MOVEQZ*/
+            case 9: /*MOVNEZ*/
+            case 10: /*MOVLTZ*/
+            case 11: /*MOVGEZ*/
+                {
+                    static const TCGCond cond[] = {
+                        TCG_COND_NE,
+                        TCG_COND_EQ,
+                        TCG_COND_GE,
+                        TCG_COND_LT
+                    };
+                    int label = gen_new_label();
+                    tcg_gen_brcondi_i32(cond[_OP2 - 8], cpu_R[RRR_T], 0, label);
+                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
+                    gen_set_label(label);
+                }
+                break;
+
+            case 12: /*MOVFp*/
+                HAS_OPTION(XTENSA_OPTION_BOOLEAN);
+                break;
+
+            case 13: /*MOVTp*/
+                HAS_OPTION(XTENSA_OPTION_BOOLEAN);
+                break;
+
+            case 14: /*RUR*/
+                {
+                    int st = (RRR_S << 4) + RRR_T;
+                    if (uregnames[st]) {
+                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
+                    } else {
+                        printf("rur %d not implemented, ", st);
+                    }
+                }
+                break;
+
+            case 15: /*WUR*/
+                {
+                    if (uregnames[RSR_SR]) {
+                        tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
+                    } else {
+                        printf("wur %d not implemented, ", RSR_SR);
+                    }
+                }
+                break;
+
+            }
             break;
 
         case 4: /*EXTUI*/