[PATCH 2/4] ARM: Thumb-2: Make undefined instruction handler support Thumb kernel code
Nicolas Pitre
nicolas.pitre at linaro.org
Mon Mar 21 20:56:23 UTC 2011
On Mon, 21 Mar 2011, Tixy wrote:
> On Mon, 2011-03-21 at 14:56 -0400, Nicolas Pitre wrote:
> > I'd suggest:
> >
> > insn = ((u16 *)pc)[0];
> > if (insn_is_wide(insn)) {
> > insn <<= 16;
> > insn |= ((u16 *)pc)[1];
> > }
> >
> > effectively using a big endian representation, but which is similar to
> > ARM mode instructions, and which would make sense regardless of the
> > instruction mode/width when printed.
>
> This is what I've done in the kprobe code that handles thumb, except
> that I've also shifted 16-bit thumb instructions into the top half.
> This was so we always know where the first half-word is and can test it
> for 16/32-bit size with "if(first_half<0xe800)".
>
> However, I've just realised that I didn't need to do this, with your
> example "if(inst<0xe800)" still works; so my other patches can be
> simplified :-)
Another reason to keep the 16-bit insn in the low half-word is to
simplify printing.
printk("instruction: 0x%04x\n", insn);
would display something sensible regardless of the mode or width (no
fancy spacing in the 32-bit Thumb2 case but that's not so bad).
> We could even just test the upper 16-bits for non-zero to indicate
> 32-bit. E.g. to store a thumb instruction:
>
> u16* pc = (u16 *)addr;
> u16 half = inst>>16;
> if (half)
> *pc++ = half;
> *pc++ = half&0xffff;
>
> which should compile to just three or four CPU instructions.
Indeed. And given the pointer is u16*, you may omit the 0xffff mask.
Nicolas
More information about the linaro-kernel
mailing list