diff mbox

[6/6,RFC] SPARCV8 asr17 register support.

Message ID 0c3c2a6386d496eab09ec18e16657c960ad3a9d0.1291397462.git.chouteau@adacore.com
State New
Headers show

Commit Message

Fabien Chouteau Dec. 6, 2010, 9:26 a.m. UTC
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
---
 hw/leon3.c               |    6 ++++++
 target-sparc/cpu.h       |    1 +
 target-sparc/machine.c   |    2 ++
 target-sparc/translate.c |   10 ++++++++++
 4 files changed, 19 insertions(+), 0 deletions(-)

Comments

Blue Swirl Dec. 6, 2010, 6:01 p.m. UTC | #1
On Mon, Dec 6, 2010 at 9:26 AM, Fabien Chouteau <chouteau@adacore.com> wrote:
>
> Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
> ---
>  hw/leon3.c               |    6 ++++++
>  target-sparc/cpu.h       |    1 +
>  target-sparc/machine.c   |    2 ++
>  target-sparc/translate.c |   10 ++++++++++
>  4 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/hw/leon3.c b/hw/leon3.c
> index ba61081..9605ce8 100644
> --- a/hw/leon3.c
> +++ b/hw/leon3.c
> @@ -187,6 +187,12 @@ static void main_cpu_reset(void *opaque)
>        values */
>     leon3_state.inst_cache_conf = 0x10220000;
>     leon3_state.data_cache_conf = 0x18220000;
> +
> +    /* Asr17 for Leon3 mono-processor */
> +    env->asr17 &= 0 << 28;          /* CPU id */
> +    env->asr17 &= 1 << 8;           /* SPARC V8 multiply and divide available */
> +    env->asr17 &= env->nwindows -1; /* Number of implemented registers
> +                                       windows */

This is constant...

>  }
>
>  static void leon3_generic_hw_init(ram_addr_t  ram_size,
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index 6020ffd..36d49fc 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -341,6 +341,7 @@ typedef struct CPUSPARCState {
>                           from PSR) */
>  #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
>     uint32_t wim;      /* window invalid mask */
> +    uint32_t asr17;    /* asr17 */

... so no new env fields are needed...

>  #endif
>     target_ulong tbr;  /* trap base register */
>  #if !defined(TARGET_SPARC64)
> diff --git a/target-sparc/machine.c b/target-sparc/machine.c
> index 752e431..c530bd3 100644
> --- a/target-sparc/machine.c
> +++ b/target-sparc/machine.c
> @@ -42,6 +42,7 @@ void cpu_save(QEMUFile *f, void *opaque)
>     qemu_put_be32s(f, &env->pil_in);
>  #ifndef TARGET_SPARC64
>     qemu_put_be32s(f, &env->wim);
> +    qemu_put_be32s(f, &env->asr17);

... there's also nothing to save/load...

>     /* MMU */
>     for (i = 0; i < 32; i++)
>         qemu_put_be32s(f, &env->mmuregs[i]);
> @@ -138,6 +139,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
>     qemu_get_be32s(f, &env->pil_in);
>  #ifndef TARGET_SPARC64
>     qemu_get_be32s(f, &env->wim);
> +    qemu_get_be32s(f, &env->asr17);
>     /* MMU */
>     for (i = 0; i < 32; i++)
>         qemu_get_be32s(f, &env->mmuregs[i]);
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index 23f9519..65de614 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -58,6 +58,7 @@ static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
>  static TCGv_i32 cpu_softint;
>  #else
>  static TCGv cpu_wim;
> +static TCGv cpu_asr17;
>  #endif
>  /* local register indexes (only used inside old micro ops) */
>  static TCGv cpu_tmp0;
> @@ -2049,6 +2050,8 @@ static void disas_sparc_insn(DisasContext * dc)
>                 rs1 = GET_FIELD(insn, 13, 17);
>                 switch(rs1) {
>                 case 0: /* rdy */
> +                    gen_movl_TN_reg(rd, cpu_y);
> +                    break;
>  #ifndef TARGET_SPARC64
>                 case 0x01 ... 0x0e: /* undefined in the SPARCv8
>                                        manual, rdy on the microSPARC
> @@ -2058,6 +2061,11 @@ static void disas_sparc_insn(DisasContext * dc)
>                 case 0x10 ... 0x1f: /* implementation-dependent in the
>                                        SPARCv8 manual, rdy on the
>                                        microSPARC II */
> +
> +                    if (rs1 == 0x11) { /* Read %asr17 */
> +                        gen_movl_TN_reg(rd, cpu_asr17);

Instead:
r_const = tcg_const_tl(asr constants  | dc->def->nwindows - 1);
gen_movl_TN_reg(rd, r_const);
tcg_temp_free(r_const);
Fabien Chouteau Dec. 7, 2010, 11:51 a.m. UTC | #2
On 12/06/2010 07:01 PM, Blue Swirl wrote:
> On Mon, Dec 6, 2010 at 9:26 AM, Fabien Chouteau<chouteau@adacore.com>  wrote:
>>
>> Signed-off-by: Fabien Chouteau<chouteau@adacore.com>
>> ---
>>   hw/leon3.c               |    6 ++++++
>>   target-sparc/cpu.h       |    1 +
>>   target-sparc/machine.c   |    2 ++
>>   target-sparc/translate.c |   10 ++++++++++
>>   4 files changed, 19 insertions(+), 0 deletions(-)
>>
>> diff --git a/hw/leon3.c b/hw/leon3.c
>> index ba61081..9605ce8 100644
>> --- a/hw/leon3.c
>> +++ b/hw/leon3.c
>> @@ -187,6 +187,12 @@ static void main_cpu_reset(void *opaque)
>>         values */
>>      leon3_state.inst_cache_conf = 0x10220000;
>>      leon3_state.data_cache_conf = 0x18220000;
>> +
>> +    /* Asr17 for Leon3 mono-processor */
>> +    env->asr17&= 0<<  28;          /* CPU id */
>> +    env->asr17&= 1<<  8;           /* SPARC V8 multiply and divide available */
>> +    env->asr17&= env->nwindows -1; /* Number of implemented registers
>> +                                       windows */
>
> This is constant...
>
>>   }
>>
>>   static void leon3_generic_hw_init(ram_addr_t  ram_size,
>> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
>> index 6020ffd..36d49fc 100644
>> --- a/target-sparc/cpu.h
>> +++ b/target-sparc/cpu.h
>> @@ -341,6 +341,7 @@ typedef struct CPUSPARCState {
>>                            from PSR) */
>>   #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
>>      uint32_t wim;      /* window invalid mask */
>> +    uint32_t asr17;    /* asr17 */
>
> ... so no new env fields are needed...
>
>>   #endif
>>      target_ulong tbr;  /* trap base register */
>>   #if !defined(TARGET_SPARC64)
>> diff --git a/target-sparc/machine.c b/target-sparc/machine.c
>> index 752e431..c530bd3 100644
>> --- a/target-sparc/machine.c
>> +++ b/target-sparc/machine.c
>> @@ -42,6 +42,7 @@ void cpu_save(QEMUFile *f, void *opaque)
>>      qemu_put_be32s(f,&env->pil_in);
>>   #ifndef TARGET_SPARC64
>>      qemu_put_be32s(f,&env->wim);
>> +    qemu_put_be32s(f,&env->asr17);
>
> ... there's also nothing to save/load...
>
>>      /* MMU */
>>      for (i = 0; i<  32; i++)
>>          qemu_put_be32s(f,&env->mmuregs[i]);
>> @@ -138,6 +139,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
>>      qemu_get_be32s(f,&env->pil_in);
>>   #ifndef TARGET_SPARC64
>>      qemu_get_be32s(f,&env->wim);
>> +    qemu_get_be32s(f,&env->asr17);
>>      /* MMU */
>>      for (i = 0; i<  32; i++)
>>          qemu_get_be32s(f,&env->mmuregs[i]);
>> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
>> index 23f9519..65de614 100644
>> --- a/target-sparc/translate.c
>> +++ b/target-sparc/translate.c
>> @@ -58,6 +58,7 @@ static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
>>   static TCGv_i32 cpu_softint;
>>   #else
>>   static TCGv cpu_wim;
>> +static TCGv cpu_asr17;
>>   #endif
>>   /* local register indexes (only used inside old micro ops) */
>>   static TCGv cpu_tmp0;
>> @@ -2049,6 +2050,8 @@ static void disas_sparc_insn(DisasContext * dc)
>>                  rs1 = GET_FIELD(insn, 13, 17);
>>                  switch(rs1) {
>>                  case 0: /* rdy */
>> +                    gen_movl_TN_reg(rd, cpu_y);
>> +                    break;
>>   #ifndef TARGET_SPARC64
>>                  case 0x01 ... 0x0e: /* undefined in the SPARCv8
>>                                         manual, rdy on the microSPARC
>> @@ -2058,6 +2061,11 @@ static void disas_sparc_insn(DisasContext * dc)
>>                  case 0x10 ... 0x1f: /* implementation-dependent in the
>>                                         SPARCv8 manual, rdy on the
>>                                         microSPARC II */
>> +
>> +                    if (rs1 == 0x11) { /* Read %asr17 */
>> +                        gen_movl_TN_reg(rd, cpu_asr17);
>
> Instead:
> r_const = tcg_const_tl(asr constants  | dc->def->nwindows - 1);
> gen_movl_TN_reg(rd, r_const);
> tcg_temp_free(r_const);

OK for me, if it is acceptable to have this Leon3's specific behavior 
for all the SPARC32 CPUs.
Blue Swirl Dec. 11, 2010, 9:59 a.m. UTC | #3
On Tue, Dec 7, 2010 at 11:51 AM, Fabien Chouteau <chouteau@adacore.com> wrote:
> On 12/06/2010 07:01 PM, Blue Swirl wrote:
>>
>> On Mon, Dec 6, 2010 at 9:26 AM, Fabien Chouteau<chouteau@adacore.com>
>>  wrote:
>>>
>>> Signed-off-by: Fabien Chouteau<chouteau@adacore.com>
>>> ---
>>>  hw/leon3.c               |    6 ++++++
>>>  target-sparc/cpu.h       |    1 +
>>>  target-sparc/machine.c   |    2 ++
>>>  target-sparc/translate.c |   10 ++++++++++
>>>  4 files changed, 19 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/hw/leon3.c b/hw/leon3.c
>>> index ba61081..9605ce8 100644
>>> --- a/hw/leon3.c
>>> +++ b/hw/leon3.c
>>> @@ -187,6 +187,12 @@ static void main_cpu_reset(void *opaque)
>>>        values */
>>>     leon3_state.inst_cache_conf = 0x10220000;
>>>     leon3_state.data_cache_conf = 0x18220000;
>>> +
>>> +    /* Asr17 for Leon3 mono-processor */
>>> +    env->asr17&= 0<<  28;          /* CPU id */
>>> +    env->asr17&= 1<<  8;           /* SPARC V8 multiply and divide
>>> available */
>>> +    env->asr17&= env->nwindows -1; /* Number of implemented registers
>>> +                                       windows */
>>
>> This is constant...
>>
>>>  }
>>>
>>>  static void leon3_generic_hw_init(ram_addr_t  ram_size,
>>> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
>>> index 6020ffd..36d49fc 100644
>>> --- a/target-sparc/cpu.h
>>> +++ b/target-sparc/cpu.h
>>> @@ -341,6 +341,7 @@ typedef struct CPUSPARCState {
>>>                           from PSR) */
>>>  #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
>>>     uint32_t wim;      /* window invalid mask */
>>> +    uint32_t asr17;    /* asr17 */
>>
>> ... so no new env fields are needed...
>>
>>>  #endif
>>>     target_ulong tbr;  /* trap base register */
>>>  #if !defined(TARGET_SPARC64)
>>> diff --git a/target-sparc/machine.c b/target-sparc/machine.c
>>> index 752e431..c530bd3 100644
>>> --- a/target-sparc/machine.c
>>> +++ b/target-sparc/machine.c
>>> @@ -42,6 +42,7 @@ void cpu_save(QEMUFile *f, void *opaque)
>>>     qemu_put_be32s(f,&env->pil_in);
>>>  #ifndef TARGET_SPARC64
>>>     qemu_put_be32s(f,&env->wim);
>>> +    qemu_put_be32s(f,&env->asr17);
>>
>> ... there's also nothing to save/load...
>>
>>>     /* MMU */
>>>     for (i = 0; i<  32; i++)
>>>         qemu_put_be32s(f,&env->mmuregs[i]);
>>> @@ -138,6 +139,7 @@ int cpu_load(QEMUFile *f, void *opaque, int
>>> version_id)
>>>     qemu_get_be32s(f,&env->pil_in);
>>>  #ifndef TARGET_SPARC64
>>>     qemu_get_be32s(f,&env->wim);
>>> +    qemu_get_be32s(f,&env->asr17);
>>>     /* MMU */
>>>     for (i = 0; i<  32; i++)
>>>         qemu_get_be32s(f,&env->mmuregs[i]);
>>> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
>>> index 23f9519..65de614 100644
>>> --- a/target-sparc/translate.c
>>> +++ b/target-sparc/translate.c
>>> @@ -58,6 +58,7 @@ static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr,
>>> cpu_ver;
>>>  static TCGv_i32 cpu_softint;
>>>  #else
>>>  static TCGv cpu_wim;
>>> +static TCGv cpu_asr17;
>>>  #endif
>>>  /* local register indexes (only used inside old micro ops) */
>>>  static TCGv cpu_tmp0;
>>> @@ -2049,6 +2050,8 @@ static void disas_sparc_insn(DisasContext * dc)
>>>                 rs1 = GET_FIELD(insn, 13, 17);
>>>                 switch(rs1) {
>>>                 case 0: /* rdy */
>>> +                    gen_movl_TN_reg(rd, cpu_y);
>>> +                    break;
>>>  #ifndef TARGET_SPARC64
>>>                 case 0x01 ... 0x0e: /* undefined in the SPARCv8
>>>                                        manual, rdy on the microSPARC
>>> @@ -2058,6 +2061,11 @@ static void disas_sparc_insn(DisasContext * dc)
>>>                 case 0x10 ... 0x1f: /* implementation-dependent in the
>>>                                        SPARCv8 manual, rdy on the
>>>                                        microSPARC II */
>>> +
>>> +                    if (rs1 == 0x11) { /* Read %asr17 */
>>> +                        gen_movl_TN_reg(rd, cpu_asr17);
>>
>> Instead:
>> r_const = tcg_const_tl(asr constants  | dc->def->nwindows - 1);
>> gen_movl_TN_reg(rd, r_const);
>> tcg_temp_free(r_const);
>
> OK for me, if it is acceptable to have this Leon3's specific behavior for
> all the SPARC32 CPUs.

This will not affect other CPUs when you use CPU feature bits to make
the ASR only available to Leon3.
Fabien Chouteau Dec. 13, 2010, 5:01 p.m. UTC | #4
On 12/11/2010 10:59 AM, Blue Swirl wrote:
> On Tue, Dec 7, 2010 at 11:51 AM, Fabien Chouteau<chouteau@adacore.com>  wrote:
>> On 12/06/2010 07:01 PM, Blue Swirl wrote:
>>>
>>> On Mon, Dec 6, 2010 at 9:26 AM, Fabien Chouteau<chouteau@adacore.com>
>>>   wrote:
>>>>
>>>> Signed-off-by: Fabien Chouteau<chouteau@adacore.com>
>>>> ---
>>>>   hw/leon3.c               |    6 ++++++
>>>>   target-sparc/cpu.h       |    1 +
>>>>   target-sparc/machine.c   |    2 ++
>>>>   target-sparc/translate.c |   10 ++++++++++
>>>>   4 files changed, 19 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/hw/leon3.c b/hw/leon3.c
>>>> index ba61081..9605ce8 100644
>>>> --- a/hw/leon3.c
>>>> +++ b/hw/leon3.c
>>>> @@ -187,6 +187,12 @@ static void main_cpu_reset(void *opaque)
>>>>         values */
>>>>      leon3_state.inst_cache_conf = 0x10220000;
>>>>      leon3_state.data_cache_conf = 0x18220000;
>>>> +
>>>> +    /* Asr17 for Leon3 mono-processor */
>>>> +    env->asr17&= 0<<    28;          /* CPU id */
>>>> +    env->asr17&= 1<<    8;           /* SPARC V8 multiply and divide
>>>> available */
>>>> +    env->asr17&= env->nwindows -1; /* Number of implemented registers
>>>> +                                       windows */
>>>
>>> This is constant...
>>>
>>>>   }
>>>>
>>>>   static void leon3_generic_hw_init(ram_addr_t  ram_size,
>>>> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
>>>> index 6020ffd..36d49fc 100644
>>>> --- a/target-sparc/cpu.h
>>>> +++ b/target-sparc/cpu.h
>>>> @@ -341,6 +341,7 @@ typedef struct CPUSPARCState {
>>>>                            from PSR) */
>>>>   #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
>>>>      uint32_t wim;      /* window invalid mask */
>>>> +    uint32_t asr17;    /* asr17 */
>>>
>>> ... so no new env fields are needed...
>>>
>>>>   #endif
>>>>      target_ulong tbr;  /* trap base register */
>>>>   #if !defined(TARGET_SPARC64)
>>>> diff --git a/target-sparc/machine.c b/target-sparc/machine.c
>>>> index 752e431..c530bd3 100644
>>>> --- a/target-sparc/machine.c
>>>> +++ b/target-sparc/machine.c
>>>> @@ -42,6 +42,7 @@ void cpu_save(QEMUFile *f, void *opaque)
>>>>      qemu_put_be32s(f,&env->pil_in);
>>>>   #ifndef TARGET_SPARC64
>>>>      qemu_put_be32s(f,&env->wim);
>>>> +    qemu_put_be32s(f,&env->asr17);
>>>
>>> ... there's also nothing to save/load...
>>>
>>>>      /* MMU */
>>>>      for (i = 0; i<    32; i++)
>>>>          qemu_put_be32s(f,&env->mmuregs[i]);
>>>> @@ -138,6 +139,7 @@ int cpu_load(QEMUFile *f, void *opaque, int
>>>> version_id)
>>>>      qemu_get_be32s(f,&env->pil_in);
>>>>   #ifndef TARGET_SPARC64
>>>>      qemu_get_be32s(f,&env->wim);
>>>> +    qemu_get_be32s(f,&env->asr17);
>>>>      /* MMU */
>>>>      for (i = 0; i<    32; i++)
>>>>          qemu_get_be32s(f,&env->mmuregs[i]);
>>>> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
>>>> index 23f9519..65de614 100644
>>>> --- a/target-sparc/translate.c
>>>> +++ b/target-sparc/translate.c
>>>> @@ -58,6 +58,7 @@ static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr,
>>>> cpu_ver;
>>>>   static TCGv_i32 cpu_softint;
>>>>   #else
>>>>   static TCGv cpu_wim;
>>>> +static TCGv cpu_asr17;
>>>>   #endif
>>>>   /* local register indexes (only used inside old micro ops) */
>>>>   static TCGv cpu_tmp0;
>>>> @@ -2049,6 +2050,8 @@ static void disas_sparc_insn(DisasContext * dc)
>>>>                  rs1 = GET_FIELD(insn, 13, 17);
>>>>                  switch(rs1) {
>>>>                  case 0: /* rdy */
>>>> +                    gen_movl_TN_reg(rd, cpu_y);
>>>> +                    break;
>>>>   #ifndef TARGET_SPARC64
>>>>                  case 0x01 ... 0x0e: /* undefined in the SPARCv8
>>>>                                         manual, rdy on the microSPARC
>>>> @@ -2058,6 +2061,11 @@ static void disas_sparc_insn(DisasContext * dc)
>>>>                  case 0x10 ... 0x1f: /* implementation-dependent in the
>>>>                                         SPARCv8 manual, rdy on the
>>>>                                         microSPARC II */
>>>> +
>>>> +                    if (rs1 == 0x11) { /* Read %asr17 */
>>>> +                        gen_movl_TN_reg(rd, cpu_asr17);
>>>
>>> Instead:
>>> r_const = tcg_const_tl(asr constants  | dc->def->nwindows - 1);
>>> gen_movl_TN_reg(rd, r_const);
>>> tcg_temp_free(r_const);
>>
>> OK for me, if it is acceptable to have this Leon3's specific behavior for
>> all the SPARC32 CPUs.
>
> This will not affect other CPUs when you use CPU feature bits to make
> the ASR only available to Leon3.

OK, I will try that.
diff mbox

Patch

diff --git a/hw/leon3.c b/hw/leon3.c
index ba61081..9605ce8 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -187,6 +187,12 @@  static void main_cpu_reset(void *opaque)
        values */
     leon3_state.inst_cache_conf = 0x10220000;
     leon3_state.data_cache_conf = 0x18220000;
+
+    /* Asr17 for Leon3 mono-processor */
+    env->asr17 &= 0 << 28;          /* CPU id */
+    env->asr17 &= 1 << 8;           /* SPARC V8 multiply and divide available */
+    env->asr17 &= env->nwindows -1; /* Number of implemented registers
+                                       windows */
 }
 
 static void leon3_generic_hw_init(ram_addr_t  ram_size,
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 6020ffd..36d49fc 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -341,6 +341,7 @@  typedef struct CPUSPARCState {
                           from PSR) */
 #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
     uint32_t wim;      /* window invalid mask */
+    uint32_t asr17;    /* asr17 */
 #endif
     target_ulong tbr;  /* trap base register */
 #if !defined(TARGET_SPARC64)
diff --git a/target-sparc/machine.c b/target-sparc/machine.c
index 752e431..c530bd3 100644
--- a/target-sparc/machine.c
+++ b/target-sparc/machine.c
@@ -42,6 +42,7 @@  void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32s(f, &env->pil_in);
 #ifndef TARGET_SPARC64
     qemu_put_be32s(f, &env->wim);
+    qemu_put_be32s(f, &env->asr17);
     /* MMU */
     for (i = 0; i < 32; i++)
         qemu_put_be32s(f, &env->mmuregs[i]);
@@ -138,6 +139,7 @@  int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_be32s(f, &env->pil_in);
 #ifndef TARGET_SPARC64
     qemu_get_be32s(f, &env->wim);
+    qemu_get_be32s(f, &env->asr17);
     /* MMU */
     for (i = 0; i < 32; i++)
         qemu_get_be32s(f, &env->mmuregs[i]);
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 23f9519..65de614 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -58,6 +58,7 @@  static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
 static TCGv_i32 cpu_softint;
 #else
 static TCGv cpu_wim;
+static TCGv cpu_asr17;
 #endif
 /* local register indexes (only used inside old micro ops) */
 static TCGv cpu_tmp0;
@@ -2049,6 +2050,8 @@  static void disas_sparc_insn(DisasContext * dc)
                 rs1 = GET_FIELD(insn, 13, 17);
                 switch(rs1) {
                 case 0: /* rdy */
+                    gen_movl_TN_reg(rd, cpu_y);
+                    break;
 #ifndef TARGET_SPARC64
                 case 0x01 ... 0x0e: /* undefined in the SPARCv8
                                        manual, rdy on the microSPARC
@@ -2058,6 +2061,11 @@  static void disas_sparc_insn(DisasContext * dc)
                 case 0x10 ... 0x1f: /* implementation-dependent in the
                                        SPARCv8 manual, rdy on the
                                        microSPARC II */
+
+                    if (rs1 == 0x11) { /* Read %asr17 */
+                        gen_movl_TN_reg(rd, cpu_asr17);
+                        break;
+                    }
 #endif
                     gen_movl_TN_reg(rd, cpu_y);
                     break;
@@ -5019,6 +5027,8 @@  void gen_intermediate_code_init(CPUSPARCState *env)
 #else
         cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, wim),
                                      "wim");
+        cpu_asr17 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, asr17),
+                                     "asr17");
 #endif
         cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cond),
                                       "cond");