|
From: Tomonori Y. <ya...@fi...> - 2007-04-20 10:29:03
|
I am really happy to know that someone else started to work
on PA-RISC emulation on QEMU.
I have developed HP-UX user mode emulation
and found my interpreter is slow
and I am concerned the legality of running HP-UX application
on an emulated system. ( I need to copy HP-UX shared libraries
to run HP-UX applications.)
Aside from the legality, I am interested in the fast emulator.
Therefore I would like to know what I can do for your project.
I attached several patches as my self introduction.
I hope they may be some help.
- Tomonori Yamane
(1) First one (cpu.h) is a reorder of the PSW flags according to the
PA-RISC 1.1 Architecture and Instruction Set Reference Manual.
(This is just bitwise reverse.)
(2) The second one (op.c ) is corresponding modifications of
ssm/rsm/mtsm
(3) The third one (op.c) fixes idcor / dcor instruction from misuse
of ‘and’ operator.
(4) The fourth one (op.c) fixes op_shrpw_cc() in case of 32bit left
shift.
( I have stacked this problem for 2 months and I don’t want
you stack the same
problem.)
0x12345678 << 32 => 0 on HP-UX
0x12345678 << 32 => 0x12345678 on Linux/Pentium (No optimize)
0x12345678 << 32 => 0 on Linux/Pentium (Optimized)
*** cpu.h Fri Apr 20 15:47:22 2007
--- cpu.h.new Fri Apr 20 15:58:20 2007
***************
*** 68,104 ****
/* the shadow registers map to the following general registers */
// int shrmap[] = { 1, 6, 9, 16, 17, 24, 25 };
! #define PSW_Y 0x00000001
! #define PSW_Z 0x00000002
! #define PSW_W 0x00000010
! #define PSW_E 0x00000020
! #define PSW_S 0x00000040
! #define PSW_T 0x00000080
! #define PSW_H 0x00000100
! #define PSW_L 0x00000200
! #define PSW_N 0x00000400
! #define PSW_X 0x00000800
! #define PSW_B 0x00001000
! #define PSW_C 0x00002000
! #define PSW_V 0x00004000
! #define PSW_M 0x00008000
! #define PSW_CB 0x00ff0000
! #define PSW_CB0 0x00010000
! #define PSW_CB1 0x00020000
! #define PSW_CB2 0x00040000
! #define PSW_CB3 0x00080000
! #define PSW_CB4 0x00100000
! #define PSW_CB5 0x00200000
! #define PSW_CB6 0x00400000
! #define PSW_CB7 0x00800000
! #define PSW_O 0x01000000
! #define PSW_G 0x02000000
! #define PSW_F 0x04000000
! #define PSW_R 0x08000000
! #define PSW_Q 0x10000000
! #define PSW_P 0x20000000
! #define PSW_D 0x40000000
! #define PSW_I 0x80000000
#define PSW_CB7_SHIFT 8 /* CHECK */
--- 68,104 ----
/* the shadow registers map to the following general registers */
// int shrmap[] = { 1, 6, 9, 16, 17, 24, 25 };
! #define PSW_Y 0x80000000
! #define PSW_Z 0x40000000
! #define PSW_W 0x08000000
! #define PSW_E 0x04000000
! #define PSW_S 0x02000000
! #define PSW_T 0x01000000
! #define PSW_H 0x00800000
! #define PSW_L 0x00400000
! #define PSW_N 0x00200000
! #define PSW_X 0x00100000
! #define PSW_B 0x00080000
! #define PSW_C 0x00040000
! #define PSW_V 0x00020000
! #define PSW_M 0x00010000
! #define PSW_CB 0x0000ff00
! #define PSW_CB0 0x00008000
! #define PSW_CB1 0x00004000
! #define PSW_CB2 0x00002000
! #define PSW_CB3 0x00001000
! #define PSW_CB4 0x00000800
! #define PSW_CB5 0x00000400
! #define PSW_CB6 0x00000200
! #define PSW_CB7 0x00000100
! #define PSW_O 0x00000080
! #define PSW_G 0x00000040
! #define PSW_F 0x00000020
! #define PSW_R 0x00000010
! #define PSW_Q 0x00000008
! #define PSW_P 0x00000004
! #define PSW_D 0x00000002
! #define PSW_I 0x00000001
#define PSW_CB7_SHIFT 8 /* CHECK */
*** op.c Fri Apr 20 15:48:38 2007
--- op.c.new Fri Apr 20 18:25:10 2007
***************
*** 378,433 ****
void OPPROTO op_ssm(void)
{
! T0 = env->psw & (PSW_W | PSW_E | PSW_O | PSW_G | PSW_F | PSW_R
| PSW_Q | PSW_P | PSW_D | PSW_I);
if (PARAM1 & (1 << 0))
! env->psw |= PSW_W;
if (PARAM1 & (1 << 1))
! env->psw |= PSW_E;
if (PARAM1 & (1 << 2))
! env->psw |= PSW_O;
! if (PARAM1 & (1 << 3))
! env->psw |= PSW_G;
if (PARAM1 & (1 << 4))
- env->psw |= PSW_F;
- if (PARAM1 & (1 << 5))
env->psw |= PSW_R;
! if (PARAM1 & (1 << 7))
! env->psw |= PSW_P;
! if (PARAM1 & (1 << 8))
! env->psw |= PSW_D;
! if (PARAM1 & (1 << 9))
! env->psw |= PSW_I;
}
void OPPROTO op_rsm(void)
{
! T0 = env->psw & (PSW_W | PSW_E | PSW_O | PSW_G | PSW_F | PSW_R
| PSW_Q | PSW_P | PSW_D | PSW_I);
if (PARAM1 & (1 << 0))
! env->psw &= ~PSW_W;
if (PARAM1 & (1 << 1))
! env->psw &= ~PSW_E;
if (PARAM1 & (1 << 2))
! env->psw &= ~PSW_O;
! if (PARAM1 & (1 << 3))
! env->psw &= ~PSW_G;
if (PARAM1 & (1 << 4))
- env->psw &= ~PSW_F;
- if (PARAM1 & (1 << 5))
env->psw &= ~PSW_R;
! if (PARAM1 & (1 << 7))
! env->psw &= ~PSW_P;
! if (PARAM1 & (1 << 8))
! env->psw &= ~PSW_D;
! if (PARAM1 & (1 << 9))
! env->psw &= ~PSW_I;
}
void OPPROTO op_mtsm(void)
{
! env->psw = env->psw & ~(PSW_W | PSW_E | PSW_O | PSW_G | PSW_F
| PSW_R | PSW_Q | PSW_P | PSW_D | PSW_I);
! env->psw |= T0 & (PSW_W | PSW_E | PSW_O | PSW_G | PSW_F |
PSW_R | PSW_Q | PSW_P | PSW_D | PSW_I);
}
/* computation instructions... page 169 PA1.1 specification */
--- 378,421 ----
void OPPROTO op_ssm(void)
{
! T0 = env->psw & (PSW_G | PSW_F | PSW_R | PSW_Q | PSW_P | PSW_D
| PSW_I);
if (PARAM1 & (1 << 0))
! env->psw |= PSW_I;
if (PARAM1 & (1 << 1))
! env->psw |= PSW_D;
if (PARAM1 & (1 << 2))
! env->psw |= PSW_P;
if (PARAM1 & (1 << 4))
env->psw |= PSW_R;
! if (PARAM1 & (1 << 5))
! env->psw |= PSW_F;
! if (PARAM1 & (1 << 6))
! env->psw |= PSW_G;
}
void OPPROTO op_rsm(void)
{
! T0 = env->psw & (PSW_G | PSW_F | PSW_R | PSW_Q | PSW_P | PSW_D
| PSW_I);
if (PARAM1 & (1 << 0))
! env->psw &= ~PSW_I;
if (PARAM1 & (1 << 1))
! env->psw &= ~PSW_D;
if (PARAM1 & (1 << 2))
! env->psw &= ~PSW_P;
if (PARAM1 & (1 << 4))
env->psw &= ~PSW_R;
! if (PARAM1 & (1 << 5))
! env->psw &= ~PSW_F;
! if (PARAM1 & (1 << 6))
! env->psw &= ~PSW_G;
}
void OPPROTO op_mtsm(void)
{
! env->psw = env->psw & ~(PSW_G | PSW_F | PSW_R | PSW_Q | PSW_P
| PSW_D | PSW_I);
! env->psw |= T0 & (PSW_G | PSW_F | PSW_R | PSW_Q | PSW_P |
PSW_D | PSW_I);
}
/* computation instructions... page 169 PA1.1 specification */
***************
*** 685,710 ****
void OPPROTO op_dcor_T0(void)
{
! T0 -= (((0x6 * (1 - (env->psw & PSW_CB7))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB6))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB5))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB4))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB3))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB2))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB1))) << 4) |
! (((0x6 * (1 - (env->psw & PSW_CB0))))))))))));
}
void OPPROTO op_idcor_T0(void)
{
! T0 += (((0x6 * (env->psw & PSW_CB7)) << 4) |
! (((0x6 * (env->psw & PSW_CB6)) << 4) |
! (((0x6 * (env->psw & PSW_CB5)) << 4) |
! (((0x6 * (env->psw & PSW_CB4)) << 4) |
! (((0x6 * (env->psw & PSW_CB3)) << 4) |
! (((0x6 * (env->psw & PSW_CB2)) << 4) |
! (((0x6 * (env->psw & PSW_CB1)) << 4) |
! (((0x6 * (env->psw & PSW_CB0)))))))))));
}
/* Shift/deposit insns */
--- 673,698 ----
void OPPROTO op_dcor_T0(void)
{
! T0 -= (((0x6 * ((env->psw & PSW_CB7)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB6)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB5)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB4)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB3)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB2)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB1)?0:1)) << 4) |
! (((0x6 * ((env->psw & PSW_CB0)?0:1)))))))))));
}
void OPPROTO op_idcor_T0(void)
{
! T0 += (((0x6 * ((env->psw & PSW_CB7)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB6)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB5)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB4)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB3)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB2)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB1)?1:0)) << 4) |
! (((0x6 * ((env->psw & PSW_CB0)?1:0)))))))))));
}
/* Shift/deposit insns */
***************
*** 713,718 ****
--- 701,714 ----
/* INPUT: T0 = shift amount, T1 and T2 = register pair values
*/
/* OUTPUT: T0 */
T0 &= 0x1f;
+ /*
+ Workaround for the following problem
+
+ 0x12345678 << 32 = 0 on HP-UX
+ 0x12345678 << 32 = 0x12345678 on Linux/x86 (No
optimization)
+ 0x12345678 << 32 = 0 on Linux/x86 (Optimized)
+ */
+ if (TO == 0) { TO = T2; } else
T0 = (T1 << (32 - T0)) | (T2 >> T0);
}
|