target-mips: fix incorrect behaviour for INSV
Corner case for INSV instruction when size=32 has not been correctly implemented. The mask for size should be one bit wider, and preparing the filter variable should be aware of this case too. The test for INSV has been extended to include the case that triggers the bug. Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
639eadb9a3
commit
c0f5f9ce86
@ -2921,7 +2921,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
|
||||
return rt; \
|
||||
} \
|
||||
\
|
||||
filter = ((int32_t)0x01 << size) - 1; \
|
||||
filter = ((int64_t)0x01 << size) - 1; \
|
||||
filter = filter << pos; \
|
||||
temprs = (rs << pos) & filter; \
|
||||
temprt = rt & ~filter; \
|
||||
@ -2930,7 +2930,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
|
||||
return (target_long)(ret_type)temp; \
|
||||
}
|
||||
|
||||
BIT_INSV(insv, 0x1F, 0x1F, int32_t);
|
||||
BIT_INSV(insv, 0x1F, 0x3F, int32_t);
|
||||
#ifdef TARGET_MIPS64
|
||||
BIT_INSV(dinsv, 0x7F, 0x3F, target_long);
|
||||
#endif
|
||||
|
@ -19,5 +19,18 @@ int main()
|
||||
);
|
||||
assert(rt == result);
|
||||
|
||||
dsp = 0x1000;
|
||||
rt = 0xF0F0F0F0;
|
||||
rs = 0xA5A5A5A5;
|
||||
result = 0xA5A5A5A5;
|
||||
|
||||
__asm
|
||||
("wrdsp %2\n\t"
|
||||
"insv %0, %1\n\t"
|
||||
: "+r"(rt)
|
||||
: "r"(rs), "r"(dsp)
|
||||
);
|
||||
assert(rt == result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user