* [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test
@ 2014-07-29 13:48 Dongxue Zhang
2014-07-29 13:48 ` [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI Dongxue Zhang
2014-09-10 15:13 ` [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test Yongbok Kim
0 siblings, 2 replies; 4+ messages in thread
From: Dongxue Zhang @ 2014-07-29 13:48 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Dongxue Zhang, aurelien
Save code with sw and raise synci. The saved code should be raise.
If the code raised, log 'test passed'.
If the code not raised, log 'test failed, the copied instruction not run'.
Other cases, log 'unhandled'.
The test should log 'test passed'.
Signed-off-by: Dongxue Zhang <elta.era@gmail.com>
---
tests/tcg/mips/mips64/Makefile | 54 ++++++++
tests/tcg/mips/mips64/head.S | 16 +++
tests/tcg/mips/mips64/io.h | 22 +++
tests/tcg/mips/mips64/mips_boot.lds | 31 +++++
tests/tcg/mips/mips64/printf.c | 266 ++++++++++++++++++++++++++++++++++++
tests/tcg/mips/mips64/synci.c | 32 +++++
6 files changed, 421 insertions(+)
create mode 100644 tests/tcg/mips/mips64/Makefile
create mode 100644 tests/tcg/mips/mips64/head.S
create mode 100644 tests/tcg/mips/mips64/io.h
create mode 100644 tests/tcg/mips/mips64/mips_boot.lds
create mode 100644 tests/tcg/mips/mips64/printf.c
create mode 100644 tests/tcg/mips/mips64/synci.c
diff --git a/tests/tcg/mips/mips64/Makefile b/tests/tcg/mips/mips64/Makefile
new file mode 100644
index 0000000..9a222f7
--- /dev/null
+++ b/tests/tcg/mips/mips64/Makefile
@@ -0,0 +1,54 @@
+CROSS_COMPILE ?= mips64el-unknown-linux-gnu-
+
+SIM = qemu-system-mips64el
+SIMFLAGS = -nographic -cpu mips64r2-generic -kernel
+
+AS = $(CROSS_COMPILE)as
+LD = $(CROSS_COMPILE)ld
+CC = $(CROSS_COMPILE)gcc
+AR = $(CROSS_COMPILE)ar
+NM = $(CROSS_COMPILE)nm
+STRIP = $(CROSS_COMPILE)strip
+RANLIB = $(CROSS_COMPILE)ranlib
+OBJCOPY = $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CROSS_COMPILE)objdump
+
+VECTORS_OBJ ?= ./head.o ./printf.o
+
+HEAD_FLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe \
+ -msoft-float -march=mips64 -Wa,-mips64 -Wa,--trap \
+ -msym32 -DKBUILD_64BIT_SYM32 -I./
+
+CFLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -fno-builtin \
+ -pipe -march=mips64r2 -mgp64 -mdspr2 -static -Wa,--trap -msym32 \
+ -DKBUILD_64BIT_SYM32 -I./
+
+LDFLAGS = -T./mips_boot.lds -L./
+FLAGS = -nostdlib -mabi=64 -march=mips64r2 -mgp64 -mdspr2
+
+TESTCASES = synci.tst
+
+all: build
+
+head.o : head.S
+ $(Q)$(CC) $(HEAD_FLAGS) -D"STACK_TOP=0xffffffff80200000" -c $< -o $@
+
+%.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%.tst: %.o $(VECTORS_OBJ)
+ $(CC) $(VECTORS_OBJ) $(FLAGS) $(LDFLAGS) $< -o $@
+
+build: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES)
+
+check: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES)
+ @for case in $(TESTCASES); do \
+ echo $(SIM) $(SIMFLAGS) ./$$case; \
+ $(SIM) $(SIMFLAGS) ./$$case & (sleep 1; killall $(SIM)); \
+ done
+
+clean:
+ $(Q)rm -f *.o *.tst *.a
diff --git a/tests/tcg/mips/mips64/head.S b/tests/tcg/mips/mips64/head.S
new file mode 100644
index 0000000..9a099ae
--- /dev/null
+++ b/tests/tcg/mips/mips64/head.S
@@ -0,0 +1,16 @@
+/*
+ * Startup Code for MIPS64 CPU-core
+ *
+ */
+.text
+.globl _start
+.align 4
+_start:
+ ori $2, $2, 0xffff
+ sll $2, $2, 16
+ ori $2, $2, 0xffff
+ mtc0 $2, $12, 0
+ jal main
+
+end:
+ b end
diff --git a/tests/tcg/mips/mips64/io.h b/tests/tcg/mips/mips64/io.h
new file mode 100644
index 0000000..b7db61d
--- /dev/null
+++ b/tests/tcg/mips/mips64/io.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+extern int printf(const char *fmt, ...);
+extern unsigned long get_ticks(void);
+
+#define _read(source) \
+({ unsigned long __res; \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __read(source) \
+({ unsigned long __res; \
+ __asm__ __volatile__( \
+ "move\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#endif
diff --git a/tests/tcg/mips/mips64/mips_boot.lds b/tests/tcg/mips/mips64/mips_boot.lds
new file mode 100644
index 0000000..bd7c0c0
--- /dev/null
+++ b/tests/tcg/mips/mips64/mips_boot.lds
@@ -0,0 +1,31 @@
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+ . = 0xffffffff80100000;
+ . = ALIGN((1 << 13));
+ .text :
+ {
+ *(.text)
+ *(.rodata)
+ *(.rodata.*)
+ }
+
+ __init_begin = .;
+ . = ALIGN((1 << 12));
+ .init.text : AT(ADDR(.init.text) - 0)
+ {
+ *(.init.text)
+ }
+ .init.data : AT(ADDR(.init.data) - 0)
+ {
+ *(.init.data)
+ }
+ . = ALIGN((1 << 12));
+ __init_end = .;
+
+ . = ALIGN((1 << 13));
+ .data :
+ {
+ *(.data)
+ }
+}
diff --git a/tests/tcg/mips/mips64/printf.c b/tests/tcg/mips/mips64/printf.c
new file mode 100644
index 0000000..cf8676d
--- /dev/null
+++ b/tests/tcg/mips/mips64/printf.c
@@ -0,0 +1,266 @@
+
+typedef unsigned long va_list;
+
+#define ACC 4
+#define __read(source) \
+({ va_list __res; \
+ __asm__ __volatile__( \
+ "move\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+enum format_type {
+ FORMAT_TYPE_NONE,
+ FORMAT_TYPE_HEX,
+ FORMAT_TYPE_ULONG,
+ FORMAT_TYPE_FLOAT
+};
+
+struct printf_spec {
+ char type;
+};
+
+static int format_decode(char *fmt, struct printf_spec *spec)
+{
+ char *start = fmt;
+
+ for (; *fmt ; ++fmt) {
+ if (*fmt == '%') {
+ break;
+ }
+ }
+
+ switch (*++fmt) {
+ case 'x':
+ spec->type = FORMAT_TYPE_HEX;
+ break;
+
+ case 'd':
+ spec->type = FORMAT_TYPE_ULONG;
+ break;
+
+ case 'f':
+ spec->type = FORMAT_TYPE_FLOAT;
+ break;
+
+ default:
+ spec->type = FORMAT_TYPE_NONE;
+ }
+
+ return ++fmt - start;
+}
+
+void *memcpy(void *dest, void *src, int n)
+{
+ int i;
+ char *s = src;
+ char *d = dest;
+
+ for (i = 0; i < n; i++) {
+ d[i] = s[i];
+ }
+ return dest;
+}
+
+char *number(char *buf, va_list num)
+{
+ int i;
+ char *str = buf;
+ static char digits[16] = "0123456789abcdef";
+ str = str + sizeof(num) * 2;
+
+ for (i = 0; i < sizeof(num) * 2; i++) {
+ *--str = digits[num & 15];
+ num >>= 4;
+ }
+
+ return buf + sizeof(num) * 2;
+}
+
+char *__number(char *buf, va_list num)
+{
+ int i;
+ va_list mm = num;
+ char *str = buf;
+
+ if (!num) {
+ *str++ = '0';
+ return str;
+ }
+
+ for (i = 0; mm; mm = mm/10, i++) {
+ /* Do nothing. */
+ }
+
+ str = str + i;
+
+ while (num) {
+ *--str = num % 10 + 48;
+ num = num / 10;
+ }
+
+ return str + i;
+}
+
+va_list modf(va_list args, va_list *integer, va_list *num)
+{
+ int i;
+ double dot_v = 0;
+ va_list E, DOT, DOT_V;
+
+ if (!args) {
+ return 0;
+ }
+
+ for (i = 0, args = args << 1 >> 1; i < 52; i++) {
+ if ((args >> i) & 0x1) {
+ break;
+ }
+ }
+
+ *integer = 0;
+
+ if ((args >> 56 != 0x3f) || (args >> 52 == 0x3ff)) {
+ E = (args >> 52) - 1023;
+ DOT = 52 - E - i;
+ DOT_V = args << (12 + E) >> (12 + E) >> i;
+ *integer = ((args << 12 >> 12) >> (i + DOT)) | (1 << E);
+ } else {
+ E = ~((args >> 52) - 1023) + 1;
+ DOT_V = args << 12 >> 12;
+
+ dot_v += 1.0 / (1 << E);
+
+ for (i = 1; i <= 16; i++) {
+ if ((DOT_V >> (52 - i)) & 0x1) {
+ dot_v += 1.0 / (1 << E + i);
+ }
+ }
+
+ for (i = 1, E = 0; i <= ACC; i++) {
+ dot_v *= 10;
+ if (!(va_list)dot_v) {
+ E++;
+ }
+ }
+
+ *num = E;
+
+ return dot_v;
+ }
+
+ if (args & 0xf) {
+ for (i = 1; i <= 16; i++) {
+ if ((DOT_V >> (DOT - i)) & 0x1) {
+ dot_v += 1.0 / (1 << i);
+ }
+ }
+
+ for (i = 1, E = 0; i <= ACC; i++) {
+ dot_v *= 10;
+ if (!(va_list)dot_v) {
+ E++;
+ }
+ }
+
+ *num = E;
+
+ return dot_v;
+ } else if (DOT) {
+ for (i = 1; i <= DOT; i++) {
+ if ((DOT_V >> (DOT - i)) & 0x1) {
+ dot_v += 1.0 / (1 << i);
+ }
+ }
+
+ for (i = 1; i <= ACC; i++) {
+ dot_v = dot_v * 10;
+ }
+
+ return dot_v;
+ }
+
+ return 0;
+}
+
+int vsnprintf(char *buf, int size, char *fmt, va_list args)
+{
+ char *str, *mm;
+ struct printf_spec spec = {0};
+
+ str = mm = buf;
+
+ while (*fmt) {
+ char *old_fmt = fmt;
+ int read = format_decode(fmt, &spec);
+
+ fmt += read;
+
+ switch (spec.type) {
+ case FORMAT_TYPE_NONE: {
+ memcpy(str, old_fmt, read);
+ str += read;
+ break;
+ }
+ case FORMAT_TYPE_HEX: {
+ memcpy(str, old_fmt, read);
+ str = number(str + read, args);
+ for (; *mm ; ++mm) {
+ if (*mm == '%') {
+ *mm = '0';
+ break;
+ }
+ }
+ break;
+ }
+ case FORMAT_TYPE_ULONG: {
+ memcpy(str, old_fmt, read - 2);
+ str = __number(str + read - 2, args);
+ break;
+ }
+ case FORMAT_TYPE_FLOAT: {
+ va_list integer, dot_v, num;
+ dot_v = modf(args, &integer, &num);
+ memcpy(str, old_fmt, read - 2);
+ str += read - 2;
+ if ((args >> 63 & 0x1)) {
+ *str++ = '-';
+ }
+ str = __number(str, integer);
+ if (dot_v) {
+ *str++ = '.';
+ while (num--) {
+ *str++ = '0';
+ }
+ str = __number(str, dot_v);
+ }
+ break;
+ }
+ }
+ }
+ *str = '\0';
+
+ return str - buf;
+}
+
+static void serial_out(char *str)
+{
+ while (*str) {
+ *(char *)0xffffffffb80003f8 = *str++;
+ }
+}
+
+int vprintf(char *fmt, va_list args)
+{
+ int printed_len = 0;
+ static char printf_buf[512];
+ printed_len = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
+ serial_out(printf_buf);
+ return printed_len;
+}
+
+int printf(char *fmt, ...)
+{
+ return vprintf(fmt, __read($5));
+}
diff --git a/tests/tcg/mips/mips64/synci.c b/tests/tcg/mips/mips64/synci.c
new file mode 100644
index 0000000..a737f0d
--- /dev/null
+++ b/tests/tcg/mips/mips64/synci.c
@@ -0,0 +1,32 @@
+#include "io.h"
+
+int main()
+{
+ unsigned long addr, tmp, result = 0;
+ unsigned int addi = 0x21ef0001; /* addi $15, $15, 1 */
+
+ __asm
+ ("move %1, $15\n\t"
+ "move $15, $0\n\t"
+ "dla %0, 1f\n\t"
+ "sw %3, 0(%0)\n\t"
+ "synci 0(%0)\n\t"
+ "nop\n\t"
+ "1:\n\t"
+ "nop\n\t"
+ "move %2, $15\n\t"
+ "move $15, %1\n\t"
+ : "+r"(addr), "+r"(tmp), "=r"(result)
+ : "r"(addi)
+ );
+
+ if (result == 0) {
+ printf("test failed, the copied instruction not run.\n");
+ } else if (result == 1) {
+ printf("test passed\n");
+ } else {
+ printf("unhandled\n");
+ }
+
+ return 0;
+}
--
1.8.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI
2014-07-29 13:48 [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test Dongxue Zhang
@ 2014-07-29 13:48 ` Dongxue Zhang
2014-09-10 15:12 ` Yongbok Kim
2014-09-10 15:13 ` [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test Yongbok Kim
1 sibling, 1 reply; 4+ messages in thread
From: Dongxue Zhang @ 2014-07-29 13:48 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Dongxue Zhang, aurelien
Update OPC_SYNCI with BS_STOP, in order to handle the instructions which saved
in the same TB of the store instruction.
Signed-off-by: Dongxue Zhang <elta.era@gmail.com>
---
target-mips/translate.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index c381366..dc8afcf 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15334,7 +15334,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_SYNCI:
check_insn(ctx, ISA_MIPS32R2);
- /* Treat as NOP. */
+ /* Break the TB to be able to sync copied instructions
+ immediately */
+ ctx->bstate = BS_STOP;
break;
case OPC_BPOSGE32: /* MIPS DSP branch */
#if defined(TARGET_MIPS64)
--
1.8.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI
2014-07-29 13:48 ` [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI Dongxue Zhang
@ 2014-09-10 15:12 ` Yongbok Kim
0 siblings, 0 replies; 4+ messages in thread
From: Yongbok Kim @ 2014-09-10 15:12 UTC (permalink / raw)
To: Dongxue Zhang
Cc: peter.maydell@linaro.org, qemu-devel@nongnu.org,
aurelien@aurel32.net
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Note that there is a microMIPS version of SYNCI, it would be even better if you could update it as well.
Best Regards,
Yongbok Kim
-----Original Message-----
From: qemu-devel-bounces+yongbok.kim=imgtec.com@nongnu.org [mailto:qemu-devel-bounces+yongbok.kim=imgtec.com@nongnu.org] On Behalf Of Dongxue Zhang
Sent: Tuesday, July 29, 2014 2:48 PM
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org; Dongxue Zhang; aurelien@aurel32.net
Subject: [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI
Update OPC_SYNCI with BS_STOP, in order to handle the instructions which saved
in the same TB of the store instruction.
Signed-off-by: Dongxue Zhang <elta.era@gmail.com>
---
target-mips/translate.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index c381366..dc8afcf 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15334,7 +15334,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_SYNCI:
check_insn(ctx, ISA_MIPS32R2);
- /* Treat as NOP. */
+ /* Break the TB to be able to sync copied instructions
+ immediately */
+ ctx->bstate = BS_STOP;
break;
case OPC_BPOSGE32: /* MIPS DSP branch */
#if defined(TARGET_MIPS64)
--
1.8.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test
2014-07-29 13:48 [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test Dongxue Zhang
2014-07-29 13:48 ` [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI Dongxue Zhang
@ 2014-09-10 15:13 ` Yongbok Kim
1 sibling, 0 replies; 4+ messages in thread
From: Yongbok Kim @ 2014-09-10 15:13 UTC (permalink / raw)
To: Dongxue Zhang, qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, aurelien@aurel32.net
Tested-by: Yongbok Kim <yongbok.kim@imgtec.com>
-----Original Message-----
From: qemu-devel-bounces+yongbok.kim=imgtec.com@nongnu.org [mailto:qemu-devel-bounces+yongbok.kim=imgtec.com@nongnu.org] On Behalf Of Dongxue Zhang
Sent: Tuesday, July 29, 2014 2:48 PM
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org; Dongxue Zhang; aurelien@aurel32.net
Subject: [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test
Save code with sw and raise synci. The saved code should be raise.
If the code raised, log 'test passed'.
If the code not raised, log 'test failed, the copied instruction not run'.
Other cases, log 'unhandled'.
The test should log 'test passed'.
Signed-off-by: Dongxue Zhang <elta.era@gmail.com>
---
tests/tcg/mips/mips64/Makefile | 54 ++++++++
tests/tcg/mips/mips64/head.S | 16 +++
tests/tcg/mips/mips64/io.h | 22 +++
tests/tcg/mips/mips64/mips_boot.lds | 31 +++++
tests/tcg/mips/mips64/printf.c | 266 ++++++++++++++++++++++++++++++++++++
tests/tcg/mips/mips64/synci.c | 32 +++++
6 files changed, 421 insertions(+)
create mode 100644 tests/tcg/mips/mips64/Makefile
create mode 100644 tests/tcg/mips/mips64/head.S
create mode 100644 tests/tcg/mips/mips64/io.h
create mode 100644 tests/tcg/mips/mips64/mips_boot.lds
create mode 100644 tests/tcg/mips/mips64/printf.c
create mode 100644 tests/tcg/mips/mips64/synci.c
diff --git a/tests/tcg/mips/mips64/Makefile b/tests/tcg/mips/mips64/Makefile
new file mode 100644
index 0000000..9a222f7
--- /dev/null
+++ b/tests/tcg/mips/mips64/Makefile
@@ -0,0 +1,54 @@
+CROSS_COMPILE ?= mips64el-unknown-linux-gnu-
+
+SIM = qemu-system-mips64el
+SIMFLAGS = -nographic -cpu mips64r2-generic -kernel
+
+AS = $(CROSS_COMPILE)as
+LD = $(CROSS_COMPILE)ld
+CC = $(CROSS_COMPILE)gcc
+AR = $(CROSS_COMPILE)ar
+NM = $(CROSS_COMPILE)nm
+STRIP = $(CROSS_COMPILE)strip
+RANLIB = $(CROSS_COMPILE)ranlib
+OBJCOPY = $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CROSS_COMPILE)objdump
+
+VECTORS_OBJ ?= ./head.o ./printf.o
+
+HEAD_FLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe \
+ -msoft-float -march=mips64 -Wa,-mips64 -Wa,--trap \
+ -msym32 -DKBUILD_64BIT_SYM32 -I./
+
+CFLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -fno-builtin \
+ -pipe -march=mips64r2 -mgp64 -mdspr2 -static -Wa,--trap -msym32 \
+ -DKBUILD_64BIT_SYM32 -I./
+
+LDFLAGS = -T./mips_boot.lds -L./
+FLAGS = -nostdlib -mabi=64 -march=mips64r2 -mgp64 -mdspr2
+
+TESTCASES = synci.tst
+
+all: build
+
+head.o : head.S
+ $(Q)$(CC) $(HEAD_FLAGS) -D"STACK_TOP=0xffffffff80200000" -c $< -o $@
+
+%.o : %.S
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%.tst: %.o $(VECTORS_OBJ)
+ $(CC) $(VECTORS_OBJ) $(FLAGS) $(LDFLAGS) $< -o $@
+
+build: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES)
+
+check: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES)
+ @for case in $(TESTCASES); do \
+ echo $(SIM) $(SIMFLAGS) ./$$case; \
+ $(SIM) $(SIMFLAGS) ./$$case & (sleep 1; killall $(SIM)); \
+ done
+
+clean:
+ $(Q)rm -f *.o *.tst *.a
diff --git a/tests/tcg/mips/mips64/head.S b/tests/tcg/mips/mips64/head.S
new file mode 100644
index 0000000..9a099ae
--- /dev/null
+++ b/tests/tcg/mips/mips64/head.S
@@ -0,0 +1,16 @@
+/*
+ * Startup Code for MIPS64 CPU-core
+ *
+ */
+.text
+.globl _start
+.align 4
+_start:
+ ori $2, $2, 0xffff
+ sll $2, $2, 16
+ ori $2, $2, 0xffff
+ mtc0 $2, $12, 0
+ jal main
+
+end:
+ b end
diff --git a/tests/tcg/mips/mips64/io.h b/tests/tcg/mips/mips64/io.h
new file mode 100644
index 0000000..b7db61d
--- /dev/null
+++ b/tests/tcg/mips/mips64/io.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+extern int printf(const char *fmt, ...);
+extern unsigned long get_ticks(void);
+
+#define _read(source) \
+({ unsigned long __res; \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __read(source) \
+({ unsigned long __res; \
+ __asm__ __volatile__( \
+ "move\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#endif
diff --git a/tests/tcg/mips/mips64/mips_boot.lds b/tests/tcg/mips/mips64/mips_boot.lds
new file mode 100644
index 0000000..bd7c0c0
--- /dev/null
+++ b/tests/tcg/mips/mips64/mips_boot.lds
@@ -0,0 +1,31 @@
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+ . = 0xffffffff80100000;
+ . = ALIGN((1 << 13));
+ .text :
+ {
+ *(.text)
+ *(.rodata)
+ *(.rodata.*)
+ }
+
+ __init_begin = .;
+ . = ALIGN((1 << 12));
+ .init.text : AT(ADDR(.init.text) - 0)
+ {
+ *(.init.text)
+ }
+ .init.data : AT(ADDR(.init.data) - 0)
+ {
+ *(.init.data)
+ }
+ . = ALIGN((1 << 12));
+ __init_end = .;
+
+ . = ALIGN((1 << 13));
+ .data :
+ {
+ *(.data)
+ }
+}
diff --git a/tests/tcg/mips/mips64/printf.c b/tests/tcg/mips/mips64/printf.c
new file mode 100644
index 0000000..cf8676d
--- /dev/null
+++ b/tests/tcg/mips/mips64/printf.c
@@ -0,0 +1,266 @@
+
+typedef unsigned long va_list;
+
+#define ACC 4
+#define __read(source) \
+({ va_list __res; \
+ __asm__ __volatile__( \
+ "move\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+enum format_type {
+ FORMAT_TYPE_NONE,
+ FORMAT_TYPE_HEX,
+ FORMAT_TYPE_ULONG,
+ FORMAT_TYPE_FLOAT
+};
+
+struct printf_spec {
+ char type;
+};
+
+static int format_decode(char *fmt, struct printf_spec *spec)
+{
+ char *start = fmt;
+
+ for (; *fmt ; ++fmt) {
+ if (*fmt == '%') {
+ break;
+ }
+ }
+
+ switch (*++fmt) {
+ case 'x':
+ spec->type = FORMAT_TYPE_HEX;
+ break;
+
+ case 'd':
+ spec->type = FORMAT_TYPE_ULONG;
+ break;
+
+ case 'f':
+ spec->type = FORMAT_TYPE_FLOAT;
+ break;
+
+ default:
+ spec->type = FORMAT_TYPE_NONE;
+ }
+
+ return ++fmt - start;
+}
+
+void *memcpy(void *dest, void *src, int n)
+{
+ int i;
+ char *s = src;
+ char *d = dest;
+
+ for (i = 0; i < n; i++) {
+ d[i] = s[i];
+ }
+ return dest;
+}
+
+char *number(char *buf, va_list num)
+{
+ int i;
+ char *str = buf;
+ static char digits[16] = "0123456789abcdef";
+ str = str + sizeof(num) * 2;
+
+ for (i = 0; i < sizeof(num) * 2; i++) {
+ *--str = digits[num & 15];
+ num >>= 4;
+ }
+
+ return buf + sizeof(num) * 2;
+}
+
+char *__number(char *buf, va_list num)
+{
+ int i;
+ va_list mm = num;
+ char *str = buf;
+
+ if (!num) {
+ *str++ = '0';
+ return str;
+ }
+
+ for (i = 0; mm; mm = mm/10, i++) {
+ /* Do nothing. */
+ }
+
+ str = str + i;
+
+ while (num) {
+ *--str = num % 10 + 48;
+ num = num / 10;
+ }
+
+ return str + i;
+}
+
+va_list modf(va_list args, va_list *integer, va_list *num)
+{
+ int i;
+ double dot_v = 0;
+ va_list E, DOT, DOT_V;
+
+ if (!args) {
+ return 0;
+ }
+
+ for (i = 0, args = args << 1 >> 1; i < 52; i++) {
+ if ((args >> i) & 0x1) {
+ break;
+ }
+ }
+
+ *integer = 0;
+
+ if ((args >> 56 != 0x3f) || (args >> 52 == 0x3ff)) {
+ E = (args >> 52) - 1023;
+ DOT = 52 - E - i;
+ DOT_V = args << (12 + E) >> (12 + E) >> i;
+ *integer = ((args << 12 >> 12) >> (i + DOT)) | (1 << E);
+ } else {
+ E = ~((args >> 52) - 1023) + 1;
+ DOT_V = args << 12 >> 12;
+
+ dot_v += 1.0 / (1 << E);
+
+ for (i = 1; i <= 16; i++) {
+ if ((DOT_V >> (52 - i)) & 0x1) {
+ dot_v += 1.0 / (1 << E + i);
+ }
+ }
+
+ for (i = 1, E = 0; i <= ACC; i++) {
+ dot_v *= 10;
+ if (!(va_list)dot_v) {
+ E++;
+ }
+ }
+
+ *num = E;
+
+ return dot_v;
+ }
+
+ if (args & 0xf) {
+ for (i = 1; i <= 16; i++) {
+ if ((DOT_V >> (DOT - i)) & 0x1) {
+ dot_v += 1.0 / (1 << i);
+ }
+ }
+
+ for (i = 1, E = 0; i <= ACC; i++) {
+ dot_v *= 10;
+ if (!(va_list)dot_v) {
+ E++;
+ }
+ }
+
+ *num = E;
+
+ return dot_v;
+ } else if (DOT) {
+ for (i = 1; i <= DOT; i++) {
+ if ((DOT_V >> (DOT - i)) & 0x1) {
+ dot_v += 1.0 / (1 << i);
+ }
+ }
+
+ for (i = 1; i <= ACC; i++) {
+ dot_v = dot_v * 10;
+ }
+
+ return dot_v;
+ }
+
+ return 0;
+}
+
+int vsnprintf(char *buf, int size, char *fmt, va_list args)
+{
+ char *str, *mm;
+ struct printf_spec spec = {0};
+
+ str = mm = buf;
+
+ while (*fmt) {
+ char *old_fmt = fmt;
+ int read = format_decode(fmt, &spec);
+
+ fmt += read;
+
+ switch (spec.type) {
+ case FORMAT_TYPE_NONE: {
+ memcpy(str, old_fmt, read);
+ str += read;
+ break;
+ }
+ case FORMAT_TYPE_HEX: {
+ memcpy(str, old_fmt, read);
+ str = number(str + read, args);
+ for (; *mm ; ++mm) {
+ if (*mm == '%') {
+ *mm = '0';
+ break;
+ }
+ }
+ break;
+ }
+ case FORMAT_TYPE_ULONG: {
+ memcpy(str, old_fmt, read - 2);
+ str = __number(str + read - 2, args);
+ break;
+ }
+ case FORMAT_TYPE_FLOAT: {
+ va_list integer, dot_v, num;
+ dot_v = modf(args, &integer, &num);
+ memcpy(str, old_fmt, read - 2);
+ str += read - 2;
+ if ((args >> 63 & 0x1)) {
+ *str++ = '-';
+ }
+ str = __number(str, integer);
+ if (dot_v) {
+ *str++ = '.';
+ while (num--) {
+ *str++ = '0';
+ }
+ str = __number(str, dot_v);
+ }
+ break;
+ }
+ }
+ }
+ *str = '\0';
+
+ return str - buf;
+}
+
+static void serial_out(char *str)
+{
+ while (*str) {
+ *(char *)0xffffffffb80003f8 = *str++;
+ }
+}
+
+int vprintf(char *fmt, va_list args)
+{
+ int printed_len = 0;
+ static char printf_buf[512];
+ printed_len = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
+ serial_out(printf_buf);
+ return printed_len;
+}
+
+int printf(char *fmt, ...)
+{
+ return vprintf(fmt, __read($5));
+}
diff --git a/tests/tcg/mips/mips64/synci.c b/tests/tcg/mips/mips64/synci.c
new file mode 100644
index 0000000..a737f0d
--- /dev/null
+++ b/tests/tcg/mips/mips64/synci.c
@@ -0,0 +1,32 @@
+#include "io.h"
+
+int main()
+{
+ unsigned long addr, tmp, result = 0;
+ unsigned int addi = 0x21ef0001; /* addi $15, $15, 1 */
+
+ __asm
+ ("move %1, $15\n\t"
+ "move $15, $0\n\t"
+ "dla %0, 1f\n\t"
+ "sw %3, 0(%0)\n\t"
+ "synci 0(%0)\n\t"
+ "nop\n\t"
+ "1:\n\t"
+ "nop\n\t"
+ "move %2, $15\n\t"
+ "move $15, %1\n\t"
+ : "+r"(addr), "+r"(tmp), "=r"(result)
+ : "r"(addi)
+ );
+
+ if (result == 0) {
+ printf("test failed, the copied instruction not run.\n");
+ } else if (result == 1) {
+ printf("test passed\n");
+ } else {
+ printf("unhandled\n");
+ }
+
+ return 0;
+}
--
1.8.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-09-10 15:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-29 13:48 [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test Dongxue Zhang
2014-07-29 13:48 ` [Qemu-devel] [PATCH 2/2] target-mips/translate.c: Update OPC_SYNCI Dongxue Zhang
2014-09-10 15:12 ` Yongbok Kim
2014-09-10 15:13 ` [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test Yongbok Kim
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).