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); } |