* [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L @ 2008-12-11 18:27 Vladimir Prus 2008-12-11 18:36 ` Paul Brook 0 siblings, 1 reply; 8+ messages in thread From: Vladimir Prus @ 2008-12-11 18:27 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 386 bytes --] This patch implements a couple more instructions specific to SH4A. The patch includes a copy of their description from the manual. The only point worth noting is the LDST -- my copy of the manual does not explain it, but I was told by Paul Mundt that this is internal state of the processor not otherwise exposed. So, adding a new field in processor state seems reasonable. - Volodya [-- Attachment #2: 0003-SH-Implement-MOVCO.L-and-MOVLI.L.patch --] [-- Type: text/x-diff, Size: 3775 bytes --] From db021cfa5ca5a170d9691910ab7450cc84dcaf97 Mon Sep 17 00:00:00 2001 From: Vladimir Prus <vladimir@codesourcery.com> Date: Sun, 12 Oct 2008 19:36:22 +0400 Subject: [PATCH] SH: Implement MOVCO.L and MOVLI.L To: qemu-devel@nongnu.org X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 * target-sh4/cpu.h (struct CPUSH4State): New field ldst. * target-sh4/helper.c (do_interrupt): Initialize ldst. * target-sh4/translate.c (cpu_ldst): New. (sh4_translate_init): Initialize cpu_ldst. (_decode_opc): Support MOVCO.L and MOVLI.L. --- target-sh4/cpu.h | 2 ++ target-sh4/helper.c | 1 + target-sh4/translate.c | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletions(-) diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index a0108b4..ae434d1 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -135,6 +135,8 @@ typedef struct CPUSH4State { uint32_t prr; /* Processor Revision Register */ uint32_t cvr; /* Cache Version Register */ + uint32_t ldst; + CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 882bc9c..61b668b 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) env->spc = env->pc; env->sgr = env->gregs[15]; env->sr |= SR_BL | SR_MD | SR_RB; + env->ldst = 0; if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { /* Branch instruction should be executed again before delay slot. */ diff --git a/target-sh4/translate.c b/target-sh4/translate.c index d38e95f..ba9db14 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; static TCGv cpu_gregs[24]; static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; static TCGv cpu_fregs[32]; /* internal register indexes */ @@ -144,6 +144,8 @@ static void sh4_translate_init(void) cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, delayed_pc), "_delayed_pc_"); + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, ldst), "_ldst_"); for (i = 0; i < 32; i++) cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, @@ -1543,6 +1545,37 @@ static void _decode_opc(DisasContext * ctx) case 0x0029: /* movt Rn */ tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); return; + case 0x0073: + /* MOVCO.L + LDST -> T + If (T == 1) R0 -> (Rn) + 0 -> LDST + For now, do unconditional move. FIXME. + */ + if (ctx->features & SH_FEATURE_SH4A) { + int label = gen_new_label(); + gen_clr_t(); + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); + gen_set_label(label); + tcg_gen_movi_i32(cpu_ldst, 0); + return; + } else + break; + case 0x0063: + /* MOVLI.L @Rm,R0 + 1 -> LDST + (Rm) -> R0 + When interrupt/exception + occurred 0 -> LDST + */ + if (ctx->features & SH_FEATURE_SH4A) { + tcg_gen_movi_i32(cpu_ldst, 1); + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); + return; + } else + break; case 0x0093: /* ocbi @Rn */ { TCGv dummy = tcg_temp_new(); -- 1.5.3.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2008-12-11 18:27 [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L Vladimir Prus @ 2008-12-11 18:36 ` Paul Brook 2008-12-11 18:48 ` Vladimir Prus 0 siblings, 1 reply; 8+ messages in thread From: Paul Brook @ 2008-12-11 18:36 UTC (permalink / raw) To: qemu-devel; +Cc: Vladimir Prus On Thursday 11 December 2008, Vladimir Prus wrote: > This patch implements a couple more instructions > specific to SH4A. > + For now, do unconditional move. FIXME. I can't make sense of this FIXME. Paul ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2008-12-11 18:36 ` Paul Brook @ 2008-12-11 18:48 ` Vladimir Prus 2009-02-07 14:24 ` Aurelien Jarno 0 siblings, 1 reply; 8+ messages in thread From: Vladimir Prus @ 2008-12-11 18:48 UTC (permalink / raw) To: Paul Brook; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 393 bytes --] On Thursday 11 December 2008 21:36:13 Paul Brook wrote: > On Thursday 11 December 2008, Vladimir Prus wrote: > > This patch implements a couple more instructions > > specific to SH4A. > > > + For now, do unconditional move. FIXME. > > I can't make sense of this FIXME. At it happens, it's stale. The entire line you quoted can be removed. I attach the revised patch. - Volodya [-- Attachment #2: movcol.diff --] [-- Type: text/x-diff, Size: 3324 bytes --] commit 9ba7a6294a809dc11a0348ccca501513dd90ae6e Author: Vladimir Prus <vladimir@codesourcery.com> Date: Sun Oct 12 19:36:22 2008 +0400 SH: Implement MOVCO.L and MOVLI.L * target-sh4/cpu.h (struct CPUSH4State): New field ldst. * target-sh4/helper.c (do_interrupt): Initialize ldst. * target-sh4/translate.c (cpu_ldst): New. (sh4_translate_init): Initialize cpu_ldst. (_decode_opc): Support MOVCO.L and MOVLI.L. diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index a0108b4..ae434d1 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -135,6 +135,8 @@ typedef struct CPUSH4State { uint32_t prr; /* Processor Revision Register */ uint32_t cvr; /* Cache Version Register */ + uint32_t ldst; + CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 882bc9c..61b668b 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) env->spc = env->pc; env->sgr = env->gregs[15]; env->sr |= SR_BL | SR_MD | SR_RB; + env->ldst = 0; if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { /* Branch instruction should be executed again before delay slot. */ diff --git a/target-sh4/translate.c b/target-sh4/translate.c index d38e95f..e4a1b28 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; static TCGv cpu_gregs[24]; static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; static TCGv cpu_fregs[32]; /* internal register indexes */ @@ -144,6 +144,8 @@ static void sh4_translate_init(void) cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, delayed_pc), "_delayed_pc_"); + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, ldst), "_ldst_"); for (i = 0; i < 32; i++) cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, @@ -1543,6 +1545,36 @@ static void _decode_opc(DisasContext * ctx) case 0x0029: /* movt Rn */ tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); return; + case 0x0073: + /* MOVCO.L + LDST -> T + If (T == 1) R0 -> (Rn) + 0 -> LDST + */ + if (ctx->features & SH_FEATURE_SH4A) { + int label = gen_new_label(); + gen_clr_t(); + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); + gen_set_label(label); + tcg_gen_movi_i32(cpu_ldst, 0); + return; + } else + break; + case 0x0063: + /* MOVLI.L @Rm,R0 + 1 -> LDST + (Rm) -> R0 + When interrupt/exception + occurred 0 -> LDST + */ + if (ctx->features & SH_FEATURE_SH4A) { + tcg_gen_movi_i32(cpu_ldst, 1); + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); + return; + } else + break; case 0x0093: /* ocbi @Rn */ { TCGv dummy = tcg_temp_new(); ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2008-12-11 18:48 ` Vladimir Prus @ 2009-02-07 14:24 ` Aurelien Jarno 2009-02-11 21:05 ` Vladimir Prus 0 siblings, 1 reply; 8+ messages in thread From: Aurelien Jarno @ 2009-02-07 14:24 UTC (permalink / raw) To: Vladimir Prus; +Cc: qemu-devel On Thu, Dec 11, 2008 at 09:48:00PM +0300, Vladimir Prus wrote: > On Thursday 11 December 2008 21:36:13 Paul Brook wrote: > > On Thursday 11 December 2008, Vladimir Prus wrote: > > > This patch implements a couple more instructions > > > specific to SH4A. > > > > > + For now, do unconditional move. FIXME. > > > > I can't make sense of this FIXME. > > At it happens, it's stale. The entire line you quoted can be removed. > I attach the revised patch. > > - Volodya > > > commit 9ba7a6294a809dc11a0348ccca501513dd90ae6e > Author: Vladimir Prus <vladimir@codesourcery.com> > Date: Sun Oct 12 19:36:22 2008 +0400 > > SH: Implement MOVCO.L and MOVLI.L > > * target-sh4/cpu.h (struct CPUSH4State): New field ldst. > * target-sh4/helper.c (do_interrupt): Initialize ldst. > * target-sh4/translate.c (cpu_ldst): New. > (sh4_translate_init): Initialize cpu_ldst. > (_decode_opc): Support MOVCO.L and MOVLI.L. > > diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h > index a0108b4..ae434d1 100644 > --- a/target-sh4/cpu.h > +++ b/target-sh4/cpu.h > @@ -135,6 +135,8 @@ typedef struct CPUSH4State { > uint32_t prr; /* Processor Revision Register */ > uint32_t cvr; /* Cache Version Register */ > > + uint32_t ldst; > + > CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ > tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ > void *intc_handle; > diff --git a/target-sh4/helper.c b/target-sh4/helper.c > index 882bc9c..61b668b 100644 > --- a/target-sh4/helper.c > +++ b/target-sh4/helper.c > @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) > env->spc = env->pc; > env->sgr = env->gregs[15]; > env->sr |= SR_BL | SR_MD | SR_RB; > + env->ldst = 0; > > if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { > /* Branch instruction should be executed again before delay slot. */ > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > index d38e95f..e4a1b28 100644 > --- a/target-sh4/translate.c > +++ b/target-sh4/translate.c > @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; > static TCGv cpu_gregs[24]; > static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; > static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; > -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; > +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; > static TCGv cpu_fregs[32]; > > /* internal register indexes */ > @@ -144,6 +144,8 @@ static void sh4_translate_init(void) > cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, > offsetof(CPUState, delayed_pc), > "_delayed_pc_"); > + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, > + offsetof(CPUState, ldst), "_ldst_"); > > for (i = 0; i < 32; i++) > cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, > @@ -1543,6 +1545,36 @@ static void _decode_opc(DisasContext * ctx) > case 0x0029: /* movt Rn */ > tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); > return; > + case 0x0073: > + /* MOVCO.L > + LDST -> T > + If (T == 1) R0 -> (Rn) > + 0 -> LDST > + */ > + if (ctx->features & SH_FEATURE_SH4A) { > + int label = gen_new_label(); > + gen_clr_t(); > + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); > + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); > + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); > + gen_set_label(label); > + tcg_gen_movi_i32(cpu_ldst, 0); > + return; > + } else > + break; > + case 0x0063: > + /* MOVLI.L @Rm,R0 > + 1 -> LDST > + (Rm) -> R0 > + When interrupt/exception > + occurred 0 -> LDST > + */ > + if (ctx->features & SH_FEATURE_SH4A) { > + tcg_gen_movi_i32(cpu_ldst, 1); > + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > + return; This TCG code doesn't seems to match the comments. With the current code, if a load exception occurs, LDST end with a value of 1 instead of 0. > + } else > + break; > case 0x0093: /* ocbi @Rn */ > { > TCGv dummy = tcg_temp_new(); -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2009-02-07 14:24 ` Aurelien Jarno @ 2009-02-11 21:05 ` Vladimir Prus 2009-02-13 20:11 ` Aurelien Jarno 0 siblings, 1 reply; 8+ messages in thread From: Vladimir Prus @ 2009-02-11 21:05 UTC (permalink / raw) To: Aurelien Jarno; +Cc: qemu-devel On Saturday 07 February 2009 17:24:59 Aurelien Jarno wrote: > On Thu, Dec 11, 2008 at 09:48:00PM +0300, Vladimir Prus wrote: > > On Thursday 11 December 2008 21:36:13 Paul Brook wrote: > > > On Thursday 11 December 2008, Vladimir Prus wrote: > > > > This patch implements a couple more instructions > > > > specific to SH4A. > > > > > > > + For now, do unconditional move. FIXME. > > > > > > I can't make sense of this FIXME. > > > > At it happens, it's stale. The entire line you quoted can be removed. > > I attach the revised patch. > > > > - Volodya > > > > > > > commit 9ba7a6294a809dc11a0348ccca501513dd90ae6e > > Author: Vladimir Prus <vladimir@codesourcery.com> > > Date: Sun Oct 12 19:36:22 2008 +0400 > > > > SH: Implement MOVCO.L and MOVLI.L > > > > * target-sh4/cpu.h (struct CPUSH4State): New field ldst. > > * target-sh4/helper.c (do_interrupt): Initialize ldst. > > * target-sh4/translate.c (cpu_ldst): New. > > (sh4_translate_init): Initialize cpu_ldst. > > (_decode_opc): Support MOVCO.L and MOVLI.L. > > > > diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h > > index a0108b4..ae434d1 100644 > > --- a/target-sh4/cpu.h > > +++ b/target-sh4/cpu.h > > @@ -135,6 +135,8 @@ typedef struct CPUSH4State { > > uint32_t prr; /* Processor Revision Register */ > > uint32_t cvr; /* Cache Version Register */ > > > > + uint32_t ldst; > > + > > CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ > > tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ > > void *intc_handle; > > diff --git a/target-sh4/helper.c b/target-sh4/helper.c > > index 882bc9c..61b668b 100644 > > --- a/target-sh4/helper.c > > +++ b/target-sh4/helper.c > > @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) > > env->spc = env->pc; > > env->sgr = env->gregs[15]; > > env->sr |= SR_BL | SR_MD | SR_RB; > > + env->ldst = 0; > > > > if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { > > /* Branch instruction should be executed again before delay slot. */ > > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > > index d38e95f..e4a1b28 100644 > > --- a/target-sh4/translate.c > > +++ b/target-sh4/translate.c > > @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; > > static TCGv cpu_gregs[24]; > > static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; > > static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; > > -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; > > +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; > > static TCGv cpu_fregs[32]; > > > > /* internal register indexes */ > > @@ -144,6 +144,8 @@ static void sh4_translate_init(void) > > cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, > > offsetof(CPUState, delayed_pc), > > "_delayed_pc_"); > > + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, > > + offsetof(CPUState, ldst), "_ldst_"); > > > > for (i = 0; i < 32; i++) > > cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, > > @@ -1543,6 +1545,36 @@ static void _decode_opc(DisasContext * ctx) > > case 0x0029: /* movt Rn */ > > tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); > > return; > > + case 0x0073: > > + /* MOVCO.L > > + LDST -> T > > + If (T == 1) R0 -> (Rn) > > + 0 -> LDST > > + */ > > + if (ctx->features & SH_FEATURE_SH4A) { > > + int label = gen_new_label(); > > + gen_clr_t(); > > + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); > > + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); > > + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); > > + gen_set_label(label); > > + tcg_gen_movi_i32(cpu_ldst, 0); > > + return; > > + } else > > + break; > > + case 0x0063: > > + /* MOVLI.L @Rm,R0 > > + 1 -> LDST > > + (Rm) -> R0 > > + When interrupt/exception > > + occurred 0 -> LDST > > + */ > > + if (ctx->features & SH_FEATURE_SH4A) { > > + tcg_gen_movi_i32(cpu_ldst, 1); > > + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > > + return; > > This TCG code doesn't seems to match the comments. With the current > code, if a load exception occurs, LDST end with a value of 1 instead of > 0. I might be missing something -- it was my intention that if any exception or interrupt happens, do_interrupt will set ldst to zero. And if the exception happens during load, there's nothing else that will set ldst back to 1. Did I miss something? - Volodya ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2009-02-11 21:05 ` Vladimir Prus @ 2009-02-13 20:11 ` Aurelien Jarno 2009-02-19 20:12 ` Vladimir Prus 0 siblings, 1 reply; 8+ messages in thread From: Aurelien Jarno @ 2009-02-13 20:11 UTC (permalink / raw) To: Vladimir Prus; +Cc: qemu-devel On Thu, Feb 12, 2009 at 12:05:15AM +0300, Vladimir Prus wrote: > On Saturday 07 February 2009 17:24:59 Aurelien Jarno wrote: > > On Thu, Dec 11, 2008 at 09:48:00PM +0300, Vladimir Prus wrote: > > > On Thursday 11 December 2008 21:36:13 Paul Brook wrote: > > > > On Thursday 11 December 2008, Vladimir Prus wrote: > > > > > This patch implements a couple more instructions > > > > > specific to SH4A. > > > > > > > > > + For now, do unconditional move. FIXME. > > > > > > > > I can't make sense of this FIXME. > > > > > > At it happens, it's stale. The entire line you quoted can be removed. > > > I attach the revised patch. > > > > > > - Volodya > > > > > > > > > > > commit 9ba7a6294a809dc11a0348ccca501513dd90ae6e > > > Author: Vladimir Prus <vladimir@codesourcery.com> > > > Date: Sun Oct 12 19:36:22 2008 +0400 > > > > > > SH: Implement MOVCO.L and MOVLI.L > > > > > > * target-sh4/cpu.h (struct CPUSH4State): New field ldst. > > > * target-sh4/helper.c (do_interrupt): Initialize ldst. > > > * target-sh4/translate.c (cpu_ldst): New. > > > (sh4_translate_init): Initialize cpu_ldst. > > > (_decode_opc): Support MOVCO.L and MOVLI.L. > > > > > > diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h > > > index a0108b4..ae434d1 100644 > > > --- a/target-sh4/cpu.h > > > +++ b/target-sh4/cpu.h > > > @@ -135,6 +135,8 @@ typedef struct CPUSH4State { > > > uint32_t prr; /* Processor Revision Register */ > > > uint32_t cvr; /* Cache Version Register */ > > > > > > + uint32_t ldst; > > > + > > > CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ > > > tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ > > > void *intc_handle; > > > diff --git a/target-sh4/helper.c b/target-sh4/helper.c > > > index 882bc9c..61b668b 100644 > > > --- a/target-sh4/helper.c > > > +++ b/target-sh4/helper.c > > > @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) > > > env->spc = env->pc; > > > env->sgr = env->gregs[15]; > > > env->sr |= SR_BL | SR_MD | SR_RB; > > > + env->ldst = 0; > > > > > > if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { > > > /* Branch instruction should be executed again before delay slot. */ > > > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > > > index d38e95f..e4a1b28 100644 > > > --- a/target-sh4/translate.c > > > +++ b/target-sh4/translate.c > > > @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; > > > static TCGv cpu_gregs[24]; > > > static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; > > > static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; > > > -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; > > > +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; > > > static TCGv cpu_fregs[32]; > > > > > > /* internal register indexes */ > > > @@ -144,6 +144,8 @@ static void sh4_translate_init(void) > > > cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, > > > offsetof(CPUState, delayed_pc), > > > "_delayed_pc_"); > > > + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, > > > + offsetof(CPUState, ldst), "_ldst_"); > > > > > > for (i = 0; i < 32; i++) > > > cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, > > > @@ -1543,6 +1545,36 @@ static void _decode_opc(DisasContext * ctx) > > > case 0x0029: /* movt Rn */ > > > tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); > > > return; > > > + case 0x0073: > > > + /* MOVCO.L > > > + LDST -> T > > > + If (T == 1) R0 -> (Rn) > > > + 0 -> LDST > > > + */ > > > + if (ctx->features & SH_FEATURE_SH4A) { > > > + int label = gen_new_label(); > > > + gen_clr_t(); > > > + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); > > > + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); > > > + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); > > > + gen_set_label(label); > > > + tcg_gen_movi_i32(cpu_ldst, 0); > > > + return; > > > + } else > > > + break; > > > + case 0x0063: > > > + /* MOVLI.L @Rm,R0 > > > + 1 -> LDST > > > + (Rm) -> R0 > > > + When interrupt/exception > > > + occurred 0 -> LDST > > > + */ > > > + if (ctx->features & SH_FEATURE_SH4A) { > > > + tcg_gen_movi_i32(cpu_ldst, 1); > > > + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > > > + return; > > > > This TCG code doesn't seems to match the comments. With the current > > code, if a load exception occurs, LDST end with a value of 1 instead of > > 0. > > I might be missing something -- it was my intention that if any exception > or interrupt happens, do_interrupt will set ldst to zero. And if the exception > happens during load, there's nothing else that will set ldst back to 1. Did > I miss something? > In system mode, I am not sure that doing that in do_interrupt() is the best way, especially given it looks like we can exit this subroutine before actually setting the value to 0, though I haven't really analyzed those cases. In user mode, it's surely wrong, given that do_interrupt() does nothing. In my opinion you should use the fact that the TCG code will stop it's execution at the point were the exception occurs. Doing something like this should work: tcg_gen_movi_i32(cpu_ldst, 0); tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); tcg_gen_movi_i32(cpu_ldst, 1); This way if everything works fine, cpu_ldst ends with 1. If an exception occurs, it stays to zero. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2009-02-13 20:11 ` Aurelien Jarno @ 2009-02-19 20:12 ` Vladimir Prus 2009-03-02 17:13 ` Aurelien Jarno 0 siblings, 1 reply; 8+ messages in thread From: Vladimir Prus @ 2009-02-19 20:12 UTC (permalink / raw) To: Aurelien Jarno; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 5979 bytes --] On Friday 13 February 2009 23:11:05 Aurelien Jarno wrote: > On Thu, Feb 12, 2009 at 12:05:15AM +0300, Vladimir Prus wrote: > > On Saturday 07 February 2009 17:24:59 Aurelien Jarno wrote: > > > On Thu, Dec 11, 2008 at 09:48:00PM +0300, Vladimir Prus wrote: > > > > On Thursday 11 December 2008 21:36:13 Paul Brook wrote: > > > > > On Thursday 11 December 2008, Vladimir Prus wrote: > > > > > > This patch implements a couple more instructions > > > > > > specific to SH4A. > > > > > > > > > > > + For now, do unconditional move. FIXME. > > > > > > > > > > I can't make sense of this FIXME. > > > > > > > > At it happens, it's stale. The entire line you quoted can be removed. > > > > I attach the revised patch. > > > > > > > > - Volodya > > > > > > > > > > > > > > > commit 9ba7a6294a809dc11a0348ccca501513dd90ae6e > > > > Author: Vladimir Prus <vladimir@codesourcery.com> > > > > Date: Sun Oct 12 19:36:22 2008 +0400 > > > > > > > > SH: Implement MOVCO.L and MOVLI.L > > > > > > > > * target-sh4/cpu.h (struct CPUSH4State): New field ldst. > > > > * target-sh4/helper.c (do_interrupt): Initialize ldst. > > > > * target-sh4/translate.c (cpu_ldst): New. > > > > (sh4_translate_init): Initialize cpu_ldst. > > > > (_decode_opc): Support MOVCO.L and MOVLI.L. > > > > > > > > diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h > > > > index a0108b4..ae434d1 100644 > > > > --- a/target-sh4/cpu.h > > > > +++ b/target-sh4/cpu.h > > > > @@ -135,6 +135,8 @@ typedef struct CPUSH4State { > > > > uint32_t prr; /* Processor Revision Register */ > > > > uint32_t cvr; /* Cache Version Register */ > > > > > > > > + uint32_t ldst; > > > > + > > > > CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ > > > > tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ > > > > void *intc_handle; > > > > diff --git a/target-sh4/helper.c b/target-sh4/helper.c > > > > index 882bc9c..61b668b 100644 > > > > --- a/target-sh4/helper.c > > > > +++ b/target-sh4/helper.c > > > > @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) > > > > env->spc = env->pc; > > > > env->sgr = env->gregs[15]; > > > > env->sr |= SR_BL | SR_MD | SR_RB; > > > > + env->ldst = 0; > > > > > > > > if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { > > > > /* Branch instruction should be executed again before delay slot. */ > > > > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > > > > index d38e95f..e4a1b28 100644 > > > > --- a/target-sh4/translate.c > > > > +++ b/target-sh4/translate.c > > > > @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; > > > > static TCGv cpu_gregs[24]; > > > > static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; > > > > static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; > > > > -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; > > > > +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; > > > > static TCGv cpu_fregs[32]; > > > > > > > > /* internal register indexes */ > > > > @@ -144,6 +144,8 @@ static void sh4_translate_init(void) > > > > cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, > > > > offsetof(CPUState, delayed_pc), > > > > "_delayed_pc_"); > > > > + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, > > > > + offsetof(CPUState, ldst), "_ldst_"); > > > > > > > > for (i = 0; i < 32; i++) > > > > cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, > > > > @@ -1543,6 +1545,36 @@ static void _decode_opc(DisasContext * ctx) > > > > case 0x0029: /* movt Rn */ > > > > tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); > > > > return; > > > > + case 0x0073: > > > > + /* MOVCO.L > > > > + LDST -> T > > > > + If (T == 1) R0 -> (Rn) > > > > + 0 -> LDST > > > > + */ > > > > + if (ctx->features & SH_FEATURE_SH4A) { > > > > + int label = gen_new_label(); > > > > + gen_clr_t(); > > > > + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); > > > > + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); > > > > + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); > > > > + gen_set_label(label); > > > > + tcg_gen_movi_i32(cpu_ldst, 0); > > > > + return; > > > > + } else > > > > + break; > > > > + case 0x0063: > > > > + /* MOVLI.L @Rm,R0 > > > > + 1 -> LDST > > > > + (Rm) -> R0 > > > > + When interrupt/exception > > > > + occurred 0 -> LDST > > > > + */ > > > > + if (ctx->features & SH_FEATURE_SH4A) { > > > > + tcg_gen_movi_i32(cpu_ldst, 1); > > > > + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > > > > + return; > > > > > > This TCG code doesn't seems to match the comments. With the current > > > code, if a load exception occurs, LDST end with a value of 1 instead of > > > 0. > > > > I might be missing something -- it was my intention that if any exception > > or interrupt happens, do_interrupt will set ldst to zero. And if the exception > > happens during load, there's nothing else that will set ldst back to 1. Did > > I miss something? > > > > In system mode, I am not sure that doing that in do_interrupt() is the > best way, especially given it looks like we can exit this subroutine > before actually setting the value to 0, though I haven't really analyzed > those cases. In user mode, it's surely wrong, given that do_interrupt() > does nothing. > > In my opinion you should use the fact that the TCG code will stop it's > execution at the point were the exception occurs. Doing something like > this should work: > > tcg_gen_movi_i32(cpu_ldst, 0); > tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > tcg_gen_movi_i32(cpu_ldst, 1); > > This way if everything works fine, cpu_ldst ends with 1. If an exception > occurs, it stays to zero. Here's a patch implementing this idea -- it appears to still work fine with 7785. - Volodya [-- Attachment #2: movcol.diff --] [-- Type: text/x-diff, Size: 2851 bytes --] commit a49011d4d2aeebd6b4da93b3fd1a80e2f031cd85 Author: Vladimir Prus <vladimir@codesourcery.com> Date: Sun Oct 12 19:36:22 2008 +0400 SH: Implement MOVCO.L and MOVLI.L * target-sh4/cpu.h (struct CPUSH4State): New field ldst. * target-sh4/translate.c (cpu_ldst): New. (sh4_translate_init): Initialize cpu_ldst. (_decode_opc): Support MOVCO.L and MOVLI.L. diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 86a4a6b..7ee22d8 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -140,6 +140,8 @@ typedef struct CPUSH4State { uint32_t prr; /* Processor Revision Register */ uint32_t cvr; /* Cache Version Register */ + uint32_t ldst; + CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; diff --git a/target-sh4/translate.c b/target-sh4/translate.c index a0ee4f1..e0bd54b 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; static TCGv cpu_gregs[24]; static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; static TCGv cpu_fregs[32]; /* internal register indexes */ @@ -144,6 +144,8 @@ static void sh4_translate_init(void) cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, delayed_pc), "_delayed_pc_"); + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, ldst), "_ldst_"); for (i = 0; i < 32; i++) cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, @@ -1559,6 +1561,37 @@ static void _decode_opc(DisasContext * ctx) case 0x0029: /* movt Rn */ tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); return; + case 0x0073: + /* MOVCO.L + LDST -> T + If (T == 1) R0 -> (Rn) + 0 -> LDST + */ + if (ctx->features & SH_FEATURE_SH4A) { + int label = gen_new_label(); + gen_clr_t(); + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); + gen_set_label(label); + tcg_gen_movi_i32(cpu_ldst, 0); + return; + } else + break; + case 0x0063: + /* MOVLI.L @Rm,R0 + 1 -> LDST + (Rm) -> R0 + When interrupt/exception + occurred 0 -> LDST + */ + if (ctx->features & SH_FEATURE_SH4A) { + tcg_gen_movi_i32(cpu_ldst, 0); + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); + tcg_gen_movi_i32(cpu_ldst, 1); + return; + } else + break; case 0x0093: /* ocbi @Rn */ { TCGv dummy = tcg_temp_new(); ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L 2009-02-19 20:12 ` Vladimir Prus @ 2009-03-02 17:13 ` Aurelien Jarno 0 siblings, 0 replies; 8+ messages in thread From: Aurelien Jarno @ 2009-03-02 17:13 UTC (permalink / raw) To: Vladimir Prus; +Cc: qemu-devel On Thu, Feb 19, 2009 at 11:12:04PM +0300, Vladimir Prus wrote: > On Friday 13 February 2009 23:11:05 Aurelien Jarno wrote: > > On Thu, Feb 12, 2009 at 12:05:15AM +0300, Vladimir Prus wrote: > > > On Saturday 07 February 2009 17:24:59 Aurelien Jarno wrote: > > > > On Thu, Dec 11, 2008 at 09:48:00PM +0300, Vladimir Prus wrote: > > > > > On Thursday 11 December 2008 21:36:13 Paul Brook wrote: > > > > > > On Thursday 11 December 2008, Vladimir Prus wrote: > > > > > > > This patch implements a couple more instructions > > > > > > > specific to SH4A. > > > > > > > > > > > > > + For now, do unconditional move. FIXME. > > > > > > > > > > > > I can't make sense of this FIXME. > > > > > > > > > > At it happens, it's stale. The entire line you quoted can be removed. > > > > > I attach the revised patch. > > > > > > > > > > - Volodya > > > > > > > > > > > > > > > > > > > commit 9ba7a6294a809dc11a0348ccca501513dd90ae6e > > > > > Author: Vladimir Prus <vladimir@codesourcery.com> > > > > > Date: Sun Oct 12 19:36:22 2008 +0400 > > > > > > > > > > SH: Implement MOVCO.L and MOVLI.L > > > > > > > > > > * target-sh4/cpu.h (struct CPUSH4State): New field ldst. > > > > > * target-sh4/helper.c (do_interrupt): Initialize ldst. > > > > > * target-sh4/translate.c (cpu_ldst): New. > > > > > (sh4_translate_init): Initialize cpu_ldst. > > > > > (_decode_opc): Support MOVCO.L and MOVLI.L. > > > > > > > > > > diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h > > > > > index a0108b4..ae434d1 100644 > > > > > --- a/target-sh4/cpu.h > > > > > +++ b/target-sh4/cpu.h > > > > > @@ -135,6 +135,8 @@ typedef struct CPUSH4State { > > > > > uint32_t prr; /* Processor Revision Register */ > > > > > uint32_t cvr; /* Cache Version Register */ > > > > > > > > > > + uint32_t ldst; > > > > > + > > > > > CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ > > > > > tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ > > > > > void *intc_handle; > > > > > diff --git a/target-sh4/helper.c b/target-sh4/helper.c > > > > > index 882bc9c..61b668b 100644 > > > > > --- a/target-sh4/helper.c > > > > > +++ b/target-sh4/helper.c > > > > > @@ -160,6 +160,7 @@ void do_interrupt(CPUState * env) > > > > > env->spc = env->pc; > > > > > env->sgr = env->gregs[15]; > > > > > env->sr |= SR_BL | SR_MD | SR_RB; > > > > > + env->ldst = 0; > > > > > > > > > > if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { > > > > > /* Branch instruction should be executed again before delay slot. */ > > > > > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > > > > > index d38e95f..e4a1b28 100644 > > > > > --- a/target-sh4/translate.c > > > > > +++ b/target-sh4/translate.c > > > > > @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; > > > > > static TCGv cpu_gregs[24]; > > > > > static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; > > > > > static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; > > > > > -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; > > > > > +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; > > > > > static TCGv cpu_fregs[32]; > > > > > > > > > > /* internal register indexes */ > > > > > @@ -144,6 +144,8 @@ static void sh4_translate_init(void) > > > > > cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, > > > > > offsetof(CPUState, delayed_pc), > > > > > "_delayed_pc_"); > > > > > + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, > > > > > + offsetof(CPUState, ldst), "_ldst_"); > > > > > > > > > > for (i = 0; i < 32; i++) > > > > > cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, > > > > > @@ -1543,6 +1545,36 @@ static void _decode_opc(DisasContext * ctx) > > > > > case 0x0029: /* movt Rn */ > > > > > tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); > > > > > return; > > > > > + case 0x0073: > > > > > + /* MOVCO.L > > > > > + LDST -> T > > > > > + If (T == 1) R0 -> (Rn) > > > > > + 0 -> LDST > > > > > + */ > > > > > + if (ctx->features & SH_FEATURE_SH4A) { > > > > > + int label = gen_new_label(); > > > > > + gen_clr_t(); > > > > > + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); > > > > > + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); > > > > > + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); > > > > > + gen_set_label(label); > > > > > + tcg_gen_movi_i32(cpu_ldst, 0); > > > > > + return; > > > > > + } else > > > > > + break; > > > > > + case 0x0063: > > > > > + /* MOVLI.L @Rm,R0 > > > > > + 1 -> LDST > > > > > + (Rm) -> R0 > > > > > + When interrupt/exception > > > > > + occurred 0 -> LDST > > > > > + */ > > > > > + if (ctx->features & SH_FEATURE_SH4A) { > > > > > + tcg_gen_movi_i32(cpu_ldst, 1); > > > > > + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > > > > > + return; > > > > > > > > This TCG code doesn't seems to match the comments. With the current > > > > code, if a load exception occurs, LDST end with a value of 1 instead of > > > > 0. > > > > > > I might be missing something -- it was my intention that if any exception > > > or interrupt happens, do_interrupt will set ldst to zero. And if the exception > > > happens during load, there's nothing else that will set ldst back to 1. Did > > > I miss something? > > > > > > > In system mode, I am not sure that doing that in do_interrupt() is the > > best way, especially given it looks like we can exit this subroutine > > before actually setting the value to 0, though I haven't really analyzed > > those cases. In user mode, it's surely wrong, given that do_interrupt() > > does nothing. > > > > In my opinion you should use the fact that the TCG code will stop it's > > execution at the point were the exception occurs. Doing something like > > this should work: > > > > tcg_gen_movi_i32(cpu_ldst, 0); > > tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > > tcg_gen_movi_i32(cpu_ldst, 1); > > > > This way if everything works fine, cpu_ldst ends with 1. If an exception > > occurs, it stays to zero. > > Here's a patch implementing this idea -- it appears to still work > fine with 7785. > > - Volodya Thanks, applied. > commit a49011d4d2aeebd6b4da93b3fd1a80e2f031cd85 > Author: Vladimir Prus <vladimir@codesourcery.com> > Date: Sun Oct 12 19:36:22 2008 +0400 > > SH: Implement MOVCO.L and MOVLI.L > > * target-sh4/cpu.h (struct CPUSH4State): New field ldst. > * target-sh4/translate.c (cpu_ldst): New. > (sh4_translate_init): Initialize cpu_ldst. > (_decode_opc): Support MOVCO.L and MOVLI.L. > > diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h > index 86a4a6b..7ee22d8 100644 > --- a/target-sh4/cpu.h > +++ b/target-sh4/cpu.h > @@ -140,6 +140,8 @@ typedef struct CPUSH4State { > uint32_t prr; /* Processor Revision Register */ > uint32_t cvr; /* Cache Version Register */ > > + uint32_t ldst; > + > CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ > tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ > void *intc_handle; > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > index a0ee4f1..e0bd54b 100644 > --- a/target-sh4/translate.c > +++ b/target-sh4/translate.c > @@ -72,7 +72,7 @@ static TCGv_ptr cpu_env; > static TCGv cpu_gregs[24]; > static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr; > static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl; > -static TCGv cpu_pr, cpu_fpscr, cpu_fpul; > +static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; > static TCGv cpu_fregs[32]; > > /* internal register indexes */ > @@ -144,6 +144,8 @@ static void sh4_translate_init(void) > cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0, > offsetof(CPUState, delayed_pc), > "_delayed_pc_"); > + cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0, > + offsetof(CPUState, ldst), "_ldst_"); > > for (i = 0; i < 32; i++) > cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0, > @@ -1559,6 +1561,37 @@ static void _decode_opc(DisasContext * ctx) > case 0x0029: /* movt Rn */ > tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T); > return; > + case 0x0073: > + /* MOVCO.L > + LDST -> T > + If (T == 1) R0 -> (Rn) > + 0 -> LDST > + */ > + if (ctx->features & SH_FEATURE_SH4A) { > + int label = gen_new_label(); > + gen_clr_t(); > + tcg_gen_or_i32(cpu_sr, cpu_sr, cpu_ldst); > + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label); > + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx); > + gen_set_label(label); > + tcg_gen_movi_i32(cpu_ldst, 0); > + return; > + } else > + break; > + case 0x0063: > + /* MOVLI.L @Rm,R0 > + 1 -> LDST > + (Rm) -> R0 > + When interrupt/exception > + occurred 0 -> LDST > + */ > + if (ctx->features & SH_FEATURE_SH4A) { > + tcg_gen_movi_i32(cpu_ldst, 0); > + tcg_gen_qemu_ld32s(REG(0), REG(B11_8), ctx->memidx); > + tcg_gen_movi_i32(cpu_ldst, 1); > + return; > + } else > + break; > case 0x0093: /* ocbi @Rn */ > { > TCGv dummy = tcg_temp_new(); -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-03-02 17:13 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-12-11 18:27 [Qemu-devel] SH: Implement MOVCO.L and MOVLI.L Vladimir Prus 2008-12-11 18:36 ` Paul Brook 2008-12-11 18:48 ` Vladimir Prus 2009-02-07 14:24 ` Aurelien Jarno 2009-02-11 21:05 ` Vladimir Prus 2009-02-13 20:11 ` Aurelien Jarno 2009-02-19 20:12 ` Vladimir Prus 2009-03-02 17:13 ` Aurelien Jarno
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).