* [Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support
@ 2011-08-15 11:25 khansa
2011-08-15 11:25 ` [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU khansa
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: khansa @ 2011-08-15 11:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, riku.voipio, Khansa Butt, aurelien
From: Khansa Butt <khansa@kics.edu.pk>
This is the team work of Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt
from HPCN Lab KICS UET Lahore.
Cavium Networks's Octeon processors are based on MIPS64r2
We have Implemented 27 user mode Cavium specific instructions.
Richard Henderson told me that QEMU does not support 64-bit
address spaces in user mode from a 32-bit host. so this code will work
only on 64 bit host. Although we did some workaround to run MIPS64 on 32 x86
and it can be generlized for other architectures. We will submit that after this
submission. This development work is tested for 64 bit X86 and working fine
all Cavium specific instructions are also tested. teast cases can be provided if required.
Octeon binaries (ELF) can be downloaded from below links
1)http://dl.dropbox.com/u/19530066/hw_mips
2)http://dl.dropbox.com/u/19530066/matmul
If you have any objection regarding the Implementation of
Cavium instructions please read following notes.
Notes
*****
The detail of some instructions are as follows
1)seq rd,rs,rt
seq-->rd = 1 if rs = rt
is equivalent to
xor rd,rs,rt
sltiu rd,rd,1
2)exts rt,rs,p,lenm1
rt = sign-extend(rs<p+lenm1:p>,lenm1)
>From reference manual of Cavium Networks
"Bit locations p + lenm1 to p are extracted from rs and the result is written into the
lowest bits of destination register rt. The remaining bits in rt are a sign-extension of
the most-significant bit of the bit field (i.e. rt<63:lenm1> are all duplicates of the
source-register bit rs<p+lenm1>)." so we can't use any of 8,16 or 32 bit
sign extention tcg function. To sign extend according to msb of bit field
we have our own implementation
3)dmul rd,rs,rt
This instruction is included in gen_arith() because it is three operand
double word multiply instruction.
--
1.7.3.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU
2011-08-15 11:25 [Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support khansa
@ 2011-08-15 11:25 ` khansa
2011-08-15 15:32 ` Richard Henderson
2011-08-15 11:25 ` [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall khansa
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: khansa @ 2011-08-15 11:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, riku.voipio, Khansa Butt, aurelien
From: Khansa Butt <khansa@kics.edu.pk>
Signed-off-by: Khansa Butt <khansa@kics.edu.pk>
---
configure | 1 +
default-configs/mips64-linux-user.mak | 1 +
linux-user/main.c | 21 +++++++++++++++++++--
linux-user/mips64/syscall.h | 2 ++
linux-user/signal.c | 2 --
5 files changed, 23 insertions(+), 4 deletions(-)
create mode 100644 default-configs/mips64-linux-user.mak
diff --git a/configure b/configure
index 0c67a4a..14a1f58 100755
--- a/configure
+++ b/configure
@@ -884,6 +884,7 @@ m68k-linux-user \
microblaze-linux-user \
microblazeel-linux-user \
mips-linux-user \
+mips64-linux-user \
mipsel-linux-user \
ppc-linux-user \
ppc64-linux-user \
diff --git a/default-configs/mips64-linux-user.mak b/default-configs/mips64-linux-user.mak
new file mode 100644
index 0000000..1598bfc
--- /dev/null
+++ b/default-configs/mips64-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for mips64-linux-user
diff --git a/linux-user/main.c b/linux-user/main.c
index 8e15474..8f14605 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2068,7 +2068,8 @@ static int do_store_exclusive(CPUMIPSState *env)
void cpu_loop(CPUMIPSState *env)
{
target_siginfo_t info;
- int trapnr, ret;
+ int trapnr;
+ abi_long ret;
unsigned int syscall_num;
for(;;) {
@@ -2077,8 +2078,23 @@ void cpu_loop(CPUMIPSState *env)
cpu_exec_end(env);
switch(trapnr) {
case EXCP_SYSCALL:
- syscall_num = env->active_tc.gpr[2] - 4000;
env->active_tc.PC += 4;
+#if defined(TARGET_MIPS64)
+ syscall_num = env->active_tc.gpr[2] - 5000;
+ /* MIPS64 has eight argument registers so there is
+ * no need to get arguments from stack
+ */
+ ret = do_syscall(env, env->active_tc.gpr[2],
+ env->active_tc.gpr[4],
+ env->active_tc.gpr[5],
+ env->active_tc.gpr[6],
+ env->active_tc.gpr[7],
+ env->active_tc.gpr[8],
+ env->active_tc.gpr[9],
+ env->active_tc.gpr[10],
+ env->active_tc.gpr[11]);
+#else
+ syscall_num = env->active_tc.gpr[2] - 4000;
if (syscall_num >= sizeof(mips_syscall_args)) {
ret = -TARGET_ENOSYS;
} else {
@@ -2105,6 +2121,7 @@ void cpu_loop(CPUMIPSState *env)
env->active_tc.gpr[7],
arg5, arg6, arg7, arg8);
}
+#endif
if (ret == -TARGET_QEMU_ESIGRETURN) {
/* Returning from a successful sigreturn syscall.
Avoid clobbering register state. */
diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h
index 668a2b9..96f03da 100644
--- a/linux-user/mips64/syscall.h
+++ b/linux-user/mips64/syscall.h
@@ -218,4 +218,6 @@ struct target_pt_regs {
+#define TARGET_QEMU_ESIGRETURN 255
+
#define UNAME_MACHINE "mips64"
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 07ad07a..b23922d 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2415,8 +2415,6 @@ void sparc64_get_context(CPUSPARCState *env)
#endif
#elif defined(TARGET_ABI_MIPSN64)
-# warning signal handling not implemented
-
static void setup_frame(int sig, struct target_sigaction *ka,
target_sigset_t *set, CPUState *env)
{
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall
2011-08-15 11:25 [Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support khansa
2011-08-15 11:25 ` [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU khansa
@ 2011-08-15 11:25 ` khansa
2011-08-15 15:43 ` Richard Henderson
2011-08-15 11:25 ` [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions khansa
2011-08-15 11:25 ` [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler khansa
3 siblings, 1 reply; 13+ messages in thread
From: khansa @ 2011-08-15 11:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, riku.voipio, Khansa Butt, aurelien
From: Khansa Butt <khansa@kics.edu.pk>
Signed-off-by: Khansa Butt <khansa@kics.edu.pk>
---
linux-user/syscall.c | 5 +++++
target-mips/mips-defs.h | 2 ++
target-mips/translate_init.c | 24 ++++++++++++++++++++++++
3 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 73f9baa..90ace4b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7653,6 +7653,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_set_thread_area:
#if defined(TARGET_MIPS)
((CPUMIPSState *) cpu_env)->tls_value = arg1;
+ if (((CPUMIPSState *) cpu_env)->insn_flags & CPU_OCTEON) {
+ /* tls entry is moved to k0 so that this can be used later
+ currently this thing is tested only for Octeon */
+ ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
+ }
ret = 0;
break;
#elif defined(TARGET_CRIS)
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index bf094a3..e1ec2b2 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -41,6 +41,7 @@
#define ASE_MICROMIPS 0x00080000
/* Chip specific instructions. */
+#define INSN_OCTEON 0x10000000
#define INSN_LOONGSON2E 0x20000000
#define INSN_LOONGSON2F 0x40000000
#define INSN_VR54XX 0x80000000
@@ -53,6 +54,7 @@
#define CPU_VR54XX (CPU_MIPS4 | INSN_VR54XX)
#define CPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E)
#define CPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F)
+#define CPU_OCTEON (CPU_MIPS64R2 | INSN_OCTEON)
#define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5)
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index d55c522..7d7e1e9 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -451,6 +451,30 @@ static const mips_def_t mips_defs[] =
.mmu_type = MMU_TYPE_R4000,
},
{
+ .name = "octeon",
+ .CP0_PRid = 0x0d30,
+ .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
+ (MMU_TYPE_R4000 << CP0C0_MT),
+ .CP0_Config1 = MIPS_CONFIG1 | (63 << CP0C1_MMU) |
+ (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
+ (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
+ (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+ .CP0_Config2 = MIPS_CONFIG2,
+ .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
+ .CP0_LLAddr_rw_bitmask = 0,
+ .CP0_LLAddr_shift = 0,
+ .SYNCI_Step = 32,
+ .CCRes = 2,
+ .CP0_Status_rw_bitmask = 0x36FBFFFF,
+ .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
+ (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
+ (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 49,
+ .PABITS = 49,
+ .insn_flags = CPU_OCTEON | ASE_MIPS3D,
+ .mmu_type = MMU_TYPE_R4000,
+ },
+ {
.name = "Loongson-2E",
.CP0_PRid = 0x6302,
/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions
2011-08-15 11:25 [Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support khansa
2011-08-15 11:25 ` [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU khansa
2011-08-15 11:25 ` [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall khansa
@ 2011-08-15 11:25 ` khansa
2011-08-15 16:18 ` Richard Henderson
2011-08-15 11:25 ` [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler khansa
3 siblings, 1 reply; 13+ messages in thread
From: khansa @ 2011-08-15 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, riku.voipio,
Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt, aurelien
From: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt <khansa@kics.edu.pk>
Signed-off-by: Khansa Butt <khansa@kics.edu.pk>
---
target-mips/cpu.h | 7 +
target-mips/helper.h | 5 +
target-mips/machine.c | 12 ++
target-mips/op_helper.c | 72 ++++++++
target-mips/translate.c | 434 ++++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 525 insertions(+), 5 deletions(-)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c5f70fa..385f6d3 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -173,6 +173,13 @@ struct TCState {
target_ulong CP0_TCSchedule;
target_ulong CP0_TCScheFBack;
int32_t CP0_Debug_tcstatus;
+ /* Multiplier registers for Octeon */
+ target_ulong MPL0;
+ target_ulong MPL1;
+ target_ulong MPL2;
+ target_ulong P0;
+ target_ulong P1;
+ target_ulong P2;
};
typedef struct CPUMIPSState CPUMIPSState;
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 297ab64..e892d39 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -8,7 +8,12 @@ DEF_HELPER_3(ldl, tl, tl, tl, int)
DEF_HELPER_3(ldr, tl, tl, tl, int)
DEF_HELPER_3(sdl, void, tl, tl, int)
DEF_HELPER_3(sdr, void, tl, tl, int)
+DEF_HELPER_2(v3mulu, tl, tl, tl)
+DEF_HELPER_2(vmulu, tl, tl, tl)
+DEF_HELPER_1(dpop, tl, tl)
#endif
+DEF_HELPER_1(pop, tl, tl);
+
DEF_HELPER_3(lwl, tl, tl, tl, int)
DEF_HELPER_3(lwr, tl, tl, tl, int)
DEF_HELPER_3(swl, void, tl, tl, int)
diff --git a/target-mips/machine.c b/target-mips/machine.c
index be72b36..a274ce2 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -25,6 +25,12 @@ static void save_tc(QEMUFile *f, TCState *tc)
qemu_put_betls(f, &tc->CP0_TCSchedule);
qemu_put_betls(f, &tc->CP0_TCScheFBack);
qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
+ qemu_put_betls(f, &tc->MPL0);
+ qemu_put_betls(f, &tc->MPL1);
+ qemu_put_betls(f, &tc->P0);
+ qemu_put_betls(f, &tc->P1);
+ qemu_put_betls(f, &tc->P2);
+
}
static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
@@ -173,6 +179,12 @@ static void load_tc(QEMUFile *f, TCState *tc)
qemu_get_betls(f, &tc->CP0_TCSchedule);
qemu_get_betls(f, &tc->CP0_TCScheFBack);
qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
+ qemu_get_betls(f, &tc->MPL0);
+ qemu_get_betls(f, &tc->MPL1);
+ qemu_get_betls(f, &tc->MPL2);
+ qemu_get_betls(f, &tc->P0);
+ qemu_get_betls(f, &tc->P1);
+ qemu_get_betls(f, &tc->P2);
}
static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 056011f..fce8755 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -320,8 +320,80 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
{
mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2);
}
+
+static void addc(uint64_t res[], uint64_t a, int i)
+{
+ uint64_t c = res[i];
+ for (; i < 4; i++) {
+ res[i] = c + a;
+ if (res[i] < a) {
+ c = 1;
+ a = res[i+1];
+ } else
+ break;
+ }
+}
+
+target_ulong helper_v3mulu(target_ulong arg1, target_ulong arg2)
+{
+ uint64_t hi, lo, res[4];
+ int i;
+ for (i = 0; i < 4; i++) {
+ res[i] = 0;
+ }
+ mulu64(&res[0], &res[1], env->active_tc.MPL0, arg1);
+ mulu64(&lo, &hi, env->active_tc.MPL1, arg1);
+ res[1] = res[1] + lo;
+ if (res[1] < lo) {
+ res[2]++;
+ }
+ res[2] = res[2] + hi;
+ if (res[2] < hi) {
+ res[3]++;
+ }
+ mulu64(&lo, &hi, env->active_tc.MPL2, arg1);
+ res[2] = res[2] + lo;
+ if (res[2] < lo) {
+ res[3]++;
+ }
+ res[3] = res[3] + hi;
+ addc(res, arg2, 0);
+ addc(res, env->active_tc.P0, 0);
+ addc(res, env->active_tc.P1, 1);
+ addc(res, env->active_tc.P2, 2);
+ env->active_tc.P0 = res[1];
+ env->active_tc.P1 = res[2];
+ env->active_tc.P2 = res[3];
+ return res[0];
+}
+
+target_ulong helper_vmulu(target_ulong arg1, target_ulong arg2)
+{
+ uint64_t hi, lo;
+ mulu64(&lo, &hi, env->active_tc.MPL0, arg1);
+ lo = lo + arg2;
+ if (lo < arg2) {
+ hi++;
+ }
+ lo = lo + env->active_tc.P0;
+ if (lo < env->active_tc.P0) {
+ hi++;
+ }
+ env->active_tc.P0 = hi;
+ return lo;
+}
+
+target_ulong helper_dpop(target_ulong arg)
+{
+ return ctpop64(arg);
+}
#endif
+target_ulong helper_pop(target_ulong arg)
+{
+ return ctpop32((uint32_t)arg);
+}
+
#ifndef CONFIG_USER_ONLY
static inline target_phys_addr_t do_translate_address(target_ulong address, int rw)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2848c6a..2df8c3e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -69,6 +69,11 @@ enum {
OPC_JAL = (0x03 << 26),
OPC_JALS = OPC_JAL | 0x5,
OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
+ /* Cavium Specific */
+ OPC_BBIT1 = (0x3a << 26), /* jump on bit set, cavium specific */
+ OPC_BBIT132 = (0x3e << 26), /* jump on bit set (for upper 32 bits) */
+ OPC_BBIT0 = (0x32 << 26), /* jump on bit clear, cavium specific */
+ OPC_BBIT032 = (0x36 << 26), /* jump on bit clear (for upper 32 bits) */
OPC_BEQL = (0x14 << 26),
OPC_BNE = (0x05 << 26),
OPC_BNEL = (0x15 << 26),
@@ -264,6 +269,31 @@ enum {
OPC_MADD = 0x00 | OPC_SPECIAL2,
OPC_MADDU = 0x01 | OPC_SPECIAL2,
OPC_MUL = 0x02 | OPC_SPECIAL2,
+ /* Cavium Specific Instructions */
+ OPC_BADDU = 0x28 | OPC_SPECIAL2,
+ OPC_DMUL = 0x03 | OPC_SPECIAL2,
+ OPC_EXTS = 0x3a | OPC_SPECIAL2,
+ OPC_EXTS32 = 0x3b | OPC_SPECIAL2,
+ OPC_CINS = 0x32 | OPC_SPECIAL2,
+ OPC_CINS32 = 0x33 | OPC_SPECIAL2,
+ OPC_SEQI = 0x2e | OPC_SPECIAL2,
+ OPC_SNEI = 0x2f | OPC_SPECIAL2,
+ OPC_MTM0 = 0x08 | OPC_SPECIAL2,
+ OPC_MTM1 = 0x0c | OPC_SPECIAL2,
+ OPC_MTM2 = 0x0d | OPC_SPECIAL2,
+ OPC_MTP0 = 0x09 | OPC_SPECIAL2,
+ OPC_MTP1 = 0x0a | OPC_SPECIAL2,
+ OPC_MTP2 = 0x0b | OPC_SPECIAL2,
+ OPC_V3MULU = 0x11 | OPC_SPECIAL2,
+ OPC_VMM0 = 0x10 | OPC_SPECIAL2,
+ OPC_VMULU = 0x0f | OPC_SPECIAL2,
+ OPC_POP = 0X2C | OPC_SPECIAL2,
+ OPC_DPOP = 0X2D | OPC_SPECIAL2,
+ OPC_SEQ = 0x2a | OPC_SPECIAL2,
+ OPC_SNE = 0x2b | OPC_SPECIAL2,
+ OPC_SAA = 0x18 | OPC_SPECIAL2,
+ OPC_SAAD = 0x19 | OPC_SPECIAL2,
+/**************************************/
OPC_MSUB = 0x04 | OPC_SPECIAL2,
OPC_MSUBU = 0x05 | OPC_SPECIAL2,
/* Loongson 2F */
@@ -1418,7 +1448,229 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
(void)opn; /* avoid a compiler warning */
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
}
+#if defined(TARGET_MIPS64)
+/* set on equal/not equal immidiate */
+static void gen_set_imm(CPUState *env, uint32_t opc,
+ int rt, int rs, int16_t imm)
+{
+ target_ulong uimm = (target_long)imm;
+ TCGv t0;
+ const char *opn = "imm set";
+ if (rt == 0) {
+ /* If no destination, treat it as a NOP. */
+ MIPS_DEBUG("NOP");
+ return;
+ }
+ t0 = tcg_temp_new();
+ gen_load_gpr(t0, rs);
+ tcg_gen_xori_tl(t0, t0, uimm);
+ switch (opc) {
+ case OPC_SEQI:
+ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, 1);
+ opn = "seqi";
+ break;
+ case OPC_SNEI:
+ tcg_gen_setcondi_tl(TCG_COND_GT, cpu_gpr[rt], t0, 0);
+ opn = "snei";
+ break;
+ }
+ tcg_temp_free(t0);
+}
+/* Cavium specific Large Multiply Instructions */
+static void gen_LMI(DisasContext *ctx, uint32_t opc, int rs, int rt, int rd)
+{
+ const char *opn = "LMI";
+ TCGv t0, t1;
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+ switch (opc) {
+ case OPC_MTM0:
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.MPL0));
+ tcg_gen_movi_tl(t0, 0);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P0));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P1));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P2));
+ opn = "mtm0";
+ break;
+ case OPC_MTM1:
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.MPL1));
+ tcg_gen_movi_tl(t0, 0);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P0));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P1));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P2));
+ opn = "mtm1";
+ break;
+ case OPC_MTM2:
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.MPL2));
+ tcg_gen_movi_tl(t0, 0);
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P0));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P1));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P2));
+ break;
+ case OPC_MTP0:
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P0));
+ opn = "mtp0";
+ break;
+ case OPC_MTP1:
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P1));
+ opn = "mtp1";
+ break;
+ case OPC_MTP2:
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P2));
+ opn = "mtp2";
+ break;
+ case OPC_VMM0:
+ {
+ TCGv t2, t3;
+ t2 = tcg_temp_new();
+ t3 = tcg_temp_new();
+ tcg_gen_ld_tl(t2, cpu_env, offsetof(CPUState, active_tc.MPL0));
+ tcg_gen_ld_tl(t3, cpu_env, offsetof(CPUState, active_tc.P0));
+ tcg_gen_mul_i64(t0, t0, t2);
+ tcg_gen_add_tl(t1, t1, t0);
+ tcg_gen_add_tl(t1, t1, t3);
+ gen_store_gpr(t1, rd);
+ tcg_gen_movi_tl(t0, 0);
+ tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, active_tc.MPL0));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P0));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P1));
+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, active_tc.P2));
+ tcg_temp_free(t2);
+ tcg_temp_free(t3);
+ opn = "vmm0";
+ break;
+ }
+ case OPC_VMULU:
+ gen_helper_vmulu(t0, t0, t1);
+ gen_store_gpr(t0, rd);
+ opn = "vmulu";
+ break;
+ case OPC_V3MULU:
+ gen_helper_v3mulu(t0, t0, t1);
+ gen_store_gpr(t0, rd);
+ opn = "v3mulu";
+ break;
+ }
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+/* set if equal/not equal */
+static void gen_set(DisasContext *ctx, uint32_t opc,
+ int rd, int rs, int rt)
+{
+ const char *opn = "seq/sne";
+ TCGv t0, t1;
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+ tcg_gen_xor_tl(t0, t0, t1);
+ switch (opc) {
+ case OPC_SEQ:
+ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rd], t0, 1);
+ opn = "seq";
+ break;
+ case OPC_SNE:
+ tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_gpr[rd], t0, 0);
+ opn = "sne";
+ break;
+ default:
+ MIPS_INVAL(opn);
+ generate_exception(ctx, EXCP_RI);
+ }
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+
+}
+/* Store atomic add */
+/* FIXME: something else should be done for emulating SMP system. */
+static void gen_saa(CPUState *env, DisasContext *ctx, uint32_t opc,
+ int rt, int base)
+{
+ const char *opn = "saa";
+ TCGv t0, t1, temp;
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+ temp = tcg_temp_new();
+ gen_load_gpr(t1, rt);
+ gen_base_offset_addr(ctx, t0, base, 0);
+ switch (opc) {
+ case OPC_SAA:
+ save_cpu_state(ctx, 1);
+ op_ld_lw(temp, t0, ctx);
+ tcg_gen_add_tl(temp, temp, t1);
+ op_st_sw(temp, t0, ctx);
+ opn = "saa";
+ break;
+ case OPC_SAAD:
+ save_cpu_state(ctx, 0);
+ op_ld_ld(temp, t0, ctx);
+ tcg_gen_add_tl(temp, temp, t1);
+ op_st_sd(temp, t0, ctx);
+ opn = "saad";
+ break;
+ }
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+static void gen_pop_count(DisasContext *ctx, uint32_t opc, int rd, int rs)
+{
+ const char *opn = "pop";
+ TCGv t0;
+ t0 = tcg_temp_new();
+ gen_load_gpr(t0, rs);
+ switch (opc) {
+ case OPC_DPOP:
+ gen_helper_dpop(t0, t0);
+ gen_store_gpr(t0, rd);
+ opn = "dpop";
+ break;
+ case OPC_POP:
+ gen_helper_pop(t0, t0);
+ gen_store_gpr(t0, rd);
+ opn = "pop";
+ break;
+ }
+ tcg_temp_free(t0);
+}
+/* Cavium specific extract instructions */
+static void gen_exts(CPUState *env, DisasContext *ctx, uint32_t opc, int rt,
+ int rs, int lsb, int msb)
+{
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ target_ulong mask;
+ gen_load_gpr(t1, rs);
+ switch (opc) {
+ case OPC_EXTS:
+ tcg_gen_shri_tl(t0, t1, lsb);
+ tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
+ /* To sign extened the remaining bits according to
+ the msb of the bit field */
+ mask = 1ULL << msb;
+ tcg_gen_andi_tl(t1, t0, mask);
+ tcg_gen_addi_tl(t1, t1, -1);
+ tcg_gen_orc_tl(t0, t0, t1);
+ gen_store_gpr(t0, rt);
+ break;
+ case OPC_EXTS32:
+ tcg_gen_shri_tl(t0, t1, lsb + 32);
+ tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
+ mask = 1ULL << msb;
+ tcg_gen_andi_tl(t1, t0, mask);
+ tcg_gen_addi_tl(t1, t1, -1);
+ tcg_gen_orc_tl(t0, t0, t1);
+ gen_store_gpr(t0, rt);
+ break;
+ }
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+#endif
/* Logic with immediate operand */
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
{
@@ -1636,6 +1888,32 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
}
opn = "addu";
break;
+ case OPC_BADDU:
+ {
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+ tcg_gen_add_tl(t0, t1, t0);
+ tcg_gen_ext8u_tl(t0, t0);
+ gen_store_gpr(t0, rd);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ opn = "baddu";
+ break;
+ }
+ case OPC_DMUL:
+ {
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+ tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ opn = "dmul";
+ break;
+ }
case OPC_SUB:
{
TCGv t0 = tcg_temp_local_new();
@@ -2729,6 +3007,28 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
}
btgt = ctx->pc + insn_bytes + offset;
break;
+ case OPC_BBIT0:
+ case OPC_BBIT1:
+ {
+ target_ulong maskb;
+ gen_load_gpr(t0, rs);
+ maskb = 1ULL << rt;
+ tcg_gen_andi_tl(t0, t0, maskb);
+ bcond_compute = 1;
+ btgt = ctx->pc + insn_bytes + offset;
+ break;
+ }
+ case OPC_BBIT032:
+ case OPC_BBIT132:
+ {
+ target_ulong maskb;
+ gen_load_gpr(t0, rs);
+ maskb = 1ULL << (rt + 32);
+ tcg_gen_andi_tl(t0, t0, maskb);
+ bcond_compute = 1;
+ btgt = ctx->pc + insn_bytes + offset;
+ break;
+ }
case OPC_BGEZ:
case OPC_BGEZAL:
case OPC_BGEZALS:
@@ -2887,6 +3187,14 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btgt);
goto not_likely;
+ case OPC_BBIT1:
+ case OPC_BBIT132:
+ tcg_gen_setcondi_tl(TCG_COND_NE, bcond, t0, 0);
+ goto not_likely;
+ case OPC_BBIT0:
+ case OPC_BBIT032:
+ tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, t0, 0);
+ goto not_likely;
case OPC_BNEL:
tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
@@ -3062,6 +3370,22 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
tcg_gen_andi_tl(t1, t1, mask);
tcg_gen_or_tl(t0, t0, t1);
break;
+ case OPC_CINS:
+ mask = (1ULL << (msb+1))-1;
+ gen_load_gpr(t0, rt);
+ tcg_gen_andi_tl(t0, t0, 0);
+ tcg_gen_andi_tl(t1, t1, mask);
+ tcg_gen_shli_tl(t1, t1, lsb);
+ tcg_gen_or_tl(t0, t0, t1);
+ break;
+ case OPC_CINS32:
+ mask = (1ULL << (msb+1))-1;
+ gen_load_gpr(t0, rt);
+ tcg_gen_andi_tl(t0, t0, 0);
+ tcg_gen_andi_tl(t1, t1, mask);
+ tcg_gen_shli_tl(t1, t1, (lsb+32));
+ tcg_gen_or_tl(t0, t0, t1);
+ break;
#endif
default:
fail:
@@ -11862,6 +12186,57 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
case OPC_MUL:
gen_arith(env, ctx, op1, rd, rs, rt);
break;
+#if defined(TARGET_MIPS64)
+ case OPC_DMUL:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_arith(env, ctx, op1, rd, rs, rt);
+ break;
+ case OPC_CINS:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_bitops(ctx, op1, rt, rs, sa, rd);
+ break;
+ case OPC_CINS32:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_bitops(ctx, op1, rt, rs, sa, rd);
+ break;
+ case OPC_MTM0:
+ case OPC_MTM1:
+ case OPC_MTM2:
+ case OPC_MTP0:
+ case OPC_MTP1:
+ case OPC_MTP2:
+ case OPC_VMULU:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_LMI(ctx, op1, rs, rt, rd);
+ break;
+ case OPC_BADDU:
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_arith(env, ctx, op1, rd, rs, rt);
+ break;
+ case OPC_EXTS:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_exts(env, ctx, op1, rt, rs, sa, rd);
+ break;
+ case OPC_EXTS32:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_exts(env, ctx, op1, rt, rs, sa, rd);
+ break;
+ case OPC_SAA:
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_saa(env, ctx, op1, rt, rs);
+ break;
+ case OPC_SAAD:
+ check_insn(env, ctx, INSN_OCTEON);
+ check_mips_64(ctx);
+ gen_saa(env, ctx, op1, rt, rs);
+ break;
+#endif
case OPC_CLO:
case OPC_CLZ:
check_insn(env, ctx, ISA_MIPS32);
@@ -11879,9 +12254,18 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
}
/* Treat as NOP. */
break;
+ case OPC_MULT_G_2F:
+#if defined(TARGET_MIPS64)
+ /* Is Cavium Specific vmm0? */
+ if ((env->insn_flags & CPU_OCTEON)) {
+ check_mips_64(ctx);
+ gen_LMI(ctx, op1, rs, rt, rd);
+ break;
+ }
+#endif
+ /* Otherwise fall through */
case OPC_DIV_G_2F:
case OPC_DIVU_G_2F:
- case OPC_MULT_G_2F:
case OPC_MULTU_G_2F:
case OPC_MOD_G_2F:
case OPC_MODU_G_2F:
@@ -11896,6 +12280,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
gen_cl(ctx, op1, rd, rs);
break;
case OPC_DMULT_G_2F:
+ /* Is Cavium Specific instruction v3mulu? */
+ if ((env->insn_flags & CPU_OCTEON)) {
+ check_mips_64(ctx);
+ gen_LMI(ctx, op1, rs, rt, rd);
+ break;
+ }
case OPC_DMULTU_G_2F:
case OPC_DDIV_G_2F:
case OPC_DDIVU_G_2F:
@@ -11904,6 +12294,31 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
check_insn(env, ctx, INSN_LOONGSON2F);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
+ case OPC_SEQ:
+ case OPC_SNE:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_set(ctx, op1, rd, rs, rt);
+ break;
+ case OPC_SEQI:
+ case OPC_SNEI:
+ {
+ int16_t imm10;
+ imm10 = (ctx->opcode >> 6) & 0x3ff;
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_set_imm(env, op1, rt, rs, imm10);
+ break;
+ }
+ case OPC_POP:
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_pop_count(ctx, op1, rd, rs);
+ break;
+ case OPC_DPOP:
+ check_mips_64(ctx);
+ check_insn(env, ctx, INSN_OCTEON);
+ gen_pop_count(ctx, op1, rd, rs);
+ break;
#endif
default: /* Invalid */
MIPS_INVAL("special2");
@@ -12195,10 +12610,18 @@ static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
break;
/* COP2. */
- case OPC_LWC2:
- case OPC_LDC2:
- case OPC_SWC2:
- case OPC_SDC2:
+ /* Conflicting opcodes with Cavium specific branch instructions
+ if cpu_model is set to Octeon these opcodes will
+ belong to Octeon processor */
+ case OPC_LWC2: /* BBIT0 */
+ case OPC_LDC2: /* BBIT032 */
+ case OPC_SWC2: /* BBIT1 */
+ case OPC_SDC2: /* BBIT132 */
+ if (env->insn_flags & CPU_OCTEON) {
+ gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
+ *is_branch = 1;
+ break;
+ }
case OPC_CP2:
/* COP2: Not implemented. */
generate_exception_err(ctx, EXCP_CpU, 2);
@@ -12693,6 +13116,7 @@ void cpu_reset (CPUMIPSState *env)
env->hflags |= MIPS_HFLAG_FPU;
}
#ifdef TARGET_MIPS64
+ env->hflags |= MIPS_HFLAG_UX;
if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
env->hflags |= MIPS_HFLAG_F64;
}
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler
2011-08-15 11:25 [Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support khansa
` (2 preceding siblings ...)
2011-08-15 11:25 ` [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions khansa
@ 2011-08-15 11:25 ` khansa
2011-08-15 16:37 ` Richard Henderson
3 siblings, 1 reply; 13+ messages in thread
From: khansa @ 2011-08-15 11:25 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, riku.voipio, Khansa Butt, aurelien
From: Khansa Butt <khansa@kics.edu.pk>
Signed-off-by: Khansa Butt <khansa@kics.edu.pk>
---
disas.c | 4 +++
mips-dis.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
target-mips/translate.c | 3 ++
3 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/disas.c b/disas.c
index 1334b8e..0137657 100644
--- a/disas.c
+++ b/disas.c
@@ -140,6 +140,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
i386 - nonzero means 16 bit code
arm - nonzero means thumb code
ppc - nonzero means little endian
+ mips64 - zero means standard MIPS ISA, 1 means Octeon CPU.
other targets - unused
*/
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
@@ -196,6 +197,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
print_insn = print_insn_m68k;
#elif defined(TARGET_MIPS)
#ifdef TARGET_WORDS_BIGENDIAN
+ if (flags)
+ disasm_info.flags = flags << 16;
+ print_insn = print_insn_big_mips;
print_insn = print_insn_big_mips;
#else
print_insn = print_insn_little_mips;
diff --git a/mips-dis.c b/mips-dis.c
index 4d8e85b..b5b4e1b 100644
--- a/mips-dis.c
+++ b/mips-dis.c
@@ -300,6 +300,7 @@ struct mips_opcode
Also used for immediate operands in vr5400 vector insns.
"o" 16 bit signed offset (OP_*_DELTA)
"p" 16 bit PC relative branch target address (OP_*_DELTA)
+ "+p" 5 bit unsigned constant describing bit position, for Octeon (OP_*_RT)
"q" 10 bit extra breakpoint code (OP_*_CODE2)
"r" 5 bit same register used as both source and target (OP_*_RS)
"s" 5 bit source register specifier (OP_*_RS)
@@ -491,6 +492,13 @@ struct mips_opcode
#define INSN_MULT 0x40000000
/* Instruction synchronize shared memory. */
#define INSN_SYNC 0x80000000
+/* Load Cavium specific multiplier registers. */
+#define INSN_WRITE_MPL0 0x100000000
+#define INSN_WRITE_MPL1 0x200000000
+#define INSN_WRITE_MPL2 0x400000000
+#define INSN_WRITE_P0 0x800000000
+#define INSN_WRITE_P1 0x1000000000
+#define INSN_WRITE_P2 0x2000000000
/* These are the bits which may be set in the pinfo2 field of an
instruction. */
@@ -569,6 +577,8 @@ struct mips_opcode
#define INSN_LOONGSON_2E 0x40000000
/* ST Microelectronics Loongson 2F. */
#define INSN_LOONGSON_2F 0x80000000
+/* Cavium Network's Octeon processor */
+#define INSN_CVM_OCTEON 0x100000000
/* MIPS ISA defines, use instead of hardcoding ISA level. */
@@ -1099,6 +1109,13 @@ extern const int bfd_mips16_num_opcodes;
#define RD_HI INSN_READ_HI
#define MOD_HI WR_HI|RD_HI
+#define WR_MPL0 INSN_WRITE_MPL0
+#define WR_MPL1 INSN_WRITE_MPL1
+#define WR_MPL2 INSN_WRITE_MPL2
+#define WR_P0 INSN_WRITE_P0
+#define WR_P1 INSN_WRITE_P1
+#define WR_P2 INSN_WRITE_P2
+
#define WR_LO INSN_WRITE_LO
#define RD_LO INSN_READ_LO
#define MOD_LO WR_LO|RD_LO
@@ -1137,6 +1154,8 @@ extern const int bfd_mips16_num_opcodes;
#define IL2E (INSN_LOONGSON_2E)
#define IL2F (INSN_LOONGSON_2F)
+#define ICVM (INSN_CVM_OCTEON)
+
#define P3 INSN_4650
#define L1 INSN_4010
#define V1 (INSN_4100 | INSN_4111 | INSN_4120)
@@ -2435,6 +2454,34 @@ const struct mips_opcode mips_builtin_opcodes[] =
{"cop1", "C", 0, (int) M_COP1, INSN_MACRO, 0, I1 },
{"cop2", "C", 0, (int) M_COP2, INSN_MACRO, 0, I1 },
{"cop3", "C", 0, (int) M_COP3, INSN_MACRO, 0, I1 },
+/* Cavium specific instructions */
+{"baddu", "d,s,t", 0x70000028, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"dmul", "d,s,t", 0x70000003, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"v3mulu", "d,s,t", 0x70000011, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"vmm0", "d,s,t", 0x70000010, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"vmulu", "d,s,t", 0x7000000f, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"seq", "d,s,t", 0x7000002a, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"seqi", "t,r,j", 0x7000002e, 0xfc00003f, WR_t|RD_s, 0, ICVM },
+{"sne", "d,s,t", 0x7000002b, 0xfc0007ff, RD_s|RD_t|WR_d, 0, ICVM },
+{"snei", "t,r,j", 0x7000002f, 0xfc00003f, WR_t|RD_s, 0, ICVM },
+{"bbit0", "s,+p,p", 0xc8000000, 0xfc000000, CBD|RD_s, 0, ICVM },
+{"bbit032", "s,+p,p", 0xd8000000, 0xfc000000, CBD|RD_s, 0, ICVM },
+{"bbit1", "s,+p,p", 0xe8000000, 0xfc000000, CBD|RD_s, 0, ICVM },
+{"bbit132", "s,+p,p", 0xf8000000, 0xfc000000, CBD|RD_s, 0, ICVM },
+{"saa", "t,(b)", 0x70000018, 0xfc00ffff, SM|RD_t|RD_b, 0, ICVM },
+{"saad", "t,(b)", 0x70000019, 0xfc00ffff, SM|RD_t|RD_b, 0, ICVM },
+{"exts", "t,r,+A,+C", 0x7000003a, 0xfc00003f, WR_t|RD_s, 0, ICVM },
+{"exts32", "t,r,+A,+C", 0x7c00003b, 0xfc00003f, WR_t|RD_s, 0, ICVM },
+{"cins", "t,r,+A,+B", 0x70000032, 0xfc00003f, WR_t|RD_s, 0, ICVM },
+{"cins32", "t,r,+A,+B", 0x70000033, 0xfc00003f, WR_t|RD_s, 0, ICVM },
+{"mtm0", "s", 0x70000008, 0xfc1fffff, RD_s|WR_MPL0, 0, ICVM },
+{"mtm1", "s", 0x7000000c, 0xfc1fffff, RD_s|WR_MPL1, 0, ICVM },
+{"mtm2", "s", 0x7000000d, 0xfc1fffff, RD_s|WR_MPL2, 0, ICVM },
+{"mtp0", "s", 0x70000009, 0xfc1fffff, RD_s|WR_P0, 0, ICVM },
+{"mtp1", "s", 0x7000000a, 0xfc1fffff, RD_s|WR_P1, 0, ICVM },
+{"mtp2", "s", 0x7000000b, 0xfc1fffff, RD_s|WR_P2, 0, ICVM },
+{"dpop", "d,s", 0x7000002d, 0xfc1f07ff, RD_s|WR_d, 0, ICVM },
+{"pop", "d,s", 0x7000002c, 0xfc1f07ff, RD_s|WR_d, 0, ICVM },
/* Conflicts with the 4650's "mul" instruction. Nobody's using the
4010 any more, so move this insn out of the way. If the object
format gave us more info, we could do this right. */
@@ -3603,6 +3650,12 @@ print_insn_args (const char *d,
break;
}
+ case 'p':
+ /* Cavium specific 5 bit value describing bit position. */
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (unsigned int)(l >> OP_SH_RT) & OP_MASK_RT);
+ break;
+
default:
/* xgettext:c-format */
(*info->fprintf_func) (info->stream,
@@ -4041,6 +4094,14 @@ print_insn_mips (bfd_vma memaddr,
{
for (; op < &mips_opcodes[NUMOPCODES]; op++)
{
+ /* This is to avoid the conflict among Cavium specific,
+ * COP2 and Loongson instructions.
+ */
+ if (info->flags) {
+ if (op->pinfo == (CLD|RD_b|WR_CC) || op->pinfo == (SM|RD_C2|RD_b)
+ || (op->pinfo == (WR_d|RD_s|RD_t) && op->membership == I33))
+ continue;
+ }
if (op->pinfo != INSN_MACRO
&& !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
&& (word & op->mask) == op->match)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2df8c3e..65786a1 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12860,6 +12860,9 @@ done_generating:
LOG_DISAS("\n");
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("IN: %s\n", lookup_symbol(pc_start));
+ if (env->insn_flags & CPU_OCTEON)
+ log_target_disas(pc_start, ctx.pc - pc_start, 1);
+ else
log_target_disas(pc_start, ctx.pc - pc_start, 0);
qemu_log("\n");
}
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU
2011-08-15 11:25 ` [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU khansa
@ 2011-08-15 15:32 ` Richard Henderson
0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2011-08-15 15:32 UTC (permalink / raw)
To: khansa; +Cc: peter.maydell, riku.voipio, qemu-devel, aurelien
On 08/15/2011 04:25 AM, khansa@kics.edu.pk wrote:
> -# warning signal handling not implemented
> -
Why? It's still true. Just configure with --disable-werror.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall
2011-08-15 11:25 ` [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall khansa
@ 2011-08-15 15:43 ` Richard Henderson
2011-08-17 7:00 ` Khansa Butt
0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2011-08-15 15:43 UTC (permalink / raw)
To: khansa; +Cc: peter.maydell, riku.voipio, qemu-devel, aurelien
On 08/15/2011 04:25 AM, khansa@kics.edu.pk wrote:
> ((CPUMIPSState *) cpu_env)->tls_value = arg1;
> + if (((CPUMIPSState *) cpu_env)->insn_flags & CPU_OCTEON) {
> + /* tls entry is moved to k0 so that this can be used later
> + currently this thing is tested only for Octeon */
> + ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
> + }
You wanted INSN_OCTEON, not CPU_OCTEON, which includes CPU_MIPS64R2.
That said, this is *not* in the current linux kernel. And I question
the wisdom of changing the user-space ABI for TLS for a single CPU.
I think you'd better leave this out until it's actually accepted upstream.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions
2011-08-15 11:25 ` [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions khansa
@ 2011-08-15 16:18 ` Richard Henderson
0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2011-08-15 16:18 UTC (permalink / raw)
To: khansa; +Cc: peter.maydell, riku.voipio, qemu-devel, aurelien
> }
> +#if defined(TARGET_MIPS64)
> +/* set on equal/not equal immidiate */
You need blank lines between all of these functions.
Also, "immediate" is misspelled.
> + tcg_gen_xori_tl(t0, t0, uimm);
> + switch (opc) {
> + case OPC_SEQI:
> + tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, 1);
For both gen_set_imm and gen_set, you're thinking about these
operations how you'd implement them with mips native insns.
For TCG this should be
tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr[rt], cpu_gpr[rs], uimm);
> +/* Store atomic add */
> +/* FIXME: something else should be done for emulating SMP system. */
See how EXCP_SC is used here in the translator and in linux-user/main.c.
> +/* Cavium specific extract instructions */
> +static void gen_exts(CPUState *env, DisasContext *ctx, uint32_t opc, int rt,
> + int rs, int lsb, int msb)
> +{
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + target_ulong mask;
> + gen_load_gpr(t1, rs);
> + switch (opc) {
> + case OPC_EXTS:
> + tcg_gen_shri_tl(t0, t1, lsb);
> + tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
> + /* To sign extened the remaining bits according to
> + the msb of the bit field */
> + mask = 1ULL << msb;
> + tcg_gen_andi_tl(t1, t0, mask);
> + tcg_gen_addi_tl(t1, t1, -1);
> + tcg_gen_orc_tl(t0, t0, t1);
> + gen_store_gpr(t0, rt);
This can be implemented with exactly two shifts:
lshift = 64 - msb - 1;
rshift = lshift + lsb;
tcg_gen_shli_tl(t0, t0, lshift);
tcg_gen_sari_tl(to, to, rshift);
> OPC_MUL = 0x02 | OPC_SPECIAL2,
> + /* Cavium Specific Instructions */
> + OPC_BADDU = 0x28 | OPC_SPECIAL2,
> + OPC_DMUL = 0x03 | OPC_SPECIAL2,
> + OPC_EXTS = 0x3a | OPC_SPECIAL2,
> + OPC_EXTS32 = 0x3b | OPC_SPECIAL2,
> + OPC_CINS = 0x32 | OPC_SPECIAL2,
> + OPC_CINS32 = 0x33 | OPC_SPECIAL2,
> + OPC_SEQI = 0x2e | OPC_SPECIAL2,
> + OPC_SNEI = 0x2f | OPC_SPECIAL2,
> + OPC_MTM0 = 0x08 | OPC_SPECIAL2,
> + OPC_MTM1 = 0x0c | OPC_SPECIAL2,
> + OPC_MTM2 = 0x0d | OPC_SPECIAL2,
> + OPC_MTP0 = 0x09 | OPC_SPECIAL2,
> + OPC_MTP1 = 0x0a | OPC_SPECIAL2,
> + OPC_MTP2 = 0x0b | OPC_SPECIAL2,
> + OPC_V3MULU = 0x11 | OPC_SPECIAL2,
> + OPC_VMM0 = 0x10 | OPC_SPECIAL2,
> + OPC_VMULU = 0x0f | OPC_SPECIAL2,
> + OPC_POP = 0X2C | OPC_SPECIAL2,
> + OPC_DPOP = 0X2D | OPC_SPECIAL2,
> + OPC_SEQ = 0x2a | OPC_SPECIAL2,
> + OPC_SNE = 0x2b | OPC_SPECIAL2,
> + OPC_SAA = 0x18 | OPC_SPECIAL2,
> + OPC_SAAD = 0x19 | OPC_SPECIAL2,
> +/**************************************/
> OPC_MSUB = 0x04 | OPC_SPECIAL2,
> OPC_MSUBU = 0x05 | OPC_SPECIAL2,
> /* Loongson 2F */
You'll notice that there are already nicely separated sections
there in the enums for SPECIAL2, and you've dropped yours right
in the middle. Don't do that. Nor the ***** thing.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler
2011-08-15 11:25 ` [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler khansa
@ 2011-08-15 16:37 ` Richard Henderson
2011-08-17 6:52 ` Khansa Butt
0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2011-08-15 16:37 UTC (permalink / raw)
To: khansa; +Cc: peter.maydell, riku.voipio, qemu-devel, aurelien
On 08/15/2011 04:25 AM, khansa@kics.edu.pk wrote:
> index 1334b8e..0137657 100644
> --- a/disas.c
> +++ b/disas.c
> @@ -140,6 +140,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
> i386 - nonzero means 16 bit code
> arm - nonzero means thumb code
> ppc - nonzero means little endian
> + mips64 - zero means standard MIPS ISA, 1 means Octeon CPU.
...
> +++ b/target-mips/translate.c
> @@ -12860,6 +12860,9 @@ done_generating:
> LOG_DISAS("\n");
> if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
> qemu_log("IN: %s\n", lookup_symbol(pc_start));
> + if (env->insn_flags & CPU_OCTEON)
> + log_target_disas(pc_start, ctx.pc - pc_start, 1);
> + else
> log_target_disas(pc_start, ctx.pc - pc_start, 0);
disas.c has access to cpu.h. You'd do well to avoid a magic number
here and pass along env->insn_flags right from the beginning, and...
> @@ -196,6 +197,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
> print_insn = print_insn_m68k;
> #elif defined(TARGET_MIPS)
> #ifdef TARGET_WORDS_BIGENDIAN
> + if (flags)
> + disasm_info.flags = flags << 16;
> + print_insn = print_insn_big_mips;
> print_insn = print_insn_big_mips;
Notice anything funny here in the last two lines?
Notice anything incorrect about the coding style?
It's a bit sad that we're limited to pre-GPLv3, because we're going
to get more and more out of sync with the binutils disassembler.
But that said, let's not go out of our way to totally change the style.
Give mips-dis.c access to target-mips/mips-defs.h. Map between that
and the existing membership field in struct mips_opcode. Put some
real code back into OPCODE_IS_MEMBER.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler
2011-08-15 16:37 ` Richard Henderson
@ 2011-08-17 6:52 ` Khansa Butt
2011-08-17 15:18 ` Richard Henderson
0 siblings, 1 reply; 13+ messages in thread
From: Khansa Butt @ 2011-08-17 6:52 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2916 bytes --]
On Mon, Aug 15, 2011 at 9:37 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 08/15/2011 04:25 AM, khansa@kics.edu.pk wrote:
> > index 1334b8e..0137657 100644
> > --- a/disas.c
> > +++ b/disas.c
> > @@ -140,6 +140,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
> > i386 - nonzero means 16 bit code
> > arm - nonzero means thumb code
> > ppc - nonzero means little endian
> > + mips64 - zero means standard MIPS ISA, 1 means Octeon CPU.
> ...
> > +++ b/target-mips/translate.c
> > @@ -12860,6 +12860,9 @@ done_generating:
> > LOG_DISAS("\n");
> > if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
> > qemu_log("IN: %s\n", lookup_symbol(pc_start));
> > + if (env->insn_flags & CPU_OCTEON)
> > + log_target_disas(pc_start, ctx.pc - pc_start, 1);
> > + else
> > log_target_disas(pc_start, ctx.pc - pc_start, 0);
>
> disas.c has access to cpu.h. You'd do well to avoid a magic number
> here and pass along env->insn_flags right from the beginning, and...
>
> > @@ -196,6 +197,9 @@ void target_disas(FILE *out, target_ulong code,
> target_ulong size, int flags)
> > print_insn = print_insn_m68k;
> > #elif defined(TARGET_MIPS)
> > #ifdef TARGET_WORDS_BIGENDIAN
> > + if (flags)
> > + disasm_info.flags = flags << 16;
> > + print_insn = print_insn_big_mips;
> > print_insn = print_insn_big_mips;
>
> Notice anything funny here in the last two lines?
>
I 'm sorry for this stupid thing as I was in a hurry because of lot of
things.
> Notice anything incorrect about the coding style?
>
> It's a bit sad that we're limited to pre-GPLv3, because we're going
> to get more and more out of sync with the binutils disassembler.
> But that said, let's not go out of our way to totally change the style.
>
If I pass env->insn_flags to target_disas() how can I pass this flag info
from disas.c to mips-dis.c. can i do following thing for MIPS in disas.c
if (flags & 0xFFFF) {
disasm_info.mach = flags & 0xFFFF;
>
> Give mips-dis.c access to target-mips/mips-defs.h. Map between that
> and the existing membership field in struct mips_opcode. Put some
> real code back into OPCODE_IS_MEMBER.
>
how can I make mips-defs.h 's definitions visible to mips-dis.c?
there are lot of similar definitions in both so will it not create problem.
Actually some of Cavium 's instructions have same Opcode field as Loongson
and COP2 instructions. whenever Cavium 's instruction comes, there is a
need
to pass info from translate.c to mips-dis.c so that correct instruction
would be
selected. but at the same time other MIPS standard instructions should
also
print in the log as Cavium 's ISA includes MIPS64r2.
I'm sorry i'm bothering you for this. But i'm stuck with this how to
correctly print
Cavium instructions instead of Loongson , A workaround that is acceptable
to
mips maintainer as well.
>
>
> r~
>
>
[-- Attachment #2: Type: text/html, Size: 4204 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall
2011-08-15 15:43 ` Richard Henderson
@ 2011-08-17 7:00 ` Khansa Butt
2011-08-17 15:03 ` Richard Henderson
0 siblings, 1 reply; 13+ messages in thread
From: Khansa Butt @ 2011-08-17 7:00 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1067 bytes --]
On Mon, Aug 15, 2011 at 8:43 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 08/15/2011 04:25 AM, khansa@kics.edu.pk wrote:
> > ((CPUMIPSState *) cpu_env)->tls_value = arg1;
> > + if (((CPUMIPSState *) cpu_env)->insn_flags & CPU_OCTEON) {
> > + /* tls entry is moved to k0 so that this can be used later
> > + currently this thing is tested only for Octeon */
> > + ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
> > + }
>
> You wanted INSN_OCTEON, not CPU_OCTEON, which includes CPU_MIPS64R2.
>
> That said, this is *not* in the current linux kernel. And I question
> the wisdom of changing the user-space ABI for TLS for a single CPU.
>
> I think you'd better leave this out until it's actually accepted upstream.
>
with out above fix Octeon user mode binary can not be correctly run on QEMU.
This was the behavior on actual hardware which we noticed when we were
debugging the
user mode binary on Octeon board.
(there are instructions in user mode ELF of Octeon which read k0 and k1
values)
>
>
> r~
>
[-- Attachment #2: Type: text/html, Size: 1656 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall
2011-08-17 7:00 ` Khansa Butt
@ 2011-08-17 15:03 ` Richard Henderson
0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2011-08-17 15:03 UTC (permalink / raw)
To: Khansa Butt; +Cc: qemu-devel
On 08/17/2011 12:00 AM, Khansa Butt wrote:
> with out above fix Octeon user mode binary can not be correctly run
> on QEMU. This was the behavior on actual hardware which we noticed
> when we were debugging the user mode binary on Octeon board. (there
> are instructions in user mode ELF of Octeon which read k0 and k1
> values)
So you're running a modified compiler, libc, and kernel as well?
Because if I look in Linux 3.1-rc2, arch/mips/kernel/syscall.c,
set_thread_area and arch/mips/kernel/process.c, copy_thread,
I see no evidence that any mips variant uses k0 or k1 for TLS.
You should keep this change alongside whatever modified runtime
you are using. It does not belong upstream in QEMU until your
changes are accepted upstream in linux as well.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler
2011-08-17 6:52 ` Khansa Butt
@ 2011-08-17 15:18 ` Richard Henderson
0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2011-08-17 15:18 UTC (permalink / raw)
To: Khansa Butt; +Cc: qemu-devel
On 08/16/2011 11:52 PM, Khansa Butt wrote:
> If I pass env->insn_flags to target_disas() how can I pass this flag info
> from disas.c to mips-dis.c. can i do following thing for MIPS in disas.c
> if (flags & 0xFFFF) {
> disasm_info.mach = flags & 0xFFFF;
Well, I'd have written this as
disasm_info.mach = flags;
I see no reason for the AND or IF.
> how can I make mips-defs.h 's definitions visible to mips-dis.c?
#include?
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-08-17 15:18 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-15 11:25 [Qemu-devel] [PATCH 0/4] MIPS64 user mode emulation in QEMU with Cavium specific instruction support khansa
2011-08-15 11:25 ` [Qemu-devel] [PATCH 1/4] linux-user:Support for MIPS64 user mode emulation in QEMU khansa
2011-08-15 15:32 ` Richard Henderson
2011-08-15 11:25 ` [Qemu-devel] [PATCH 2/4] Octeon cpu definitions in target-mips and Octeon specific changes in set_thread_area syscall khansa
2011-08-15 15:43 ` Richard Henderson
2011-08-17 7:00 ` Khansa Butt
2011-08-17 15:03 ` Richard Henderson
2011-08-15 11:25 ` [Qemu-devel] [PATCH 3/4] target-mips:Support for Cavium specific instructions khansa
2011-08-15 16:18 ` Richard Henderson
2011-08-15 11:25 ` [Qemu-devel] [PATCH 4/4] Addition of Cavium instruction in disassembler khansa
2011-08-15 16:37 ` Richard Henderson
2011-08-17 6:52 ` Khansa Butt
2011-08-17 15:18 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).