mirror of https://gitee.com/openkylin/qemu.git
When targeting PPU use rlwinm instead of andi. if possible
andi. is microcoded and slow there. Signed-off-by: malc <av1474@comtv.ru>
This commit is contained in:
parent
b3d6fb4a6a
commit
c45851c44a
|
@ -1253,14 +1253,60 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
|
|||
|
||||
case INDEX_op_and_i32:
|
||||
if (const_args[2]) {
|
||||
if ((args[2] & 0xffff) == args[2])
|
||||
tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
|
||||
else if ((args[2] & 0xffff0000) == args[2])
|
||||
tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
|
||||
| ((args[2] >> 16) & 0xffff));
|
||||
else {
|
||||
tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
|
||||
tcg_out32 (s, AND | SAB (args[1], args[0], 0));
|
||||
uint32_t c;
|
||||
|
||||
c = args[2];
|
||||
|
||||
if (!c) {
|
||||
tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
|
||||
break;
|
||||
}
|
||||
#ifdef __PPU__
|
||||
uint32_t t, n;
|
||||
int mb, me;
|
||||
|
||||
n = c ^ -(c & 1);
|
||||
t = n + (n & -n);
|
||||
|
||||
if ((t & (t - 1)) == 0) {
|
||||
int lzc, tzc;
|
||||
|
||||
if ((c & 0x80000001) == 0x80000001) {
|
||||
lzc = clz32 (n);
|
||||
tzc = ctz32 (n);
|
||||
|
||||
mb = 32 - tzc;
|
||||
me = lzc - 1;
|
||||
}
|
||||
else {
|
||||
lzc = clz32 (c);
|
||||
tzc = ctz32 (c);
|
||||
|
||||
mb = lzc;
|
||||
me = 31 - tzc;
|
||||
}
|
||||
|
||||
tcg_out32 (s, (RLWINM
|
||||
| RA (args[0])
|
||||
| RS (args[1])
|
||||
| SH (0)
|
||||
| MB (mb)
|
||||
| ME (me)
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
#endif /* !__PPU__ */
|
||||
{
|
||||
if ((c & 0xffff) == c)
|
||||
tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | c);
|
||||
else if ((c & 0xffff0000) == c)
|
||||
tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
|
||||
| ((c >> 16) & 0xffff));
|
||||
else {
|
||||
tcg_out_movi (s, TCG_TYPE_I32, 0, c);
|
||||
tcg_out32 (s, AND | SAB (args[1], args[0], 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue