mips32: Add support for mips32 DSP instruction set.

Add support for mips32 DSP and DSP revision 2 ASE.
More details about the mips32 DSP(r2) ASE:
http://www.mips.com/media/files/MD00566-2B-MIPSDSP-QRC-01.00.pdf
Applied patch provided by Maja Gagic <maja.gagic@rt-rk.com>



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13470
This commit is contained in:
Dejan Jevtic 2013-07-25 08:22:08 +00:00
parent 4c9052b4d6
commit 78ae0356c4
4 changed files with 122 additions and 3 deletions

View File

@ -444,6 +444,58 @@ __asm__(
#endif /* VGP_x86_linux || VGP_x86_darwin */
#if defined(VGP_mips32_linux)
__asm__(
".text \n\t"
".globl VG_MINIMAL_SETJMP; \n\t"
".align 2; \n\t"
"VG_MINIMAL_SETJMP: \n\t" /* a0 = jmp_buf */
" sw $s0, 0($a0) \n\t" /* Save registers s0-s7. */
" sw $s1, 4($a0) \n\t"
" sw $s2, 8($a0) \n\t"
" sw $s3, 12($a0) \n\t"
" sw $s4, 16($a0) \n\t"
" sw $s5, 20($a0) \n\t"
" sw $s6, 24($a0) \n\t"
" sw $s7, 28($a0) \n\t"
" sw $s8, 32($a0) \n\t" /* Frame pointer. */
" sw $ra, 36($a0) \n\t" /* Return address. */
" sw $gp, 40($a0) \n\t" /* Global data pointer. */
" sw $sp, 44($a0) \n\t" /* Stack pointer. */
" move $v0, $zero \n\t" /* Return zero. */
" j $ra \n\t"
" nop \n\t"
".end VG_MINIMAL_SETJMP; \n\t"
" \n\t"
".globl VG_MINIMAL_LONGJMP; \n\t"
".align 2; \n\t"
"VG_MINIMAL_LONGJMP: \n\t" /* a0 = jmp_buf */
" lw $s0, 0($a0) \n\t" /* Restore registers s0-s7. */
" lw $s1, 4($a0) \n\t"
" lw $s2, 8($a0) \n\t"
" lw $s3, 12($a0) \n\t"
" lw $s4, 16($a0) \n\t"
" lw $s5, 20($a0) \n\t"
" lw $s6, 24($a0) \n\t"
" lw $s7, 28($a0) \n\t"
" lw $s8, 32($a0) \n\t" /* Frame pointer. */
" lw $ra, 36($a0) \n\t" /* Return address. */
" lw $gp, 40($a0) \n\t" /* Global data pointer. */
" lw $sp, 44($a0) \n\t" /* Stack pointer. */
/* Checking whether second argument is zero. */
" bnez $a1, 1f \n\t"
" nop \n\t"
" addi $a1, $a1, 1 \n\t" /* We must return 1 if val=0. */
"1: \n\t"
" move $v0, $a1 \n\t" /* Return value of second argument. */
" j $ra \n\t"
".end VG_MINIMAL_SETJMP; \n\t"
);
#endif /* VGP_mips32_linux */
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/

View File

@ -444,7 +444,7 @@ Int VG_(machine_arm_archlevel) = 4;
/* For hwcaps detection on ppc32/64, s390x, and arm we'll need to do SIGILL
testing, so we need a VG_MINIMAL_JMP_BUF. */
#if defined(VGA_ppc32) || defined(VGA_ppc64) \
|| defined(VGA_arm) || defined(VGA_s390x)
|| defined(VGA_arm) || defined(VGA_s390x) || defined(VGA_mips32)
#include "pub_tool_libcsetjmp.h"
static VG_MINIMAL_JMP_BUF(env_unsup_insn);
static void handler_unsup_insn ( Int x ) {
@ -1400,11 +1400,63 @@ Bool VG_(machine_get_hwcaps)( void )
{
va = VexArchMIPS32;
UInt model = VG_(get_machine_model)();
if (model== -1)
if (model == -1)
return False;
vai.hwcaps = model;
/* Same instruction set detection algorithm as for ppc32/arm... */
vki_sigset_t saved_set, tmp_set;
vki_sigaction_fromK_t saved_sigill_act;
vki_sigaction_toK_t tmp_sigill_act;
volatile Bool have_DSP, have_DSPr2;
Int r;
vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
VG_(sigemptyset)(&tmp_set);
VG_(sigaddset)(&tmp_set, VKI_SIGILL);
r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
vg_assert(r == 0);
r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
vg_assert(r == 0);
tmp_sigill_act = saved_sigill_act;
/* NODEFER: signal handler does not return (from the kernel's point of
view), hence if it is to successfully catch a signal more than once,
we need the NODEFER flag. */
tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
tmp_sigill_act.ksa_handler = handler_unsup_insn;
VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
/* DSP instructions. */
have_DSP = True;
if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
have_DSP = False;
} else {
__asm__ __volatile__(".word 0x7c3f44b8"); /* rddsp t0, 0x3f */
}
/* DSPr2 instructions. */
have_DSPr2 = True;
if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
have_DSPr2 = False;
} else {
__asm__ __volatile__(".word 0x7d095351"); /* precr.qb.ph t2, t0, t1 */
}
VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act);
VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
if (have_DSP) vai.hwcaps |= VEX_MIPS_ASE_DSP;
if (have_DSPr2) vai.hwcaps |= VEX_MIPS_ASE_DSP2P;
VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps);
VG_(machine_get_cache_info)(&vai);
return True;

View File

@ -108,6 +108,13 @@ __attribute__((noreturn))
__attribute__((regparm(1))) // ditto
void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
#elif defined(VGP_mips32_linux)
#define VG_MINIMAL_JMP_BUF(_name) UInt _name [8+1+1+1+1]
__attribute__((returns_twice))
UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
__attribute__((noreturn))
void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
#else

View File

@ -1060,7 +1060,15 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
if (o >= GOF(f30) && o+sz <= GOF(f30)+SZB(f30)) return GOF(f30);
if (o >= GOF(f31) && o+sz <= GOF(f31)+SZB(f31)) return GOF(f31);
if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1; /*padding registers*/
/* Slot unused. */
if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1;
/* MIPS32 DSP ASE(r2) specific registers. */
if (o == GOF(DSPControl) && sz == 4) return o;
if (o == GOF(ac0) && sz == 8) return o;
if (o == GOF(ac1) && sz == 8) return o;
if (o == GOF(ac2) && sz == 8) return o;
if (o == GOF(ac3) && sz == 8) return o;
VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
offset,szB);