Re: [Qemu-devel] [PATCH] linux-user, fix getgroups/getgroups32 when both args are zero.

2008-02-23 Thread Takashi Yoshii
Hi,

 My version of patch to fix same problem:
Oh, yes. You are right.
I have read manpage again, and I found it says,
  if size is zero, list is not modified, but ...
So, mine is wrong. We should check only size.
/yoshii




[Qemu-devel] [PATCH] SH4,linux-user, Add pipe syscall support.

2008-02-22 Thread Takashi Yoshii
This one should be applied to run sh4-linux userland. /yoshii
---
add handling of return values of pipe syscall for SH4.

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3514,6 +3514,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
env-gpr[env-current_tc][3] = host_pipe[1];
ret = host_pipe[0];
+#elif defined(TARGET_SH4)
+   ((CPUSH4State*)cpu_env)-gregs[1] = host_pipe[1];
+   ret = host_pipe[0];
 #else
 if (put_user_s32(host_pipe[0], arg1)
 || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))




[Qemu-devel] [PATCH] linux-user, fix getgroups/getgroups32 when both args are zero.

2008-02-22 Thread Takashi Yoshii
getgroups() and getgroups32() returns NGROUPS_MAX when both its two args are
zero. But because we pass a ptr to allocated space as 2nd arg, this function
are interfered. The patch attached fixed it.
/yoshii
---
linux-user/syscall.c: fix getgroups{,32} when both args are zero.

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5185,7 +5185,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
 break;
 case TARGET_NR_getgroups:
