diff mbox

[RFC,09/28] target-xtensa: implement JX/RET0/CALLX

Message ID 1304470768-16924-9-git-send-email-jcmvbkbc@gmail.com
State New
Headers show

Commit Message

Max Filippov May 4, 2011, 12:59 a.m. UTC
Group SNM0 (indirect jumps and calls).

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 target-xtensa/translate.c |   49 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 48 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 2bfa801..f4d74e0 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -130,7 +130,11 @@  static void disas_xtensa_insn(DisasContext *dc)
 #define CALL_OFFSET ((((_b0) & 0x3) << 16) | ((_b1) << 8) | (_b2))
 #define CALL_OFFSET_SE (((_b0 & 0x2) ? 0xfffc0000 : 0) | CALL_OFFSET)
 
-#define BRI12_M ((_b0) & 0x3)
+#define CALLX_N CALL_N
+#define CALLX_M ((_b0) & 0x3)
+#define CALLX_S RRR_S
+
+#define BRI12_M CALLX_M
 #define BRI12_S RRR_S
 #define BRI12_IMM12 ((((_b1) & 0xf) << 8) | (_b2))
 #define BRI12_IMM12_SE ((((_b1) & 0x8) ? 0xfffff000 : 0) | BRI12_IMM12)
@@ -165,6 +169,49 @@  static void disas_xtensa_insn(DisasContext *dc)
 
                 switch (RRR_R) {
                 case 0: /*SNM0*/
+                    switch (CALLX_M) {
+                    case 0: /*ILL*/
+                        break;
+
+                    case 1: /*reserved*/
+                        break;
+
+                    case 2: /*JR*/
+                        switch (CALLX_N) {
+                        case 0: /*RET*/
+                        case 2: /*JX*/
+                            gen_jump(dc, cpu_R[CALLX_S]);
+                            break;
+
+                        case 1: /*RETWw*/
+                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
+                            break;
+
+                        case 3: /*reserved*/
+                            break;
+                        }
+                        break;
+
+                    case 3: /*CALLX*/
+                        switch (CALLX_N) {
+                        case 0: /*CALLX0*/
+                            {
+                                TCGv_i32 tmp = tcg_temp_new_i32();
+                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
+                                tcg_gen_movi_i32(cpu_R[0], dc->pc + 3);
+                                gen_jump(dc, tmp);
+                                tcg_temp_free(tmp);
+                            }
+                            break;
+
+                        case 1: /*CALLX4w*/
+                        case 2: /*CALLX8w*/
+                        case 3: /*CALLX12w*/
+                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
+                            break;
+                        }
+                        break;
+                    }
                     break;
 
                 case 1: /*MOVSPw*/