From 6240d4121cc66491d3c5a587eb970edc7560422d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 24 May 2005 15:30:38 +0000 Subject: (handle_v6_thumb_insn): New function. (ARMul_ThumbDecode): Call handle_v6_thumb_insn() when an undefined instruction binary is encountered. --- sim/arm/ChangeLog | 6 ++++ sim/arm/thumbemu.c | 87 ++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 78 insertions(+), 15 deletions(-) (limited to 'sim') diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog index 1402584609b..e79141698aa 100644 --- a/sim/arm/ChangeLog +++ b/sim/arm/ChangeLog @@ -1,3 +1,9 @@ +2005-05-24 Nick Clifton + + * thumbemu.c (handle_v6_thumb_insn): New function. + (ARMul_ThumbDecode): Call handle_v6_thumb_insn() when an undefined + instruction binary is encountered. + 2005-05-12 Nick Clifton * Update the address and phone number of the FSF organization in diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c index 0aa0f61fed0..8707ca71a64 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 -- cgit v1.2.1