-{
+if (arg1 == 0  arg2 == 0)
+ret = get_errno(getgroups(0, 0));
+else {
 int gidsetsize = arg1;
 uint16_t *target_grouplist;
 gid_t *grouplist;
@@ -5335,7 +5337,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_getgroups32
 case TARGET_NR_getgroups32:
-{
+if (arg1 == 0  arg2 == 0)
+ret = get_errno(getgroups(0, 0));
+else {
 int gidsetsize = arg1;
 uint32_t *target_grouplist;
 gid_t *grouplist;




[Qemu-devel] [PATCH] SH4, fix several instructions.

2008-02-21 Thread Takashi Yoshii
Hi,

I succeeded to build system set of packages on Gentoo Linux, which is
a small root filesystem with toolchain(because it is essential for Gentoo),
inside a chroot environment with qemu-linux-user emu.

Several instructions for sh4 need to be fixed/added.
Some fixes and workarounds are needed in other part of qemu, too.
# Some seems to be too dirty to be merged, though.

Anyway, with a patch attached, {op,translate}.c are functional enough 
 to run userland. Please apply.

I found some optimization for code can be done, but maybe later.
I believe we need a formal test for all instructions, first.
But it looks a long way(,and I'm lazy:). Any idea?

/yoshii
---

fix instruction code for frchg, fschg, ocbp.
fix addressing mode handling for @Rn+, @-Rn, @(disp,gbr).
fix operation for div0s.
fix comments for mov imm, add imm, @(r0+,gbr), mac.l @Rm+,@Rn+.
fix ldb to ldub for or/tst/xor.b #imm,@(r0,gbr).
add fmov extended operations.
add fcmp/eq, fcmp/gt, fneg, fabs, fsqrt, fcnvsd, fcnvds.

diff --git a/target-sh4/op.c b/target-sh4/op.c
index 955610a..615d30a 100644
--- a/target-sh4/op.c
+++ b/target-sh4/op.c
@@ -45,13 +45,7 @@ void OPPROTO op_movl_imm_T0(void)
 
 void OPPROTO op_movl_imm_T1(void)
 {
-T0 = (uint32_t) PARAM1;
-RETURN();
-}
-
-void OPPROTO op_movl_imm_T2(void)
-{
-T0 = (uint32_t) PARAM1;
+T1 = (uint32_t) PARAM1;
 RETURN();
 }
 
@@ -240,6 +234,12 @@ void OPPROTO op_xtrct_T0_T1(void)
 RETURN();
 }
 
+void OPPROTO op_add_T0_T1(void)
+{
+T1 += T0;
+RETURN();
+}
+
 void OPPROTO op_addc_T0_T1(void)
 {
 helper_addc_T0_T1();
@@ -355,13 +355,13 @@ void OPPROTO op_mull_T0_T1(void)
 
 void OPPROTO op_mulsw_T0_T1(void)
 {
-env-macl = (int32_t) T0 *(int32_t) T1;
+env-macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
 RETURN();
 }
 
 void OPPROTO op_muluw_T0_T1(void)
 {
-env-macl = (uint32_t) T0 *(uint32_t) T1;
+env-macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
 RETURN();
 }
 
@@ -382,7 +382,7 @@ void OPPROTO op_shad_T0_T1(void)
 if ((T0  0x8000) == 0)
T1 = (T0  0x1f);
 else if ((T0  0x1f) == 0)
-   T1 = 0;
+   T1 = (T1  0x8000)? 0x : 0;
 else
T1 = ((int32_t) T1)  ((~T0  0x1f) + 1);
 RETURN();
@@ -539,7 +539,7 @@ void OPPROTO op_shal_Rn(void)
 void OPPROTO op_shar_Rn(void)
 {
 cond_t(env-gregs[PARAM1]  1);
-env-gregs[PARAM1] = 1;
+*(int32_t *)env-gregs[PARAM1] = 1;
 RETURN();
 }
 
@@ -767,6 +767,30 @@ void OPPROTO op_fdiv_DT(void)
 RETURN();
 }
 
+void OPPROTO op_fcmp_eq_FT(void)
+{
+cond_t(float32_compare(FT0, FT1, env-fp_status) == 0);
+RETURN();
+}
+
+void OPPROTO op_fcmp_eq_DT(void)
+{
+cond_t(float64_compare(DT0, DT1, env-fp_status) == 0);
+RETURN();
+}
+
+void OPPROTO op_fcmp_gt_FT(void)
+{
+cond_t(float32_compare(FT0, FT1, env-fp_status) == 1);
+RETURN();
+}
+
+void OPPROTO op_fcmp_gt_DT(void)
+{
+cond_t(float64_compare(DT0, DT1, env-fp_status) == 1);
+RETURN();
+}
+
 void OPPROTO op_float_FT(void)
 {
 FT0 = int32_to_float32(env-fpul, env-fp_status);
@@ -791,9 +815,51 @@ void OPPROTO op_ftrc_DT(void)
 RETURN();
 }
 
+void OPPROTO op_fneg_frN(void)
+{
+env-fregs[PARAM1] = float32_chs(env-fregs[PARAM1]);
+RETURN();
+}
+
+void OPPROTO op_fabs_FT(void)
+{
+FT0 = float32_abs(FT0);
+RETURN();
+}
+
+void OPPROTO op_fabs_DT(void)
+{
+DT0 = float64_abs(DT0);
+RETURN();
+}
+
+void OPPROTO op_fcnvsd_FT_DT(void)
+{
+DT0 = float32_to_float64(FT0, env-fp_status);
+RETURN();
+}
+
+void OPPROTO op_fcnvds_DT_FT(void)
+{
+FT0 = float64_to_float32(DT0, env-fp_status);
+RETURN();
+}
+
+void OPPROTO op_fsqrt_FT(void)
+{
+FT0 = float32_sqrt(FT0, env-fp_status);
+RETURN();
+}
+
+void OPPROTO op_fsqrt_DT(void)
+{
+DT0 = float64_sqrt(DT0, env-fp_status);
+RETURN();
+}
+
 void OPPROTO op_fmov_T0_frN(void)
 {
-*(unsigned int *)env-fregs[PARAM1] = T0;
+*(uint32_t *)env-fregs[PARAM1] = T0;
 RETURN();
 }
 
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 0c66e0b..0aacc98 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -268,11 +268,11 @@ void _decode_opc(DisasContext * ctx)
 case 0x0018:   /* sett */
gen_op_sett();
return;
-case 0xfbfb:   /* frchg */
+case 0xfbfd:   /* frchg */
gen_op_frchg();
ctx-bstate = BS_STOP;
return;
-case 0xf3fb:   /* fschg */
+case 0xf3fd:   /* fschg */
gen_op_fschg();
ctx-bstate = BS_STOP;
return;
@@ -296,7 +296,7 @@ void _decode_opc(DisasContext * ctx)
gen_op_ldl_T0_T0(ctx);
gen_op_movl_T0_rN(REG(B11_8));
return;
-case 0xe000:   /* mov.l #imm,Rn */
+case 0xe000:   /* mov #imm,Rn */
gen_op_movl_imm_rN(B7_0s, REG(B11_8));
return;
 case 0x9000:   /* mov.w 

[Qemu-devel] [PATCH] linux-user, Add missing break just before execve.

2007-12-11 Thread Takashi Yoshii
Small patch around execve again.
Now unlinkat() goes through into execve. Here is the fix.
/yoshii

diff -u -p -r1.157 syscall.c
--- a/linux-user/syscall.c  9 Dec 2007 23:12:55 -   1.157
+++ b/linux-user/syscall.c  11 Dec 2007 17:02:11 -
@@ -3177,6 +3176,7 @@ abi_long do_syscall(void *cpu_env, int n
 goto efault;
 ret = get_errno(sys_unlinkat(arg1, p, arg3));
 unlock_user(p, arg2, 0);
+break;
 #endif
 case TARGET_NR_execve:
 {




[Qemu-devel] [PATCH] SH4, Add more float instructions.

2007-12-11 Thread Takashi Yoshii
Hi,
I found some instructions missing on SH4, and added some.
Graphics extentions(like sin/cos/sqrt/vector op) are still missing,
 but I believe no one need them, at least, so far.

fneg is implemented as 32bit op, according to the programming manual.
/yoshii

diff -u -p -r1.10 op.c
--- a/target-sh4/op.c   2 Dec 2007 06:18:24 -   1.10
+++ b/target-sh4/op.c   11 Dec 2007 17:24:31 -
@@ -797,6 +797,36 @@ void OPPROTO op_ftrc_DT(void)
 RETURN();
 }
 
+void OPPROTO op_fneg_frN(void)
+{
+env-fregs[PARAM1] = float32_chs(env-fregs[PARAM1]);
+RETURN();
+}
+
+void OPPROTO op_fabs_FT(void)
+{
+FT0 = float32_abs(FT0);
+RETURN();
+}
+
+void OPPROTO op_fabs_DT(void)
+{
+DT0 = float64_abs(DT0);
+RETURN();
+}
+
+void OPPROTO op_fcnvsd_DT(void)
+{
+DT0 = float32_to_float64(env-fpul, env-fp_status);
+RETURN();
+}
+
+void OPPROTO op_fcnvds_DT(void)
+{
+env-fpul = float64_to_float32(DT0, env-fp_status);
+RETURN();
+}
+
 void OPPROTO op_fmov_T0_frN(void)
 {
 *(unsigned int *)env-fregs[PARAM1] = T0;
diff -u -p -r1.21 translate.c
--- a/target-sh4/translate.c2 Dec 2007 06:10:04 -   1.21
+++ b/target-sh4/translate.c11 Dec 2007 17:24:31 -
@@ -1123,6 +1123,23 @@ void _decode_opc(DisasContext * ctx)
gen_op_ftrc_FT();
}
return;
+case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
+   gen_op_fneg_frN(FREG(B11_8));
+   return;
+case 0xf05d: /* fabs FRn/DRn */
+   if (ctx-fpscr  FPSCR_PR) {
+   if (ctx-opcode  0x0100)
+   break; /* illegal instruction */
+   gen_op_fmov_drN_DT0(DREG(B11_8));
+   gen_op_fabs_DT();
+   gen_op_fmov_DT0_drN(DREG(B11_8));
+   }
+   else {
+   gen_op_fmov_frN_FT0(FREG(B11_8));
+   gen_op_fabs_FT();
+   gen_op_fmov_FT0_frN(FREG(B11_8));
+   }
+   return;
 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
if (!(ctx-fpscr  FPSCR_PR)) {
gen_op_movl_imm_T0(0);
@@ -1137,6 +1154,14 @@ void _decode_opc(DisasContext * ctx)
return;
}
break;
+case 0xf0ad: /* cnvsd FPUL,DRn */
+   gen_op_fcnvsd_DT();
+   gen_op_fmov_DT0_drN(DREG(B11_8));
+   return;
+case 0xf0bd: /* cnvds DRn,FPUL */
+   gen_op_fmov_drN_DT0(DREG(B11_8));
+   gen_op_fcnvds_DT();
+   return;
 }
 
 fprintf(stderr, unknown instruction 0x%04x at pc 0x%08x\n,




[Qemu-devel] [PATCH] linux-user, Fix execve argc/envc counting.

2007-12-09 Thread Takashi Yoshii
In execve code for linux-user emulation, address increment steps seems to be 
wrong when counting argc/envc. 
/yoshii

Index: linux-user/syscall.c
===
RCS file: /sources/qemu/qemu/linux-user/syscall.c,v
retrieving revision 1.156
diff -u -p -r1.156 syscall.c
--- a/linux-user/syscall.c  9 Dec 2007 02:37:05 -   1.156
+++ b/linux-user/syscall.c  9 Dec 2007 20:44:05 -
@@ -3190,7 +3189,7 @@ abi_long do_syscall(void *cpu_env, int n
 
 argc = 0;
 guest_argp = arg2;
-for (gp = guest_argp; ; gp++) {
+for (gp = guest_argp; ; gp += sizeof(abi_ulong)) {
 if (get_user_ual(addr, gp))
 goto efault;
 if (!addr)
@@ -3199,7 +3198,7 @@ abi_long do_syscall(void *cpu_env, int n
 }
 envc = 0;
 guest_envp = arg3;
-for (gp = guest_envp; ; gp++) {
+for (gp = guest_envp; ; gp += sizeof(abi_ulong)) {
 if (get_user_ual(addr, gp))
 goto efault;
 if (!addr)