diff options
author | Nick Clifton <nickc@redhat.com> | 2005-05-24 15:30:38 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2005-05-24 15:30:38 +0000 |
commit | 546aee7a22a519dca4d1efbcc33b0cb547328e35 (patch) | |
tree | c59ba95eab71da5e190c4e6840eb9214da9734a9 /sim/arm/thumbemu.c | |
parent | 18d59ab9dda96ae2c7c052466d20b1d3f6f61b10 (diff) | |
download | gdb-546aee7a22a519dca4d1efbcc33b0cb547328e35.zip gdb-546aee7a22a519dca4d1efbcc33b0cb547328e35.tar.gz gdb-546aee7a22a519dca4d1efbcc33b0cb547328e35.tar.bz2 |
(handle_v6_thumb_insn): New function.
(ARMul_ThumbDecode): Call handle_v6_thumb_insn() when an undefined instruction
binary is encountered.
Diffstat (limited to 'sim/arm/thumbemu.c')
-rw-r--r-- | sim/arm/thumbemu.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c index 0aa0f61..8707ca7 100644 --- a/sim/arm/thumbemu.c +++ b/sim/arm/thumbemu.c @@ -31,20 +31,74 @@ existing ARM simulator. */ #include "armemu.h" #include "armos.h" +/* Attempt to emulate an ARMv6 instruction. + Stores t_branch into PVALUE upon success or t_undefined otherwise. */ + +static void +handle_v6_thumb_insn (ARMul_State * state, + ARMword tinstr, + tdstate * pvalid) +{ + ARMword Rd; + ARMword Rm; + + if (! state->is_v6) + { + * pvalid = t_undefined; + return; + } + + switch (tinstr & 0xFFC0) + { + case 0xb660: /* cpsie */ + case 0xb670: /* cpsid */ + case 0x4600: /* cpy */ + case 0xba00: /* rev */ + case 0xba40: /* rev16 */ + case 0xbac0: /* revsh */ + case 0xb650: /* setend */ + default: + printf ("Unhandled v6 thumb insn: %04x\n", tinstr); + * pvalid = t_undefined; + return; + + case 0xb200: /* sxth */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + if (Rm & 0x8000) + state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000; + else + state->Reg [(tinstr & 0x7)] = Rm & 0xffff; + break; + case 0xb240: /* sxtb */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + if (Rm & 0x80) + state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00; + else + state->Reg [(tinstr & 0x7)] = Rm & 0xff; + break; + case 0xb280: /* uxth */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + state->Reg [(tinstr & 0x7)] = Rm & 0xffff; + break; + case 0xb2c0: /* uxtb */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + state->Reg [(tinstr & 0x7)] = Rm & 0xff; + break; + } + /* Indicate that the instruction has been processed. */ + * pvalid = t_branch; +} + /* Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions allows easier simulation of the special dual BL instruction. */ -tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr) - ARMul_State * - state; - ARMword - pc; - ARMword - tinstr; - ARMword * - ainstr; +tdstate +ARMul_ThumbDecode (ARMul_State * state, + ARMword pc, + ARMword tinstr, + ARMword * ainstr) { tdstate valid = t_decoded; /* default assumes a valid instruction */ ARMword next_instr; @@ -222,7 +276,7 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr) case 0x0: /* UNDEFINED */ case 0x4: /* UNDEFINED */ case 0x8: /* UNDEFINED */ - valid = t_undefined; + handle_v6_thumb_insn (state, tinstr, & valid); break; } } @@ -370,7 +424,7 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr) /* Drop through. */ default: /* Everything else is an undefined instruction. */ - valid = t_undefined; + handle_v6_thumb_insn (state, tinstr, & valid); break; } break; @@ -460,8 +514,9 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr) } valid = t_branch; } - else /* UNDEFINED : cc=1110(AL) uses different format */ - valid = t_undefined; + else + /* UNDEFINED : cc=1110(AL) uses different format. */ + handle_v6_thumb_insn (state, tinstr, & valid); break; case 28: /* B */ /* Format 18 */ @@ -476,7 +531,7 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr) { if (tinstr & 1) { - valid = t_undefined; + handle_v6_thumb_insn (state, tinstr, & valid); break; } /* Drop through. */ @@ -499,8 +554,10 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr) break; } } - valid = t_undefined; + + handle_v6_thumb_insn (state, tinstr, & valid); break; + case 30: /* BL instruction 1 */ /* Format 19 */ /* There is no single ARM instruction equivalent for this Thumb |