Hello all,

On 09/27/2013 02:48 AM, Alexander Graf wrote:
> This patch adds emulation support for the adr instruction.
> 
> Signed-off-by: Alexander Graf <ag...@suse.de>
> ---
>  target-arm/translate-a64.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index bc91324..00eda0f 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -943,6 +943,27 @@ static void handle_insg(DisasContext *s, uint32_t insn)
>      simd_st(cpu_reg(rn), freg_offs_d + idx, size);
>  }
>  
> +/* PC relative address calculation */
> +static void handle_adr(DisasContext *s, uint32_t insn)
> +{
> +    int reg = get_reg(insn);
> +    int is_page = get_bits(insn, 31, 1);
> +    uint64_t imm;
> +    uint64_t base;
> +
> +    imm = get_sbits(insn, 5, 19) << 2;
> +    imm |= get_bits(insn, 29, 2);
> +
> +    base = s->pc - 4;
> +    if (is_page) {
> +        /* ADRP (page based) */
> +        base &= ~0xFFFULL;
> +        imm <<= 12;
> +    }
> +
> +    tcg_gen_movi_i64(cpu_reg(reg), base + imm);
> +}
> +

does this work with negative values?
The spec says to SignExtend:

if page then
    imm = SignExtend(immhi:immlo:Zeros(12), 64);
else
    imm = SignExtend(immhi:immlo, 64);

/*...*/

maybe Michael you know if this is an issue in practice?
If I want to get a negative PC relative offset, how does this work?

Claudio


>  /* SIMD ORR */
>  static void handle_simdorr(DisasContext *s, uint32_t insn)
>  {
> @@ -1365,6 +1386,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
>              unallocated_encoding(s);
>          }
>          break;
> +    case 0x10:
> +        handle_adr(s, insn);
> +        break;
>      default:
>          unallocated_encoding(s);
>          break;
> 


Reply via email to