Merge branch 'master' into el6
Why is there no git merge -s theirs :(
This commit is contained in:
commit
d9f9605999
19
.gitignore
vendored
19
.gitignore
vendored
@ -1 +1,18 @@
|
||||
qemu-kvm-*.tar.gz
|
||||
qemu-kvm-0.13.0-b81fe95.tar.gz
|
||||
qemu-kvm-0.13.0-25fdf4a.tar.gz
|
||||
/qemu-kvm-0.13.0-rc1.tar.gz
|
||||
/qemu-kvm-0.13.0.tar.gz
|
||||
/qemu-kvm-0.14.0-3593e6b.tar.gz
|
||||
/qemu-kvm-0.14.0-7aa8c46.tar.gz
|
||||
/qemu-kvm-0.15.0-525e3df.tar.gz
|
||||
/qemu-kvm-0.15.0-fda1906.tar.gz
|
||||
/qemu-kvm-0.15.0-59fadcc.tar.gz
|
||||
/qemu-kvm-0.15.0-0af4922.tar.gz
|
||||
/qemu-kvm-0.15.0.tar.gz
|
||||
/qemu-kvm-0.15.1.tar.gz
|
||||
/qemu-kvm-1.1.0.tar.gz
|
||||
/qemu-kvm-1.1.1.tar.gz
|
||||
/qemu-1.2-0.1.20120806git3e430569.fc18.src.rpm
|
||||
/qemu-kvm-1.2-3e430569.tar.gz
|
||||
/qemu-kvm-1.2.0-rc1.tar.gz
|
||||
/qemu-kvm-1.2.0.tar.gz
|
||||
|
@ -1,53 +0,0 @@
|
||||
From c0c1147350005b47068285a288f848cf75eb60c6 Mon Sep 17 00:00:00 2001
|
||||
From: Christoph Hellwig <hch@lst.de>
|
||||
Date: Tue, 26 Jan 2010 14:49:08 +0100
|
||||
Subject: [PATCH] block: avoid creating too large iovecs in multiwrite_merge
|
||||
|
||||
If we go over the maximum number of iovecs support by syscall we get
|
||||
back EINVAL from the kernel which translate to I/O errors for the guest.
|
||||
|
||||
Add a MAX_IOV defintion for platforms that don't have it. For now we use
|
||||
the same 1024 define that's used on Linux and various other platforms,
|
||||
but until the windows block backend implements some kind of vectored I/O
|
||||
it doesn't matter.
|
||||
|
||||
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
||||
---
|
||||
block.c | 4 ++++
|
||||
qemu-common.h | 4 ++++
|
||||
2 files changed, 8 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/block.c b/block.c
|
||||
index 97af3f5..9697dc9 100644
|
||||
--- a/block.c
|
||||
+++ b/block.c
|
||||
@@ -1669,6 +1669,10 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
|
||||
merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
|
||||
}
|
||||
|
||||
+ if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
|
||||
+ merge = 0;
|
||||
+ }
|
||||
+
|
||||
if (merge) {
|
||||
size_t size;
|
||||
QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));
|
||||
diff --git a/qemu-common.h b/qemu-common.h
|
||||
index 1c5c0b2..b604ddf 100644
|
||||
--- a/qemu-common.h
|
||||
+++ b/qemu-common.h
|
||||
@@ -54,6 +54,10 @@ struct iovec {
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
+/*
|
||||
+ * Use the same value as Linux for now.
|
||||
+ */
|
||||
+#define IOV_MAX 1024
|
||||
#else
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
--
|
||||
1.6.6.1
|
||||
|
183
0001-target-xtensa-convert-host-errno-values-to-guest.patch
Normal file
183
0001-target-xtensa-convert-host-errno-values-to-guest.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From 707f294ca28977968fb85bf36f10c6b37b16f557 Mon Sep 17 00:00:00 2001
|
||||
From: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Date: Wed, 29 Aug 2012 23:54:25 +0400
|
||||
Subject: [PATCH] target-xtensa: convert host errno values to guest
|
||||
|
||||
Guest errno values are taken from the newlib. Convert only those errno
|
||||
values that can be returned from used system calls.
|
||||
|
||||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-xtensa/xtensa-semi.c | 106 ++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 98 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
|
||||
index 6d001c2..e745bef 100644
|
||||
--- a/target-xtensa/xtensa-semi.c
|
||||
+++ b/target-xtensa/xtensa-semi.c
|
||||
@@ -54,6 +54,96 @@ enum {
|
||||
SELECT_ONE_EXCEPT = 3,
|
||||
};
|
||||
|
||||
+enum {
|
||||
+ TARGET_EPERM = 1,
|
||||
+ TARGET_ENOENT = 2,
|
||||
+ TARGET_ESRCH = 3,
|
||||
+ TARGET_EINTR = 4,
|
||||
+ TARGET_EIO = 5,
|
||||
+ TARGET_ENXIO = 6,
|
||||
+ TARGET_E2BIG = 7,
|
||||
+ TARGET_ENOEXEC = 8,
|
||||
+ TARGET_EBADF = 9,
|
||||
+ TARGET_ECHILD = 10,
|
||||
+ TARGET_EAGAIN = 11,
|
||||
+ TARGET_ENOMEM = 12,
|
||||
+ TARGET_EACCES = 13,
|
||||
+ TARGET_EFAULT = 14,
|
||||
+ TARGET_ENOTBLK = 15,
|
||||
+ TARGET_EBUSY = 16,
|
||||
+ TARGET_EEXIST = 17,
|
||||
+ TARGET_EXDEV = 18,
|
||||
+ TARGET_ENODEV = 19,
|
||||
+ TARGET_ENOTDIR = 20,
|
||||
+ TARGET_EISDIR = 21,
|
||||
+ TARGET_EINVAL = 22,
|
||||
+ TARGET_ENFILE = 23,
|
||||
+ TARGET_EMFILE = 24,
|
||||
+ TARGET_ENOTTY = 25,
|
||||
+ TARGET_ETXTBSY = 26,
|
||||
+ TARGET_EFBIG = 27,
|
||||
+ TARGET_ENOSPC = 28,
|
||||
+ TARGET_ESPIPE = 29,
|
||||
+ TARGET_EROFS = 30,
|
||||
+ TARGET_EMLINK = 31,
|
||||
+ TARGET_EPIPE = 32,
|
||||
+ TARGET_EDOM = 33,
|
||||
+ TARGET_ERANGE = 34,
|
||||
+ TARGET_ENOSYS = 88,
|
||||
+ TARGET_ELOOP = 92,
|
||||
+};
|
||||
+
|
||||
+static uint32_t errno_h2g(int host_errno)
|
||||
+{
|
||||
+ static const uint32_t guest_errno[] = {
|
||||
+ [EPERM] = TARGET_EPERM,
|
||||
+ [ENOENT] = TARGET_ENOENT,
|
||||
+ [ESRCH] = TARGET_ESRCH,
|
||||
+ [EINTR] = TARGET_EINTR,
|
||||
+ [EIO] = TARGET_EIO,
|
||||
+ [ENXIO] = TARGET_ENXIO,
|
||||
+ [E2BIG] = TARGET_E2BIG,
|
||||
+ [ENOEXEC] = TARGET_ENOEXEC,
|
||||
+ [EBADF] = TARGET_EBADF,
|
||||
+ [ECHILD] = TARGET_ECHILD,
|
||||
+ [EAGAIN] = TARGET_EAGAIN,
|
||||
+ [ENOMEM] = TARGET_ENOMEM,
|
||||
+ [EACCES] = TARGET_EACCES,
|
||||
+ [EFAULT] = TARGET_EFAULT,
|
||||
+ [ENOTBLK] = TARGET_ENOTBLK,
|
||||
+ [EBUSY] = TARGET_EBUSY,
|
||||
+ [EEXIST] = TARGET_EEXIST,
|
||||
+ [EXDEV] = TARGET_EXDEV,
|
||||
+ [ENODEV] = TARGET_ENODEV,
|
||||
+ [ENOTDIR] = TARGET_ENOTDIR,
|
||||
+ [EISDIR] = TARGET_EISDIR,
|
||||
+ [EINVAL] = TARGET_EINVAL,
|
||||
+ [ENFILE] = TARGET_ENFILE,
|
||||
+ [EMFILE] = TARGET_EMFILE,
|
||||
+ [ENOTTY] = TARGET_ENOTTY,
|
||||
+ [ETXTBSY] = TARGET_ETXTBSY,
|
||||
+ [EFBIG] = TARGET_EFBIG,
|
||||
+ [ENOSPC] = TARGET_ENOSPC,
|
||||
+ [ESPIPE] = TARGET_ESPIPE,
|
||||
+ [EROFS] = TARGET_EROFS,
|
||||
+ [EMLINK] = TARGET_EMLINK,
|
||||
+ [EPIPE] = TARGET_EPIPE,
|
||||
+ [EDOM] = TARGET_EDOM,
|
||||
+ [ERANGE] = TARGET_ERANGE,
|
||||
+ [ENOSYS] = TARGET_ENOSYS,
|
||||
+ [ELOOP] = TARGET_ELOOP,
|
||||
+ };
|
||||
+
|
||||
+ if (host_errno == 0) {
|
||||
+ return 0;
|
||||
+ } else if (host_errno > 0 && host_errno < ARRAY_SIZE(guest_errno) &&
|
||||
+ guest_errno[host_errno]) {
|
||||
+ return guest_errno[host_errno];
|
||||
+ } else {
|
||||
+ return TARGET_EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void HELPER(simcall)(CPUXtensaState *env)
|
||||
{
|
||||
uint32_t *regs = env->regs;
|
||||
@@ -87,14 +177,14 @@ void HELPER(simcall)(CPUXtensaState *env)
|
||||
regs[2] = is_write ?
|
||||
write(fd, buf, io_sz) :
|
||||
read(fd, buf, io_sz);
|
||||
- regs[3] = errno;
|
||||
+ regs[3] = errno_h2g(errno);
|
||||
cpu_physical_memory_unmap(buf, sz, is_write, sz);
|
||||
if (regs[2] == -1) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
regs[2] = -1;
|
||||
- regs[3] = EINVAL;
|
||||
+ regs[3] = TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,10 +207,10 @@ void HELPER(simcall)(CPUXtensaState *env)
|
||||
|
||||
if (rc == 0 && i < ARRAY_SIZE(name)) {
|
||||
regs[2] = open(name, regs[4], regs[5]);
|
||||
- regs[3] = errno;
|
||||
+ regs[3] = errno_h2g(errno);
|
||||
} else {
|
||||
regs[2] = -1;
|
||||
- regs[3] = EINVAL;
|
||||
+ regs[3] = TARGET_EINVAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -130,13 +220,13 @@ void HELPER(simcall)(CPUXtensaState *env)
|
||||
regs[2] = regs[3] = 0;
|
||||
} else {
|
||||
regs[2] = close(regs[3]);
|
||||
- regs[3] = errno;
|
||||
+ regs[3] = errno_h2g(errno);
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_lseek:
|
||||
regs[2] = lseek(regs[3], (off_t)(int32_t)regs[4], regs[5]);
|
||||
- regs[3] = errno;
|
||||
+ regs[3] = errno_h2g(errno);
|
||||
break;
|
||||
|
||||
case TARGET_SYS_select_one:
|
||||
@@ -163,7 +253,7 @@ void HELPER(simcall)(CPUXtensaState *env)
|
||||
rq == SELECT_ONE_WRITE ? &fdset : NULL,
|
||||
rq == SELECT_ONE_EXCEPT ? &fdset : NULL,
|
||||
target_tv ? &tv : NULL);
|
||||
- regs[3] = errno;
|
||||
+ regs[3] = errno_h2g(errno);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -219,7 +309,7 @@ void HELPER(simcall)(CPUXtensaState *env)
|
||||
default:
|
||||
qemu_log("%s(%d): not implemented\n", __func__, regs[2]);
|
||||
regs[2] = -1;
|
||||
- regs[3] = ENOSYS;
|
||||
+ regs[3] = TARGET_ENOSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -1,100 +0,0 @@
|
||||
From baaa7b9f8498f73d14c8457e0150d0dfdcdbd245 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Quintela <quintela@redhat.com>
|
||||
Date: Tue, 9 Mar 2010 23:58:50 +0100
|
||||
Subject: [PATCH] migration: Clear fd also in error cases
|
||||
|
||||
Not clearing the fd and closing the file makes qemu spin using 100%CPU
|
||||
after incoming migration error.
|
||||
|
||||
See for instance bug:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=518032
|
||||
|
||||
Signed-off-by: Juan Quintela <quintela@trasno.org>
|
||||
---
|
||||
migration-exec.c | 3 +--
|
||||
migration-fd.c | 3 +--
|
||||
migration-tcp.c | 5 ++---
|
||||
migration-unix.c | 5 ++---
|
||||
4 files changed, 6 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/migration-exec.c b/migration-exec.c
|
||||
index 87f645b..e57a55d 100644
|
||||
--- a/migration-exec.c
|
||||
+++ b/migration-exec.c
|
||||
@@ -120,12 +120,11 @@ static void exec_accept_incoming_migration(void *opaque)
|
||||
}
|
||||
qemu_announce_self();
|
||||
dprintf("successfully loaded vm state\n");
|
||||
- /* we've successfully migrated, close the fd */
|
||||
- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
|
||||
if (autostart)
|
||||
vm_start();
|
||||
|
||||
err:
|
||||
+ qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
|
||||
qemu_fclose(f);
|
||||
}
|
||||
|
||||
diff --git a/migration-fd.c b/migration-fd.c
|
||||
index ef7edbc..7325d13 100644
|
||||
--- a/migration-fd.c
|
||||
+++ b/migration-fd.c
|
||||
@@ -113,12 +113,11 @@ static void fd_accept_incoming_migration(void *opaque)
|
||||
}
|
||||
qemu_announce_self();
|
||||
dprintf("successfully loaded vm state\n");
|
||||
- /* we've successfully migrated, close the fd */
|
||||
- qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
|
||||
if (autostart)
|
||||
vm_start();
|
||||
|
||||
err:
|
||||
+ qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
|
||||
qemu_fclose(f);
|
||||
}
|
||||
|
||||
diff --git a/migration-tcp.c b/migration-tcp.c
|
||||
index 2cfa8cb..c328e73 100644
|
||||
--- a/migration-tcp.c
|
||||
+++ b/migration-tcp.c
|
||||
@@ -170,15 +170,14 @@ static void tcp_accept_incoming_migration(void *opaque)
|
||||
qemu_announce_self();
|
||||
dprintf("successfully loaded vm state\n");
|
||||
|
||||
- /* we've successfully migrated, close the server socket */
|
||||
- qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
|
||||
- close(s);
|
||||
if (autostart)
|
||||
vm_start();
|
||||
|
||||
out_fopen:
|
||||
qemu_fclose(f);
|
||||
out:
|
||||
+ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
|
||||
+ close(s);
|
||||
close(c);
|
||||
}
|
||||
|
||||
diff --git a/migration-unix.c b/migration-unix.c
|
||||
index a141dbb..9685c4b 100644
|
||||
--- a/migration-unix.c
|
||||
+++ b/migration-unix.c
|
||||
@@ -176,13 +176,12 @@ static void unix_accept_incoming_migration(void *opaque)
|
||||
qemu_announce_self();
|
||||
dprintf("successfully loaded vm state\n");
|
||||
|
||||
- /* we've successfully migrated, close the server socket */
|
||||
- qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
|
||||
- close(s);
|
||||
|
||||
out_fopen:
|
||||
qemu_fclose(f);
|
||||
out:
|
||||
+ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
|
||||
+ close(s);
|
||||
close(c);
|
||||
}
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
35
0002-target-cris-Fix-buffer-overflow.patch
Normal file
35
0002-target-cris-Fix-buffer-overflow.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 8057ac10e8cba3acb89c11c94f04967306e55a9f Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Weil <sw@weilnetz.de>
|
||||
Date: Fri, 7 Sep 2012 22:36:08 +0200
|
||||
Subject: [PATCH] target-cris: Fix buffer overflow
|
||||
|
||||
Report from smatch:
|
||||
|
||||
target-cris/translate.c:3464 cpu_dump_state(32) error:
|
||||
buffer overflow 'env->sregs' 4 <= 255
|
||||
|
||||
sregs is declared 'uint32_t sregs[4][16]', so the first index must be
|
||||
less than 4 or ARRAY_SIZE(env->sregs).
|
||||
|
||||
Signed-off-by: Stefan Weil <sw@weilnetz.de>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-cris/translate.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/target-cris/translate.c b/target-cris/translate.c
|
||||
index 1ad9ec7..ad31877 100644
|
||||
--- a/target-cris/translate.c
|
||||
+++ b/target-cris/translate.c
|
||||
@@ -3458,7 +3458,7 @@ void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
|
||||
}
|
||||
srs = env->pregs[PR_SRS];
|
||||
cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
|
||||
- if (srs < 256) {
|
||||
+ if (srs < ARRAY_SIZE(env->sregs)) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
cpu_fprintf(f, "s%2.2d=%8.8x ",
|
||||
i, env->sregs[srs][i]);
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -1,61 +0,0 @@
|
||||
From 78a27b6a8f394c5a987c31aaf308e11556280f6a Mon Sep 17 00:00:00 2001
|
||||
From: Cole Robinson <crobinso@redhat.com>
|
||||
Date: Thu, 14 Jan 2010 16:19:40 +0000
|
||||
Subject: [PATCH] raw-posix: Detect CDROM via ioctl on linux
|
||||
|
||||
Current CDROM detection is hardcoded based on source file name.
|
||||
Make this smarter on linux by attempting a CDROM specific ioctl.
|
||||
|
||||
This makes '-cdrom /dev/sr0' succeed with no media present.
|
||||
|
||||
v2:
|
||||
Give ioctl check higher priority than filename check.
|
||||
|
||||
v3:
|
||||
Actually initialize 'prio' variable.
|
||||
Check for ioctl success rather than absence of specific failure.
|
||||
|
||||
v4:
|
||||
Explicitly mention that change is linux specific.
|
||||
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
|
||||
---
|
||||
block/raw-posix.c | 20 ++++++++++++++++++--
|
||||
1 files changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/block/raw-posix.c b/block/raw-posix.c
|
||||
index c204cf9..1c777a1 100644
|
||||
--- a/block/raw-posix.c
|
||||
+++ b/block/raw-posix.c
|
||||
@@ -1142,9 +1142,25 @@ static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
|
||||
static int cdrom_probe_device(const char *filename)
|
||||
{
|
||||
+ int fd, ret;
|
||||
+ int prio = 0;
|
||||
+
|
||||
if (strstart(filename, "/dev/cd", NULL))
|
||||
- return 100;
|
||||
- return 0;
|
||||
+ prio = 50;
|
||||
+
|
||||
+ fd = open(filename, O_RDONLY | O_NONBLOCK);
|
||||
+ if (fd < 0) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* Attempt to detect via a CDROM specific ioctl */
|
||||
+ ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
|
||||
+ if (ret >= 0)
|
||||
+ prio = 100;
|
||||
+
|
||||
+ close(fd);
|
||||
+out:
|
||||
+ return prio;
|
||||
}
|
||||
|
||||
static int cdrom_is_inserted(BlockDriverState *bs)
|
||||
--
|
||||
1.6.6.1
|
||||
|
64
0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch
Normal file
64
0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 33e25a4a6c6dc7632b15ee50637d33b4c3cf729e Mon Sep 17 00:00:00 2001
|
||||
From: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Date: Thu, 6 Sep 2012 04:36:46 +0400
|
||||
Subject: [PATCH] target-xtensa: fix missing errno codes for mingw32
|
||||
|
||||
Put the following errno value mappings under #ifdef:
|
||||
|
||||
xtensa-semi.c: In function 'errno_h2g':
|
||||
xtensa-semi.c:113: error: 'ENOTBLK' undeclared (first use in this function)
|
||||
xtensa-semi.c:113: error: (Each undeclared identifier is reported only once
|
||||
xtensa-semi.c:113: error: for each function it appears in.)
|
||||
xtensa-semi.c:113: error: array index in initializer not of integer type
|
||||
xtensa-semi.c:113: error: (near initialization for 'guest_errno')
|
||||
xtensa-semi.c:124: error: 'ETXTBSY' undeclared (first use in this function)
|
||||
xtensa-semi.c:124: error: array index in initializer not of integer type
|
||||
xtensa-semi.c:124: error: (near initialization for 'guest_errno')
|
||||
xtensa-semi.c:134: error: 'ELOOP' undeclared (first use in this function)
|
||||
xtensa-semi.c:134: error: array index in initializer not of integer type
|
||||
xtensa-semi.c:134: error: (near initialization for 'guest_errno')
|
||||
|
||||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-xtensa/xtensa-semi.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
|
||||
index e745bef..52be07a 100644
|
||||
--- a/target-xtensa/xtensa-semi.c
|
||||
+++ b/target-xtensa/xtensa-semi.c
|
||||
@@ -110,7 +110,9 @@ static uint32_t errno_h2g(int host_errno)
|
||||
[ENOMEM] = TARGET_ENOMEM,
|
||||
[EACCES] = TARGET_EACCES,
|
||||
[EFAULT] = TARGET_EFAULT,
|
||||
+#ifdef ENOTBLK
|
||||
[ENOTBLK] = TARGET_ENOTBLK,
|
||||
+#endif
|
||||
[EBUSY] = TARGET_EBUSY,
|
||||
[EEXIST] = TARGET_EEXIST,
|
||||
[EXDEV] = TARGET_EXDEV,
|
||||
@@ -121,7 +123,9 @@ static uint32_t errno_h2g(int host_errno)
|
||||
[ENFILE] = TARGET_ENFILE,
|
||||
[EMFILE] = TARGET_EMFILE,
|
||||
[ENOTTY] = TARGET_ENOTTY,
|
||||
+#ifdef ETXTBSY
|
||||
[ETXTBSY] = TARGET_ETXTBSY,
|
||||
+#endif
|
||||
[EFBIG] = TARGET_EFBIG,
|
||||
[ENOSPC] = TARGET_ENOSPC,
|
||||
[ESPIPE] = TARGET_ESPIPE,
|
||||
@@ -131,7 +135,9 @@ static uint32_t errno_h2g(int host_errno)
|
||||
[EDOM] = TARGET_EDOM,
|
||||
[ERANGE] = TARGET_ERANGE,
|
||||
[ENOSYS] = TARGET_ENOSYS,
|
||||
+#ifdef ELOOP
|
||||
[ELOOP] = TARGET_ELOOP,
|
||||
+#endif
|
||||
};
|
||||
|
||||
if (host_errno == 0) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
133
0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch
Normal file
133
0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From 5e955b895d4a92cdc49c7b4e76284483d49aa4b8 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 7 Sep 2012 17:13:28 +0200
|
||||
Subject: [PATCH] target-sparc: fix fcmp{s,d,q} instructions wrt exception
|
||||
|
||||
fcmp{s,d,q} instructions are supposed to ignore quiet NaN (contrary to
|
||||
the fcmpe{s,d,q} instructions), but the current code is wrongly setting
|
||||
the NV exception in that case. Moreover the current code is duplicated:
|
||||
first the arguments are checked for NaN to generate an exception, and
|
||||
later in case the comparison is unordered (which can only happens if one
|
||||
of the argument is a NaN), the same check is done to generate an
|
||||
exception.
|
||||
|
||||
Fix that by calling clear_float_exceptions() followed by
|
||||
check_ieee_exceptions() as for the other floating point instructions.
|
||||
Use the _compare_quiet functions for fcmp{s,d,q} and the _compare ones
|
||||
for fcmpe{s,d,q}. Simplify the flag setting by not clearing a flag that
|
||||
is set the line just below.
|
||||
|
||||
This fix allows the math glibc testsuite to pass.
|
||||
|
||||
Cc: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-sparc/fop_helper.c | 67 +++++++++++++++++++----------------------------
|
||||
1 file changed, 27 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c
|
||||
index 9c64ef8..f4b62a5 100644
|
||||
--- a/target-sparc/fop_helper.c
|
||||
+++ b/target-sparc/fop_helper.c
|
||||
@@ -334,34 +334,28 @@ void helper_fsqrtq(CPUSPARCState *env)
|
||||
}
|
||||
|
||||
#define GEN_FCMP(name, size, reg1, reg2, FS, E) \
|
||||
- void glue(helper_, name) (CPUSPARCState *env) \
|
||||
+ void glue(helper_, name) (CPUSPARCState *env) \
|
||||
{ \
|
||||
- env->fsr &= FSR_FTT_NMASK; \
|
||||
- if (E && (glue(size, _is_any_nan)(reg1) || \
|
||||
- glue(size, _is_any_nan)(reg2)) && \
|
||||
- (env->fsr & FSR_NVM)) { \
|
||||
- env->fsr |= FSR_NVC; \
|
||||
- env->fsr |= FSR_FTT_IEEE_EXCP; \
|
||||
- helper_raise_exception(env, TT_FP_EXCP); \
|
||||
+ int ret; \
|
||||
+ clear_float_exceptions(env); \
|
||||
+ if (E) { \
|
||||
+ ret = glue(size, _compare)(reg1, reg2, &env->fp_status); \
|
||||
+ } else { \
|
||||
+ ret = glue(size, _compare_quiet)(reg1, reg2, \
|
||||
+ &env->fp_status); \
|
||||
} \
|
||||
- switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \
|
||||
+ check_ieee_exceptions(env); \
|
||||
+ switch (ret) { \
|
||||
case float_relation_unordered: \
|
||||
- if ((env->fsr & FSR_NVM)) { \
|
||||
- env->fsr |= FSR_NVC; \
|
||||
- env->fsr |= FSR_FTT_IEEE_EXCP; \
|
||||
- helper_raise_exception(env, TT_FP_EXCP); \
|
||||
- } else { \
|
||||
- env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
- env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
|
||||
- env->fsr |= FSR_NVA; \
|
||||
- } \
|
||||
+ env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
|
||||
+ env->fsr |= FSR_NVA; \
|
||||
break; \
|
||||
case float_relation_less: \
|
||||
- env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
+ env->fsr &= ~(FSR_FCC1) << FS; \
|
||||
env->fsr |= FSR_FCC0 << FS; \
|
||||
break; \
|
||||
case float_relation_greater: \
|
||||
- env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
+ env->fsr &= ~(FSR_FCC0) << FS; \
|
||||
env->fsr |= FSR_FCC1 << FS; \
|
||||
break; \
|
||||
default: \
|
||||
@@ -370,34 +364,27 @@ void helper_fsqrtq(CPUSPARCState *env)
|
||||
} \
|
||||
}
|
||||
#define GEN_FCMP_T(name, size, FS, E) \
|
||||
- void glue(helper_, name)(CPUSPARCState *env, size src1, size src2) \
|
||||
+ void glue(helper_, name)(CPUSPARCState *env, size src1, size src2) \
|
||||
{ \
|
||||
- env->fsr &= FSR_FTT_NMASK; \
|
||||
- if (E && (glue(size, _is_any_nan)(src1) || \
|
||||
- glue(size, _is_any_nan)(src2)) && \
|
||||
- (env->fsr & FSR_NVM)) { \
|
||||
- env->fsr |= FSR_NVC; \
|
||||
- env->fsr |= FSR_FTT_IEEE_EXCP; \
|
||||
- helper_raise_exception(env, TT_FP_EXCP); \
|
||||
+ int ret; \
|
||||
+ clear_float_exceptions(env); \
|
||||
+ if (E) { \
|
||||
+ ret = glue(size, _compare)(src1, src2, &env->fp_status); \
|
||||
+ } else { \
|
||||
+ ret = glue(size, _compare_quiet)(src1, src2, \
|
||||
+ &env->fp_status); \
|
||||
} \
|
||||
- switch (glue(size, _compare) (src1, src2, &env->fp_status)) { \
|
||||
+ check_ieee_exceptions(env); \
|
||||
+ switch (ret) { \
|
||||
case float_relation_unordered: \
|
||||
- if ((env->fsr & FSR_NVM)) { \
|
||||
- env->fsr |= FSR_NVC; \
|
||||
- env->fsr |= FSR_FTT_IEEE_EXCP; \
|
||||
- helper_raise_exception(env, TT_FP_EXCP); \
|
||||
- } else { \
|
||||
- env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
- env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
|
||||
- env->fsr |= FSR_NVA; \
|
||||
- } \
|
||||
+ env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
|
||||
break; \
|
||||
case float_relation_less: \
|
||||
- env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
+ env->fsr &= ~(FSR_FCC1 << FS); \
|
||||
env->fsr |= FSR_FCC0 << FS; \
|
||||
break; \
|
||||
case float_relation_greater: \
|
||||
- env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
|
||||
+ env->fsr &= ~(FSR_FCC0 << FS); \
|
||||
env->fsr |= FSR_FCC1 << FS; \
|
||||
break; \
|
||||
default: \
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 67e6ab59a04db24c4c947b7653d0f9e3078192bd Mon Sep 17 00:00:00 2001
|
||||
From: Christian Krause <chkr@plauener.de>
|
||||
Date: Sun, 24 Jan 2010 16:34:52 +0000
|
||||
Subject: [PATCH] usb-linux: increase buffer for USB control requests
|
||||
|
||||
The WLAN USB stick ZyXEL NWD271N (0586:3417) uses very large
|
||||
usb control transfers of more than 2048 bytes which won't fit
|
||||
into the buffer of the ctrl_struct. This results in an error message
|
||||
"husb: ctrl buffer too small" and a non-working device.
|
||||
Increasing the buffer size to 8192 seems to be a safe choice.
|
||||
|
||||
Signed-off-by: Christian Krause <chkr@plauener.de>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
---
|
||||
usb-linux.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/usb-linux.c b/usb-linux.c
|
||||
index 5619b30..e6cd432 100644
|
||||
--- a/usb-linux.c
|
||||
+++ b/usb-linux.c
|
||||
@@ -113,7 +113,7 @@ struct ctrl_struct {
|
||||
uint16_t offset;
|
||||
uint8_t state;
|
||||
struct usb_ctrlrequest req;
|
||||
- uint8_t buffer[2048];
|
||||
+ uint8_t buffer[8192];
|
||||
};
|
||||
|
||||
struct USBAutoFilter {
|
||||
--
|
||||
1.6.6.1
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 048294d62e2d61dfbe1e89d1dadb914371bba010 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Date: Tue, 6 Apr 2010 19:38:51 -0300
|
||||
Subject: [PATCH] net: remove NICInfo.bootable field
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=561078
|
||||
|
||||
It is just set by net_set_boot_mask() and never used. The logic for rom loading
|
||||
changed a lot since this field was introduced. It is not needed anymore.
|
||||
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
---
|
||||
net.c | 1 -
|
||||
net.h | 1 -
|
||||
2 files changed, 0 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/net.c b/net.c
|
||||
index 029b0d7..4030e39 100644
|
||||
--- a/net.c
|
||||
+++ b/net.c
|
||||
@@ -1196,7 +1196,6 @@ void net_set_boot_mask(int net_boot_mask)
|
||||
|
||||
for (i = 0; i < nb_nics; i++) {
|
||||
if (net_boot_mask & (1 << i)) {
|
||||
- nd_table[i].bootable = 1;
|
||||
net_boot_mask &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
diff --git a/net.h b/net.h
|
||||
index 673b355..508d02e 100644
|
||||
--- a/net.h
|
||||
+++ b/net.h
|
||||
@@ -132,7 +132,6 @@ struct NICInfo {
|
||||
VLANState *vlan;
|
||||
VLANClientState *netdev;
|
||||
int used;
|
||||
- int bootable;
|
||||
int nvectors;
|
||||
};
|
||||
|
||||
--
|
||||
1.6.6.1
|
||||
|
1603
0005-target-s390x-fix-style.patch
Normal file
1603
0005-target-s390x-fix-style.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,100 +0,0 @@
|
||||
From a4e7898d9442efc0e9b60d5e50d531effa095b63 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Date: Tue, 6 Apr 2010 19:38:52 -0300
|
||||
Subject: [PATCH] net: remove broken net_set_boot_mask() boot device validation
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=561078
|
||||
|
||||
There are many problems with net_set_boot_mask():
|
||||
|
||||
1) It is broken when using the device model instead of "-net nic". Example:
|
||||
$ qemu-system-x86_64 -device rtl8139,vlan=0,id=net0,mac=52:54:00:82:41:fd,bus=pci.0,addr=0x4 -net user,vlan=0,name=hostnet0 -vnc 0.0.0.0:0 -boot n
|
||||
Cannot boot from non-existent NIC
|
||||
$
|
||||
2) The mask was previously used to set which boot ROMs were supposed to be
|
||||
loaded, but this was changed long time ago. Now all ROM images are loaded,
|
||||
and SeaBIOS takes care of jumping to the right boot entry point depending on
|
||||
the boot settings.
|
||||
3) Interpretation and validation of the boot parameter letters is done on
|
||||
the machine type code. Examples: PC accepts only a,b,c,d,n as valid boot
|
||||
device letters. mac99 accepts only a,b,c,d,e,f.
|
||||
|
||||
As a side-effect of this change, qemu-kvm won't abort anymore if using "-boot n"
|
||||
on a machine with no network devices. Checking if the requested boot device is
|
||||
valid is now a task for the BIOS or the machine-type code.
|
||||
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
---
|
||||
net.c | 19 -------------------
|
||||
net.h | 1 -
|
||||
vl.c | 5 +----
|
||||
3 files changed, 1 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/net.c b/net.c
|
||||
index 4030e39..28b6b43 100644
|
||||
--- a/net.c
|
||||
+++ b/net.c
|
||||
@@ -1187,25 +1187,6 @@ void net_host_device_remove(Monitor *mon, const QDict *qdict)
|
||||
qemu_del_vlan_client(vc);
|
||||
}
|
||||
|
||||
-void net_set_boot_mask(int net_boot_mask)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- /* Only the first four NICs may be bootable */
|
||||
- net_boot_mask = net_boot_mask & 0xF;
|
||||
-
|
||||
- for (i = 0; i < nb_nics; i++) {
|
||||
- if (net_boot_mask & (1 << i)) {
|
||||
- net_boot_mask &= ~(1 << i);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (net_boot_mask) {
|
||||
- fprintf(stderr, "Cannot boot from non-existent NIC\n");
|
||||
- exit(1);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void do_info_network(Monitor *mon)
|
||||
{
|
||||
VLANState *vlan;
|
||||
diff --git a/net.h b/net.h
|
||||
index 508d02e..be0ee12 100644
|
||||
--- a/net.h
|
||||
+++ b/net.h
|
||||
@@ -162,7 +162,6 @@ int net_client_parse(QemuOptsList *opts_list, const char *str);
|
||||
int net_init_clients(void);
|
||||
void net_check_clients(void);
|
||||
void net_cleanup(void);
|
||||
-void net_set_boot_mask(int boot_mask);
|
||||
void net_host_device_add(Monitor *mon, const QDict *qdict);
|
||||
void net_host_device_remove(Monitor *mon, const QDict *qdict);
|
||||
|
||||
diff --git a/vl.c b/vl.c
|
||||
index 59f8084..98d390e 100644
|
||||
--- a/vl.c
|
||||
+++ b/vl.c
|
||||
@@ -4909,7 +4909,7 @@ int main(int argc, char **argv, char **envp)
|
||||
const char *gdbstub_dev = NULL;
|
||||
uint32_t boot_devices_bitmap = 0;
|
||||
int i;
|
||||
- int snapshot, linux_boot, net_boot;
|
||||
+ int snapshot, linux_boot;
|
||||
const char *initrd_filename;
|
||||
const char *kernel_filename, *kernel_cmdline;
|
||||
char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
|
||||
@@ -5948,9 +5948,6 @@ int main(int argc, char **argv, char **envp)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
|
||||
- net_set_boot_mask(net_boot);
|
||||
-
|
||||
/* init the bluetooth world */
|
||||
if (foreach_device_config(DEV_BT, bt_parse))
|
||||
exit(1);
|
||||
--
|
||||
1.6.6.1
|
||||
|
1756
0006-target-s390x-split-FPU-ops.patch
Normal file
1756
0006-target-s390x-split-FPU-ops.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,63 +0,0 @@
|
||||
From fbd17986e80087d0d686c5b13a5b39998c845f2c Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Date: Tue, 6 Apr 2010 19:38:53 -0300
|
||||
Subject: [PATCH] boot: remove unused boot_devices_bitmap variable
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=561078
|
||||
|
||||
In addition to removing the variable, this also renames the parse_bootdevices()
|
||||
function to validate_bootdevices(), as we don't need its return value anymore.
|
||||
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
---
|
||||
vl.c | 8 +++-----
|
||||
1 files changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/vl.c b/vl.c
|
||||
index 98d390e..2c97805 100644
|
||||
--- a/vl.c
|
||||
+++ b/vl.c
|
||||
@@ -2514,7 +2514,7 @@ int qemu_boot_set(const char *boot_devices)
|
||||
return boot_set_handler(boot_set_opaque, boot_devices);
|
||||
}
|
||||
|
||||
-static int parse_bootdevices(char *devices)
|
||||
+static void validate_bootdevices(char *devices)
|
||||
{
|
||||
/* We just do some generic consistency checks */
|
||||
const char *p;
|
||||
@@ -2540,7 +2540,6 @@ static int parse_bootdevices(char *devices)
|
||||
}
|
||||
bitmap |= 1 << (*p - 'a');
|
||||
}
|
||||
- return bitmap;
|
||||
}
|
||||
|
||||
static void restore_boot_devices(void *opaque)
|
||||
@@ -4907,7 +4906,6 @@ static int virtcon_parse(const char *devname)
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
const char *gdbstub_dev = NULL;
|
||||
- uint32_t boot_devices_bitmap = 0;
|
||||
int i;
|
||||
int snapshot, linux_boot;
|
||||
const char *initrd_filename;
|
||||
@@ -5202,13 +5200,13 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
if (legacy ||
|
||||
get_param_value(buf, sizeof(buf), "order", optarg)) {
|
||||
- boot_devices_bitmap = parse_bootdevices(buf);
|
||||
+ validate_bootdevices(buf);
|
||||
pstrcpy(boot_devices, sizeof(boot_devices), buf);
|
||||
}
|
||||
if (!legacy) {
|
||||
if (get_param_value(buf, sizeof(buf),
|
||||
"once", optarg)) {
|
||||
- boot_devices_bitmap |= parse_bootdevices(buf);
|
||||
+ validate_bootdevices(buf);
|
||||
standard_boot_devices = qemu_strdup(boot_devices);
|
||||
pstrcpy(boot_devices, sizeof(boot_devices), buf);
|
||||
qemu_register_reset(restore_boot_devices,
|
||||
--
|
||||
1.6.6.1
|
||||
|
1158
0007-target-s390x-split-condition-code-helpers.patch
Normal file
1158
0007-target-s390x-split-condition-code-helpers.patch
Normal file
File diff suppressed because it is too large
Load Diff
444
0008-target-s390x-split-integer-helpers.patch
Normal file
444
0008-target-s390x-split-integer-helpers.patch
Normal file
@ -0,0 +1,444 @@
|
||||
From e9f67c1f326a995ff0000a08a223435386867d8f Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:33:33 +0000
|
||||
Subject: [PATCH] target-s390x: split integer helpers
|
||||
|
||||
Move integer helpers to int_helper.c.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-s390x/Makefile.objs | 3 +-
|
||||
target-s390x/int_helper.c | 201 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
target-s390x/op_helper.c | 170 --------------------------------------
|
||||
3 files changed, 203 insertions(+), 171 deletions(-)
|
||||
create mode 100644 target-s390x/int_helper.c
|
||||
|
||||
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
|
||||
index f9437d6..e8f66e9 100644
|
||||
--- a/target-s390x/Makefile.objs
|
||||
+++ b/target-s390x/Makefile.objs
|
||||
@@ -1,8 +1,9 @@
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
|
||||
-obj-y += fpu_helper.o cc_helper.o
|
||||
+obj-y += int_helper.o fpu_helper.o cc_helper.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
+$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
|
||||
new file mode 100644
|
||||
index 0000000..e2eeb07
|
||||
--- /dev/null
|
||||
+++ b/target-s390x/int_helper.c
|
||||
@@ -0,0 +1,201 @@
|
||||
+/*
|
||||
+ * S/390 integer helper routines
|
||||
+ *
|
||||
+ * Copyright (c) 2009 Ulrich Hecht
|
||||
+ * Copyright (c) 2009 Alexander Graf
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include "cpu.h"
|
||||
+#include "dyngen-exec.h"
|
||||
+#include "host-utils.h"
|
||||
+#include "helper.h"
|
||||
+
|
||||
+/* #define DEBUG_HELPER */
|
||||
+#ifdef DEBUG_HELPER
|
||||
+#define HELPER_LOG(x...) qemu_log(x)
|
||||
+#else
|
||||
+#define HELPER_LOG(x...)
|
||||
+#endif
|
||||
+
|
||||
+/* 64/64 -> 128 unsigned multiplication */
|
||||
+void HELPER(mlg)(uint32_t r1, uint64_t v2)
|
||||
+{
|
||||
+#if HOST_LONG_BITS == 64 && defined(__GNUC__)
|
||||
+ /* assuming 64-bit hosts have __uint128_t */
|
||||
+ __uint128_t res = (__uint128_t)env->regs[r1 + 1];
|
||||
+
|
||||
+ res *= (__uint128_t)v2;
|
||||
+ env->regs[r1] = (uint64_t)(res >> 64);
|
||||
+ env->regs[r1 + 1] = (uint64_t)res;
|
||||
+#else
|
||||
+ mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+/* 128 -> 64/64 unsigned division */
|
||||
+void HELPER(dlg)(uint32_t r1, uint64_t v2)
|
||||
+{
|
||||
+ uint64_t divisor = v2;
|
||||
+
|
||||
+ if (!env->regs[r1]) {
|
||||
+ /* 64 -> 64/64 case */
|
||||
+ env->regs[r1] = env->regs[r1 + 1] % divisor;
|
||||
+ env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
|
||||
+ return;
|
||||
+ } else {
|
||||
+#if HOST_LONG_BITS == 64 && defined(__GNUC__)
|
||||
+ /* assuming 64-bit hosts have __uint128_t */
|
||||
+ __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
|
||||
+ (env->regs[r1 + 1]);
|
||||
+ __uint128_t quotient = dividend / divisor;
|
||||
+ __uint128_t remainder = dividend % divisor;
|
||||
+
|
||||
+ env->regs[r1 + 1] = quotient;
|
||||
+ env->regs[r1] = remainder;
|
||||
+#else
|
||||
+ /* 32-bit hosts would need special wrapper functionality - just abort if
|
||||
+ we encounter such a case; it's very unlikely anyways. */
|
||||
+ cpu_abort(env, "128 -> 64/64 division not implemented\n");
|
||||
+#endif
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* absolute value 32-bit */
|
||||
+uint32_t HELPER(abs_i32)(int32_t val)
|
||||
+{
|
||||
+ if (val < 0) {
|
||||
+ return -val;
|
||||
+ } else {
|
||||
+ return val;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* negative absolute value 32-bit */
|
||||
+int32_t HELPER(nabs_i32)(int32_t val)
|
||||
+{
|
||||
+ if (val < 0) {
|
||||
+ return val;
|
||||
+ } else {
|
||||
+ return -val;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* absolute value 64-bit */
|
||||
+uint64_t HELPER(abs_i64)(int64_t val)
|
||||
+{
|
||||
+ HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
|
||||
+
|
||||
+ if (val < 0) {
|
||||
+ return -val;
|
||||
+ } else {
|
||||
+ return val;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* negative absolute value 64-bit */
|
||||
+int64_t HELPER(nabs_i64)(int64_t val)
|
||||
+{
|
||||
+ if (val < 0) {
|
||||
+ return val;
|
||||
+ } else {
|
||||
+ return -val;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* add with carry 32-bit unsigned */
|
||||
+uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
|
||||
+{
|
||||
+ uint32_t res;
|
||||
+
|
||||
+ res = v1 + v2;
|
||||
+ if (cc & 2) {
|
||||
+ res++;
|
||||
+ }
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+/* subtract unsigned v2 from v1 with borrow */
|
||||
+uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
|
||||
+{
|
||||
+ uint32_t v1 = env->regs[r1];
|
||||
+ uint32_t res = v1 + (~v2) + (cc >> 1);
|
||||
+
|
||||
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
|
||||
+ if (cc & 2) {
|
||||
+ /* borrow */
|
||||
+ return v1 ? 1 : 0;
|
||||
+ } else {
|
||||
+ return v1 ? 3 : 2;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* subtract unsigned v2 from v1 with borrow */
|
||||
+uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
|
||||
+{
|
||||
+ uint64_t res = v1 + (~v2) + (cc >> 1);
|
||||
+
|
||||
+ env->regs[r1] = res;
|
||||
+ if (cc & 2) {
|
||||
+ /* borrow */
|
||||
+ return v1 ? 1 : 0;
|
||||
+ } else {
|
||||
+ return v1 ? 3 : 2;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* find leftmost one */
|
||||
+uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
|
||||
+{
|
||||
+ uint64_t res = 0;
|
||||
+ uint64_t ov2 = v2;
|
||||
+
|
||||
+ while (!(v2 & 0x8000000000000000ULL) && v2) {
|
||||
+ v2 <<= 1;
|
||||
+ res++;
|
||||
+ }
|
||||
+
|
||||
+ if (!v2) {
|
||||
+ env->regs[r1] = 64;
|
||||
+ env->regs[r1 + 1] = 0;
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ env->regs[r1] = res;
|
||||
+ env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
|
||||
+ return 2;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+uint64_t HELPER(cvd)(int32_t bin)
|
||||
+{
|
||||
+ /* positive 0 */
|
||||
+ uint64_t dec = 0x0c;
|
||||
+ int shift = 4;
|
||||
+
|
||||
+ if (bin < 0) {
|
||||
+ bin = -bin;
|
||||
+ dec = 0x0d;
|
||||
+ }
|
||||
+
|
||||
+ for (shift = 4; (shift < 64) && bin; shift += 4) {
|
||||
+ int current_number = bin % 10;
|
||||
+
|
||||
+ dec |= (current_number) << shift;
|
||||
+ bin /= 10;
|
||||
+ }
|
||||
+
|
||||
+ return dec;
|
||||
+}
|
||||
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
|
||||
index eced890..3b8b997 100644
|
||||
--- a/target-s390x/op_helper.c
|
||||
+++ b/target-s390x/op_helper.c
|
||||
@@ -352,49 +352,6 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
|
||||
HELPER_LOG("\n");
|
||||
}
|
||||
|
||||
-/* 64/64 -> 128 unsigned multiplication */
|
||||
-void HELPER(mlg)(uint32_t r1, uint64_t v2)
|
||||
-{
|
||||
-#if HOST_LONG_BITS == 64 && defined(__GNUC__)
|
||||
- /* assuming 64-bit hosts have __uint128_t */
|
||||
- __uint128_t res = (__uint128_t)env->regs[r1 + 1];
|
||||
-
|
||||
- res *= (__uint128_t)v2;
|
||||
- env->regs[r1] = (uint64_t)(res >> 64);
|
||||
- env->regs[r1 + 1] = (uint64_t)res;
|
||||
-#else
|
||||
- mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
-/* 128 -> 64/64 unsigned division */
|
||||
-void HELPER(dlg)(uint32_t r1, uint64_t v2)
|
||||
-{
|
||||
- uint64_t divisor = v2;
|
||||
-
|
||||
- if (!env->regs[r1]) {
|
||||
- /* 64 -> 64/64 case */
|
||||
- env->regs[r1] = env->regs[r1 + 1] % divisor;
|
||||
- env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
|
||||
- return;
|
||||
- } else {
|
||||
-#if HOST_LONG_BITS == 64 && defined(__GNUC__)
|
||||
- /* assuming 64-bit hosts have __uint128_t */
|
||||
- __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
|
||||
- (env->regs[r1 + 1]);
|
||||
- __uint128_t quotient = dividend / divisor;
|
||||
- __uint128_t remainder = dividend % divisor;
|
||||
-
|
||||
- env->regs[r1 + 1] = quotient;
|
||||
- env->regs[r1] = remainder;
|
||||
-#else
|
||||
- /* 32-bit hosts would need special wrapper functionality - just abort if
|
||||
- we encounter such a case; it's very unlikely anyways. */
|
||||
- cpu_abort(env, "128 -> 64/64 division not implemented\n");
|
||||
-#endif
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static inline uint64_t get_address(int x2, int b2, int d2)
|
||||
{
|
||||
uint64_t r = d2;
|
||||
@@ -677,61 +634,6 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
|
||||
return cc;
|
||||
}
|
||||
|
||||
-/* absolute value 32-bit */
|
||||
-uint32_t HELPER(abs_i32)(int32_t val)
|
||||
-{
|
||||
- if (val < 0) {
|
||||
- return -val;
|
||||
- } else {
|
||||
- return val;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* negative absolute value 32-bit */
|
||||
-int32_t HELPER(nabs_i32)(int32_t val)
|
||||
-{
|
||||
- if (val < 0) {
|
||||
- return val;
|
||||
- } else {
|
||||
- return -val;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* absolute value 64-bit */
|
||||
-uint64_t HELPER(abs_i64)(int64_t val)
|
||||
-{
|
||||
- HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
|
||||
-
|
||||
- if (val < 0) {
|
||||
- return -val;
|
||||
- } else {
|
||||
- return val;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* negative absolute value 64-bit */
|
||||
-int64_t HELPER(nabs_i64)(int64_t val)
|
||||
-{
|
||||
- if (val < 0) {
|
||||
- return val;
|
||||
- } else {
|
||||
- return -val;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* add with carry 32-bit unsigned */
|
||||
-uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
|
||||
-{
|
||||
- uint32_t res;
|
||||
-
|
||||
- res = v1 + v2;
|
||||
- if (cc & 2) {
|
||||
- res++;
|
||||
- }
|
||||
-
|
||||
- return res;
|
||||
-}
|
||||
-
|
||||
/* store character under mask high operates on the upper half of r1 */
|
||||
void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
|
||||
{
|
||||
@@ -936,57 +838,6 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
|
||||
return cc;
|
||||
}
|
||||
|
||||
-/* subtract unsigned v2 from v1 with borrow */
|
||||
-uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
|
||||
-{
|
||||
- uint32_t v1 = env->regs[r1];
|
||||
- uint32_t res = v1 + (~v2) + (cc >> 1);
|
||||
-
|
||||
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
|
||||
- if (cc & 2) {
|
||||
- /* borrow */
|
||||
- return v1 ? 1 : 0;
|
||||
- } else {
|
||||
- return v1 ? 3 : 2;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* subtract unsigned v2 from v1 with borrow */
|
||||
-uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
|
||||
-{
|
||||
- uint64_t res = v1 + (~v2) + (cc >> 1);
|
||||
-
|
||||
- env->regs[r1] = res;
|
||||
- if (cc & 2) {
|
||||
- /* borrow */
|
||||
- return v1 ? 1 : 0;
|
||||
- } else {
|
||||
- return v1 ? 3 : 2;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* find leftmost one */
|
||||
-uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
|
||||
-{
|
||||
- uint64_t res = 0;
|
||||
- uint64_t ov2 = v2;
|
||||
-
|
||||
- while (!(v2 & 0x8000000000000000ULL) && v2) {
|
||||
- v2 <<= 1;
|
||||
- res++;
|
||||
- }
|
||||
-
|
||||
- if (!v2) {
|
||||
- env->regs[r1] = 64;
|
||||
- env->regs[r1 + 1] = 0;
|
||||
- return 0;
|
||||
- } else {
|
||||
- env->regs[r1] = res;
|
||||
- env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
|
||||
- return 2;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/* checksum */
|
||||
void HELPER(cksm)(uint32_t r1, uint32_t r2)
|
||||
{
|
||||
@@ -1026,27 +877,6 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
|
||||
((uint32_t)cksm + (cksm >> 32));
|
||||
}
|
||||
|
||||
-uint64_t HELPER(cvd)(int32_t bin)
|
||||
-{
|
||||
- /* positive 0 */
|
||||
- uint64_t dec = 0x0c;
|
||||
- int shift = 4;
|
||||
-
|
||||
- if (bin < 0) {
|
||||
- bin = -bin;
|
||||
- dec = 0x0d;
|
||||
- }
|
||||
-
|
||||
- for (shift = 4; (shift < 64) && bin; shift += 4) {
|
||||
- int current_number = bin % 10;
|
||||
-
|
||||
- dec |= (current_number) << shift;
|
||||
- bin /= 10;
|
||||
- }
|
||||
-
|
||||
- return dec;
|
||||
-}
|
||||
-
|
||||
void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
|
||||
{
|
||||
int len_dest = len >> 4;
|
||||
--
|
||||
1.7.12.1
|
||||
|
2424
0009-target-s390x-split-memory-access-helpers.patch
Normal file
2424
0009-target-s390x-split-memory-access-helpers.patch
Normal file
File diff suppressed because it is too large
Load Diff
924
0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch
Normal file
924
0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch
Normal file
@ -0,0 +1,924 @@
|
||||
From 56018228deac6e704a7ec8befd9e9dc69f2fe73f Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:33:35 +0000
|
||||
Subject: [PATCH] target-s390x: rename op_helper.c to misc_helper.c
|
||||
|
||||
Now op_helper.c contains miscellaneous helpers, rename
|
||||
it to misc_helper.c.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
[agraf: fix conflict]
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-s390x/Makefile.objs | 6 +-
|
||||
target-s390x/cpu.h | 2 +-
|
||||
target-s390x/misc_helper.c | 428 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
target-s390x/op_helper.c | 428 ---------------------------------------------
|
||||
4 files changed, 432 insertions(+), 432 deletions(-)
|
||||
create mode 100644 target-s390x/misc_helper.c
|
||||
delete mode 100644 target-s390x/op_helper.c
|
||||
|
||||
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
|
||||
index b9b3061..a87d26f 100644
|
||||
--- a/target-s390x/Makefile.objs
|
||||
+++ b/target-s390x/Makefile.objs
|
||||
@@ -1,10 +1,10 @@
|
||||
-obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
|
||||
-obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
|
||||
+obj-y += translate.o helper.o cpu.o interrupt.o
|
||||
+obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
+$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
|
||||
index 97fde5e..0ccb551 100644
|
||||
--- a/target-s390x/cpu.h
|
||||
+++ b/target-s390x/cpu.h
|
||||
@@ -1005,7 +1005,7 @@ uint32_t set_cc_f64(float64 v1, float64 v2);
|
||||
uint32_t set_cc_nz_f32(float32 v);
|
||||
uint32_t set_cc_nz_f64(float64 v);
|
||||
|
||||
-/* op_helper.c */
|
||||
+/* misc_helper.c */
|
||||
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
|
||||
|
||||
#endif
|
||||
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
|
||||
new file mode 100644
|
||||
index 0000000..1d5137f
|
||||
--- /dev/null
|
||||
+++ b/target-s390x/misc_helper.c
|
||||
@@ -0,0 +1,428 @@
|
||||
+/*
|
||||
+ * S/390 misc helper routines
|
||||
+ *
|
||||
+ * Copyright (c) 2009 Ulrich Hecht
|
||||
+ * Copyright (c) 2009 Alexander Graf
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include "cpu.h"
|
||||
+#include "memory.h"
|
||||
+#include "cputlb.h"
|
||||
+#include "dyngen-exec.h"
|
||||
+#include "host-utils.h"
|
||||
+#include "helper.h"
|
||||
+#include <string.h>
|
||||
+#include "kvm.h"
|
||||
+#include "qemu-timer.h"
|
||||
+#ifdef CONFIG_KVM
|
||||
+#include <linux/kvm.h>
|
||||
+#endif
|
||||
+
|
||||
+#if !defined(CONFIG_USER_ONLY)
|
||||
+#include "softmmu_exec.h"
|
||||
+#include "sysemu.h"
|
||||
+#endif
|
||||
+
|
||||
+/* #define DEBUG_HELPER */
|
||||
+#ifdef DEBUG_HELPER
|
||||
+#define HELPER_LOG(x...) qemu_log(x)
|
||||
+#else
|
||||
+#define HELPER_LOG(x...)
|
||||
+#endif
|
||||
+
|
||||
+/* raise an exception */
|
||||
+void HELPER(exception)(uint32_t excp)
|
||||
+{
|
||||
+ HELPER_LOG("%s: exception %d\n", __func__, excp);
|
||||
+ env->exception_index = excp;
|
||||
+ cpu_loop_exit(env);
|
||||
+}
|
||||
+
|
||||
+#ifndef CONFIG_USER_ONLY
|
||||
+void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
|
||||
+{
|
||||
+ qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
|
||||
+
|
||||
+ if (kvm_enabled()) {
|
||||
+#ifdef CONFIG_KVM
|
||||
+ kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
|
||||
+#endif
|
||||
+ } else {
|
||||
+ env->int_pgm_code = code;
|
||||
+ env->int_pgm_ilc = ilc;
|
||||
+ env->exception_index = EXCP_PGM;
|
||||
+ cpu_loop_exit(env);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
|
||||
+ */
|
||||
+int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
|
||||
+{
|
||||
+ int r = 0;
|
||||
+ int shift = 0;
|
||||
+
|
||||
+#ifdef DEBUG_HELPER
|
||||
+ printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
|
||||
+#endif
|
||||
+
|
||||
+ /* basic checks */
|
||||
+ if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
|
||||
+ return -PGM_ADDRESSING;
|
||||
+ }
|
||||
+ if (sccb & ~0x7ffffff8ul) {
|
||||
+ return -PGM_SPECIFICATION;
|
||||
+ }
|
||||
+
|
||||
+ switch (code) {
|
||||
+ case SCLP_CMDW_READ_SCP_INFO:
|
||||
+ case SCLP_CMDW_READ_SCP_INFO_FORCED:
|
||||
+ while ((ram_size >> (20 + shift)) > 65535) {
|
||||
+ shift++;
|
||||
+ }
|
||||
+ stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
|
||||
+ stb_phys(sccb + SCP_INCREMENT, 1 << shift);
|
||||
+ stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
|
||||
+
|
||||
+ s390_sclp_extint(sccb & ~3);
|
||||
+ break;
|
||||
+ default:
|
||||
+#ifdef DEBUG_HELPER
|
||||
+ printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
|
||||
+#endif
|
||||
+ r = 3;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/* SCLP service call */
|
||||
+uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
|
||||
+{
|
||||
+ int r;
|
||||
+
|
||||
+ r = sclp_service_call(env, r1, r2);
|
||||
+ if (r < 0) {
|
||||
+ program_interrupt(env, -r, 4);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/* DIAG */
|
||||
+uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
|
||||
+{
|
||||
+ uint64_t r;
|
||||
+
|
||||
+ switch (num) {
|
||||
+ case 0x500:
|
||||
+ /* KVM hypercall */
|
||||
+ r = s390_virtio_hypercall(env, mem, code);
|
||||
+ break;
|
||||
+ case 0x44:
|
||||
+ /* yield */
|
||||
+ r = 0;
|
||||
+ break;
|
||||
+ case 0x308:
|
||||
+ /* ipl */
|
||||
+ r = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ r = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (r) {
|
||||
+ program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/* Store CPU ID */
|
||||
+void HELPER(stidp)(uint64_t a1)
|
||||
+{
|
||||
+ stq(a1, env->cpu_num);
|
||||
+}
|
||||
+
|
||||
+/* Set Prefix */
|
||||
+void HELPER(spx)(uint64_t a1)
|
||||
+{
|
||||
+ uint32_t prefix;
|
||||
+
|
||||
+ prefix = ldl(a1);
|
||||
+ env->psa = prefix & 0xfffff000;
|
||||
+ qemu_log("prefix: %#x\n", prefix);
|
||||
+ tlb_flush_page(env, 0);
|
||||
+ tlb_flush_page(env, TARGET_PAGE_SIZE);
|
||||
+}
|
||||
+
|
||||
+/* Set Clock */
|
||||
+uint32_t HELPER(sck)(uint64_t a1)
|
||||
+{
|
||||
+ /* XXX not implemented - is it necessary? */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline uint64_t clock_value(CPUS390XState *env)
|
||||
+{
|
||||
+ uint64_t time;
|
||||
+
|
||||
+ time = env->tod_offset +
|
||||
+ time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
|
||||
+
|
||||
+ return time;
|
||||
+}
|
||||
+
|
||||
+/* Store Clock */
|
||||
+uint32_t HELPER(stck)(uint64_t a1)
|
||||
+{
|
||||
+ stq(a1, clock_value(env));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Store Clock Extended */
|
||||
+uint32_t HELPER(stcke)(uint64_t a1)
|
||||
+{
|
||||
+ stb(a1, 0);
|
||||
+ /* basically the same value as stck */
|
||||
+ stq(a1 + 1, clock_value(env) | env->cpu_num);
|
||||
+ /* more fine grained than stck */
|
||||
+ stq(a1 + 9, 0);
|
||||
+ /* XXX programmable fields */
|
||||
+ stw(a1 + 17, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Set Clock Comparator */
|
||||
+void HELPER(sckc)(uint64_t a1)
|
||||
+{
|
||||
+ uint64_t time = ldq(a1);
|
||||
+
|
||||
+ if (time == -1ULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* difference between now and then */
|
||||
+ time -= clock_value(env);
|
||||
+ /* nanoseconds */
|
||||
+ time = (time * 125) >> 9;
|
||||
+
|
||||
+ qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
|
||||
+}
|
||||
+
|
||||
+/* Store Clock Comparator */
|
||||
+void HELPER(stckc)(uint64_t a1)
|
||||
+{
|
||||
+ /* XXX implement */
|
||||
+ stq(a1, 0);
|
||||
+}
|
||||
+
|
||||
+/* Set CPU Timer */
|
||||
+void HELPER(spt)(uint64_t a1)
|
||||
+{
|
||||
+ uint64_t time = ldq(a1);
|
||||
+
|
||||
+ if (time == -1ULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* nanoseconds */
|
||||
+ time = (time * 125) >> 9;
|
||||
+
|
||||
+ qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
|
||||
+}
|
||||
+
|
||||
+/* Store CPU Timer */
|
||||
+void HELPER(stpt)(uint64_t a1)
|
||||
+{
|
||||
+ /* XXX implement */
|
||||
+ stq(a1, 0);
|
||||
+}
|
||||
+
|
||||
+/* Store System Information */
|
||||
+uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
|
||||
+{
|
||||
+ int cc = 0;
|
||||
+ int sel1, sel2;
|
||||
+
|
||||
+ if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
|
||||
+ ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
|
||||
+ /* valid function code, invalid reserved bits */
|
||||
+ program_interrupt(env, PGM_SPECIFICATION, 2);
|
||||
+ }
|
||||
+
|
||||
+ sel1 = r0 & STSI_R0_SEL1_MASK;
|
||||
+ sel2 = r1 & STSI_R1_SEL2_MASK;
|
||||
+
|
||||
+ /* XXX: spec exception if sysib is not 4k-aligned */
|
||||
+
|
||||
+ switch (r0 & STSI_LEVEL_MASK) {
|
||||
+ case STSI_LEVEL_1:
|
||||
+ if ((sel1 == 1) && (sel2 == 1)) {
|
||||
+ /* Basic Machine Configuration */
|
||||
+ struct sysib_111 sysib;
|
||||
+
|
||||
+ memset(&sysib, 0, sizeof(sysib));
|
||||
+ ebcdic_put(sysib.manuf, "QEMU ", 16);
|
||||
+ /* same as machine type number in STORE CPU ID */
|
||||
+ ebcdic_put(sysib.type, "QEMU", 4);
|
||||
+ /* same as model number in STORE CPU ID */
|
||||
+ ebcdic_put(sysib.model, "QEMU ", 16);
|
||||
+ ebcdic_put(sysib.sequence, "QEMU ", 16);
|
||||
+ ebcdic_put(sysib.plant, "QEMU", 4);
|
||||
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
+ } else if ((sel1 == 2) && (sel2 == 1)) {
|
||||
+ /* Basic Machine CPU */
|
||||
+ struct sysib_121 sysib;
|
||||
+
|
||||
+ memset(&sysib, 0, sizeof(sysib));
|
||||
+ /* XXX make different for different CPUs? */
|
||||
+ ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
|
||||
+ ebcdic_put(sysib.plant, "QEMU", 4);
|
||||
+ stw_p(&sysib.cpu_addr, env->cpu_num);
|
||||
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
+ } else if ((sel1 == 2) && (sel2 == 2)) {
|
||||
+ /* Basic Machine CPUs */
|
||||
+ struct sysib_122 sysib;
|
||||
+
|
||||
+ memset(&sysib, 0, sizeof(sysib));
|
||||
+ stl_p(&sysib.capability, 0x443afc29);
|
||||
+ /* XXX change when SMP comes */
|
||||
+ stw_p(&sysib.total_cpus, 1);
|
||||
+ stw_p(&sysib.active_cpus, 1);
|
||||
+ stw_p(&sysib.standby_cpus, 0);
|
||||
+ stw_p(&sysib.reserved_cpus, 0);
|
||||
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
+ } else {
|
||||
+ cc = 3;
|
||||
+ }
|
||||
+ break;
|
||||
+ case STSI_LEVEL_2:
|
||||
+ {
|
||||
+ if ((sel1 == 2) && (sel2 == 1)) {
|
||||
+ /* LPAR CPU */
|
||||
+ struct sysib_221 sysib;
|
||||
+
|
||||
+ memset(&sysib, 0, sizeof(sysib));
|
||||
+ /* XXX make different for different CPUs? */
|
||||
+ ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
|
||||
+ ebcdic_put(sysib.plant, "QEMU", 4);
|
||||
+ stw_p(&sysib.cpu_addr, env->cpu_num);
|
||||
+ stw_p(&sysib.cpu_id, 0);
|
||||
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
+ } else if ((sel1 == 2) && (sel2 == 2)) {
|
||||
+ /* LPAR CPUs */
|
||||
+ struct sysib_222 sysib;
|
||||
+
|
||||
+ memset(&sysib, 0, sizeof(sysib));
|
||||
+ stw_p(&sysib.lpar_num, 0);
|
||||
+ sysib.lcpuc = 0;
|
||||
+ /* XXX change when SMP comes */
|
||||
+ stw_p(&sysib.total_cpus, 1);
|
||||
+ stw_p(&sysib.conf_cpus, 1);
|
||||
+ stw_p(&sysib.standby_cpus, 0);
|
||||
+ stw_p(&sysib.reserved_cpus, 0);
|
||||
+ ebcdic_put(sysib.name, "QEMU ", 8);
|
||||
+ stl_p(&sysib.caf, 1000);
|
||||
+ stw_p(&sysib.dedicated_cpus, 0);
|
||||
+ stw_p(&sysib.shared_cpus, 0);
|
||||
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
+ } else {
|
||||
+ cc = 3;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case STSI_LEVEL_3:
|
||||
+ {
|
||||
+ if ((sel1 == 2) && (sel2 == 2)) {
|
||||
+ /* VM CPUs */
|
||||
+ struct sysib_322 sysib;
|
||||
+
|
||||
+ memset(&sysib, 0, sizeof(sysib));
|
||||
+ sysib.count = 1;
|
||||
+ /* XXX change when SMP comes */
|
||||
+ stw_p(&sysib.vm[0].total_cpus, 1);
|
||||
+ stw_p(&sysib.vm[0].conf_cpus, 1);
|
||||
+ stw_p(&sysib.vm[0].standby_cpus, 0);
|
||||
+ stw_p(&sysib.vm[0].reserved_cpus, 0);
|
||||
+ ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
|
||||
+ stl_p(&sysib.vm[0].caf, 1000);
|
||||
+ ebcdic_put(sysib.vm[0].cpi, "KVM/Linux ", 16);
|
||||
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
+ } else {
|
||||
+ cc = 3;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case STSI_LEVEL_CURRENT:
|
||||
+ env->regs[0] = STSI_LEVEL_3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ cc = 3;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return cc;
|
||||
+}
|
||||
+
|
||||
+uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
|
||||
+{
|
||||
+ int cc = 0;
|
||||
+
|
||||
+ HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
|
||||
+ __func__, order_code, r1, cpu_addr);
|
||||
+
|
||||
+ /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
|
||||
+ as parameter (input). Status (output) is always R1. */
|
||||
+
|
||||
+ switch (order_code) {
|
||||
+ case SIGP_SET_ARCH:
|
||||
+ /* switch arch */
|
||||
+ break;
|
||||
+ case SIGP_SENSE:
|
||||
+ /* enumerate CPU status */
|
||||
+ if (cpu_addr) {
|
||||
+ /* XXX implement when SMP comes */
|
||||
+ return 3;
|
||||
+ }
|
||||
+ env->regs[r1] &= 0xffffffff00000000ULL;
|
||||
+ cc = 1;
|
||||
+ break;
|
||||
+#if !defined(CONFIG_USER_ONLY)
|
||||
+ case SIGP_RESTART:
|
||||
+ qemu_system_reset_request();
|
||||
+ cpu_loop_exit(env);
|
||||
+ break;
|
||||
+ case SIGP_STOP:
|
||||
+ qemu_system_shutdown_request();
|
||||
+ cpu_loop_exit(env);
|
||||
+ break;
|
||||
+#endif
|
||||
+ default:
|
||||
+ /* unknown sigp */
|
||||
+ fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
|
||||
+ cc = 3;
|
||||
+ }
|
||||
+
|
||||
+ return cc;
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
|
||||
deleted file mode 100644
|
||||
index bb8dbf5..0000000
|
||||
--- a/target-s390x/op_helper.c
|
||||
+++ /dev/null
|
||||
@@ -1,428 +0,0 @@
|
||||
-/*
|
||||
- * S/390 helper routines
|
||||
- *
|
||||
- * Copyright (c) 2009 Ulrich Hecht
|
||||
- * Copyright (c) 2009 Alexander Graf
|
||||
- *
|
||||
- * This library is free software; you can redistribute it and/or
|
||||
- * modify it under the terms of the GNU Lesser General Public
|
||||
- * License as published by the Free Software Foundation; either
|
||||
- * version 2 of the License, or (at your option) any later version.
|
||||
- *
|
||||
- * This library is distributed in the hope that it will be useful,
|
||||
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- * Lesser General Public License for more details.
|
||||
- *
|
||||
- * You should have received a copy of the GNU Lesser General Public
|
||||
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
- */
|
||||
-
|
||||
-#include "cpu.h"
|
||||
-#include "memory.h"
|
||||
-#include "cputlb.h"
|
||||
-#include "dyngen-exec.h"
|
||||
-#include "host-utils.h"
|
||||
-#include "helper.h"
|
||||
-#include <string.h>
|
||||
-#include "kvm.h"
|
||||
-#include "qemu-timer.h"
|
||||
-#ifdef CONFIG_KVM
|
||||
-#include <linux/kvm.h>
|
||||
-#endif
|
||||
-
|
||||
-#if !defined(CONFIG_USER_ONLY)
|
||||
-#include "softmmu_exec.h"
|
||||
-#include "sysemu.h"
|
||||
-#endif
|
||||
-
|
||||
-/* #define DEBUG_HELPER */
|
||||
-#ifdef DEBUG_HELPER
|
||||
-#define HELPER_LOG(x...) qemu_log(x)
|
||||
-#else
|
||||
-#define HELPER_LOG(x...)
|
||||
-#endif
|
||||
-
|
||||
-/* raise an exception */
|
||||
-void HELPER(exception)(uint32_t excp)
|
||||
-{
|
||||
- HELPER_LOG("%s: exception %d\n", __func__, excp);
|
||||
- env->exception_index = excp;
|
||||
- cpu_loop_exit(env);
|
||||
-}
|
||||
-
|
||||
-#ifndef CONFIG_USER_ONLY
|
||||
-void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
|
||||
-{
|
||||
- qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
|
||||
-
|
||||
- if (kvm_enabled()) {
|
||||
-#ifdef CONFIG_KVM
|
||||
- kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
|
||||
-#endif
|
||||
- } else {
|
||||
- env->int_pgm_code = code;
|
||||
- env->int_pgm_ilc = ilc;
|
||||
- env->exception_index = EXCP_PGM;
|
||||
- cpu_loop_exit(env);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
|
||||
- */
|
||||
-int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
|
||||
-{
|
||||
- int r = 0;
|
||||
- int shift = 0;
|
||||
-
|
||||
-#ifdef DEBUG_HELPER
|
||||
- printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
|
||||
-#endif
|
||||
-
|
||||
- /* basic checks */
|
||||
- if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
|
||||
- return -PGM_ADDRESSING;
|
||||
- }
|
||||
- if (sccb & ~0x7ffffff8ul) {
|
||||
- return -PGM_SPECIFICATION;
|
||||
- }
|
||||
-
|
||||
- switch (code) {
|
||||
- case SCLP_CMDW_READ_SCP_INFO:
|
||||
- case SCLP_CMDW_READ_SCP_INFO_FORCED:
|
||||
- while ((ram_size >> (20 + shift)) > 65535) {
|
||||
- shift++;
|
||||
- }
|
||||
- stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
|
||||
- stb_phys(sccb + SCP_INCREMENT, 1 << shift);
|
||||
- stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
|
||||
-
|
||||
- s390_sclp_extint(sccb & ~3);
|
||||
- break;
|
||||
- default:
|
||||
-#ifdef DEBUG_HELPER
|
||||
- printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
|
||||
-#endif
|
||||
- r = 3;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return r;
|
||||
-}
|
||||
-
|
||||
-/* SCLP service call */
|
||||
-uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
|
||||
-{
|
||||
- int r;
|
||||
-
|
||||
- r = sclp_service_call(env, r1, r2);
|
||||
- if (r < 0) {
|
||||
- program_interrupt(env, -r, 4);
|
||||
- return 0;
|
||||
- }
|
||||
- return r;
|
||||
-}
|
||||
-
|
||||
-/* DIAG */
|
||||
-uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
|
||||
-{
|
||||
- uint64_t r;
|
||||
-
|
||||
- switch (num) {
|
||||
- case 0x500:
|
||||
- /* KVM hypercall */
|
||||
- r = s390_virtio_hypercall(env, mem, code);
|
||||
- break;
|
||||
- case 0x44:
|
||||
- /* yield */
|
||||
- r = 0;
|
||||
- break;
|
||||
- case 0x308:
|
||||
- /* ipl */
|
||||
- r = 0;
|
||||
- break;
|
||||
- default:
|
||||
- r = -1;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (r) {
|
||||
- program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
|
||||
- }
|
||||
-
|
||||
- return r;
|
||||
-}
|
||||
-
|
||||
-/* Store CPU ID */
|
||||
-void HELPER(stidp)(uint64_t a1)
|
||||
-{
|
||||
- stq(a1, env->cpu_num);
|
||||
-}
|
||||
-
|
||||
-/* Set Prefix */
|
||||
-void HELPER(spx)(uint64_t a1)
|
||||
-{
|
||||
- uint32_t prefix;
|
||||
-
|
||||
- prefix = ldl(a1);
|
||||
- env->psa = prefix & 0xfffff000;
|
||||
- qemu_log("prefix: %#x\n", prefix);
|
||||
- tlb_flush_page(env, 0);
|
||||
- tlb_flush_page(env, TARGET_PAGE_SIZE);
|
||||
-}
|
||||
-
|
||||
-/* Set Clock */
|
||||
-uint32_t HELPER(sck)(uint64_t a1)
|
||||
-{
|
||||
- /* XXX not implemented - is it necessary? */
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static inline uint64_t clock_value(CPUS390XState *env)
|
||||
-{
|
||||
- uint64_t time;
|
||||
-
|
||||
- time = env->tod_offset +
|
||||
- time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
|
||||
-
|
||||
- return time;
|
||||
-}
|
||||
-
|
||||
-/* Store Clock */
|
||||
-uint32_t HELPER(stck)(uint64_t a1)
|
||||
-{
|
||||
- stq(a1, clock_value(env));
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/* Store Clock Extended */
|
||||
-uint32_t HELPER(stcke)(uint64_t a1)
|
||||
-{
|
||||
- stb(a1, 0);
|
||||
- /* basically the same value as stck */
|
||||
- stq(a1 + 1, clock_value(env) | env->cpu_num);
|
||||
- /* more fine grained than stck */
|
||||
- stq(a1 + 9, 0);
|
||||
- /* XXX programmable fields */
|
||||
- stw(a1 + 17, 0);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/* Set Clock Comparator */
|
||||
-void HELPER(sckc)(uint64_t a1)
|
||||
-{
|
||||
- uint64_t time = ldq(a1);
|
||||
-
|
||||
- if (time == -1ULL) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* difference between now and then */
|
||||
- time -= clock_value(env);
|
||||
- /* nanoseconds */
|
||||
- time = (time * 125) >> 9;
|
||||
-
|
||||
- qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
|
||||
-}
|
||||
-
|
||||
-/* Store Clock Comparator */
|
||||
-void HELPER(stckc)(uint64_t a1)
|
||||
-{
|
||||
- /* XXX implement */
|
||||
- stq(a1, 0);
|
||||
-}
|
||||
-
|
||||
-/* Set CPU Timer */
|
||||
-void HELPER(spt)(uint64_t a1)
|
||||
-{
|
||||
- uint64_t time = ldq(a1);
|
||||
-
|
||||
- if (time == -1ULL) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* nanoseconds */
|
||||
- time = (time * 125) >> 9;
|
||||
-
|
||||
- qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
|
||||
-}
|
||||
-
|
||||
-/* Store CPU Timer */
|
||||
-void HELPER(stpt)(uint64_t a1)
|
||||
-{
|
||||
- /* XXX implement */
|
||||
- stq(a1, 0);
|
||||
-}
|
||||
-
|
||||
-/* Store System Information */
|
||||
-uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
|
||||
-{
|
||||
- int cc = 0;
|
||||
- int sel1, sel2;
|
||||
-
|
||||
- if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
|
||||
- ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
|
||||
- /* valid function code, invalid reserved bits */
|
||||
- program_interrupt(env, PGM_SPECIFICATION, 2);
|
||||
- }
|
||||
-
|
||||
- sel1 = r0 & STSI_R0_SEL1_MASK;
|
||||
- sel2 = r1 & STSI_R1_SEL2_MASK;
|
||||
-
|
||||
- /* XXX: spec exception if sysib is not 4k-aligned */
|
||||
-
|
||||
- switch (r0 & STSI_LEVEL_MASK) {
|
||||
- case STSI_LEVEL_1:
|
||||
- if ((sel1 == 1) && (sel2 == 1)) {
|
||||
- /* Basic Machine Configuration */
|
||||
- struct sysib_111 sysib;
|
||||
-
|
||||
- memset(&sysib, 0, sizeof(sysib));
|
||||
- ebcdic_put(sysib.manuf, "QEMU ", 16);
|
||||
- /* same as machine type number in STORE CPU ID */
|
||||
- ebcdic_put(sysib.type, "QEMU", 4);
|
||||
- /* same as model number in STORE CPU ID */
|
||||
- ebcdic_put(sysib.model, "QEMU ", 16);
|
||||
- ebcdic_put(sysib.sequence, "QEMU ", 16);
|
||||
- ebcdic_put(sysib.plant, "QEMU", 4);
|
||||
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
- } else if ((sel1 == 2) && (sel2 == 1)) {
|
||||
- /* Basic Machine CPU */
|
||||
- struct sysib_121 sysib;
|
||||
-
|
||||
- memset(&sysib, 0, sizeof(sysib));
|
||||
- /* XXX make different for different CPUs? */
|
||||
- ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
|
||||
- ebcdic_put(sysib.plant, "QEMU", 4);
|
||||
- stw_p(&sysib.cpu_addr, env->cpu_num);
|
||||
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
- } else if ((sel1 == 2) && (sel2 == 2)) {
|
||||
- /* Basic Machine CPUs */
|
||||
- struct sysib_122 sysib;
|
||||
-
|
||||
- memset(&sysib, 0, sizeof(sysib));
|
||||
- stl_p(&sysib.capability, 0x443afc29);
|
||||
- /* XXX change when SMP comes */
|
||||
- stw_p(&sysib.total_cpus, 1);
|
||||
- stw_p(&sysib.active_cpus, 1);
|
||||
- stw_p(&sysib.standby_cpus, 0);
|
||||
- stw_p(&sysib.reserved_cpus, 0);
|
||||
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
- } else {
|
||||
- cc = 3;
|
||||
- }
|
||||
- break;
|
||||
- case STSI_LEVEL_2:
|
||||
- {
|
||||
- if ((sel1 == 2) && (sel2 == 1)) {
|
||||
- /* LPAR CPU */
|
||||
- struct sysib_221 sysib;
|
||||
-
|
||||
- memset(&sysib, 0, sizeof(sysib));
|
||||
- /* XXX make different for different CPUs? */
|
||||
- ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
|
||||
- ebcdic_put(sysib.plant, "QEMU", 4);
|
||||
- stw_p(&sysib.cpu_addr, env->cpu_num);
|
||||
- stw_p(&sysib.cpu_id, 0);
|
||||
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
- } else if ((sel1 == 2) && (sel2 == 2)) {
|
||||
- /* LPAR CPUs */
|
||||
- struct sysib_222 sysib;
|
||||
-
|
||||
- memset(&sysib, 0, sizeof(sysib));
|
||||
- stw_p(&sysib.lpar_num, 0);
|
||||
- sysib.lcpuc = 0;
|
||||
- /* XXX change when SMP comes */
|
||||
- stw_p(&sysib.total_cpus, 1);
|
||||
- stw_p(&sysib.conf_cpus, 1);
|
||||
- stw_p(&sysib.standby_cpus, 0);
|
||||
- stw_p(&sysib.reserved_cpus, 0);
|
||||
- ebcdic_put(sysib.name, "QEMU ", 8);
|
||||
- stl_p(&sysib.caf, 1000);
|
||||
- stw_p(&sysib.dedicated_cpus, 0);
|
||||
- stw_p(&sysib.shared_cpus, 0);
|
||||
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
- } else {
|
||||
- cc = 3;
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- case STSI_LEVEL_3:
|
||||
- {
|
||||
- if ((sel1 == 2) && (sel2 == 2)) {
|
||||
- /* VM CPUs */
|
||||
- struct sysib_322 sysib;
|
||||
-
|
||||
- memset(&sysib, 0, sizeof(sysib));
|
||||
- sysib.count = 1;
|
||||
- /* XXX change when SMP comes */
|
||||
- stw_p(&sysib.vm[0].total_cpus, 1);
|
||||
- stw_p(&sysib.vm[0].conf_cpus, 1);
|
||||
- stw_p(&sysib.vm[0].standby_cpus, 0);
|
||||
- stw_p(&sysib.vm[0].reserved_cpus, 0);
|
||||
- ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
|
||||
- stl_p(&sysib.vm[0].caf, 1000);
|
||||
- ebcdic_put(sysib.vm[0].cpi, "KVM/Linux ", 16);
|
||||
- cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
|
||||
- } else {
|
||||
- cc = 3;
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- case STSI_LEVEL_CURRENT:
|
||||
- env->regs[0] = STSI_LEVEL_3;
|
||||
- break;
|
||||
- default:
|
||||
- cc = 3;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return cc;
|
||||
-}
|
||||
-
|
||||
-uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
|
||||
-{
|
||||
- int cc = 0;
|
||||
-
|
||||
- HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
|
||||
- __func__, order_code, r1, cpu_addr);
|
||||
-
|
||||
- /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
|
||||
- as parameter (input). Status (output) is always R1. */
|
||||
-
|
||||
- switch (order_code) {
|
||||
- case SIGP_SET_ARCH:
|
||||
- /* switch arch */
|
||||
- break;
|
||||
- case SIGP_SENSE:
|
||||
- /* enumerate CPU status */
|
||||
- if (cpu_addr) {
|
||||
- /* XXX implement when SMP comes */
|
||||
- return 3;
|
||||
- }
|
||||
- env->regs[r1] &= 0xffffffff00000000ULL;
|
||||
- cc = 1;
|
||||
- break;
|
||||
-#if !defined(CONFIG_USER_ONLY)
|
||||
- case SIGP_RESTART:
|
||||
- qemu_system_reset_request();
|
||||
- cpu_loop_exit(env);
|
||||
- break;
|
||||
- case SIGP_STOP:
|
||||
- qemu_system_shutdown_request();
|
||||
- cpu_loop_exit(env);
|
||||
- break;
|
||||
-#endif
|
||||
- default:
|
||||
- /* unknown sigp */
|
||||
- fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
|
||||
- cc = 3;
|
||||
- }
|
||||
-
|
||||
- return cc;
|
||||
-}
|
||||
-#endif
|
||||
--
|
||||
1.7.12.1
|
||||
|
1218
0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch
Normal file
1218
0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch
Normal file
File diff suppressed because it is too large
Load Diff
202
0012-target-s390x-avoid-AREG0-for-integer-helpers.patch
Normal file
202
0012-target-s390x-avoid-AREG0-for-integer-helpers.patch
Normal file
@ -0,0 +1,202 @@
|
||||
From d44b8c2cacaa50e7420f0dfaf42c344bcf134431 Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:33:37 +0000
|
||||
Subject: [PATCH] target-s390x: avoid AREG0 for integer helpers
|
||||
|
||||
Make integer helpers take a parameter for CPUState instead
|
||||
of relying on global env.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-s390x/Makefile.objs | 1 -
|
||||
target-s390x/helper.h | 10 +++++-----
|
||||
target-s390x/int_helper.c | 12 ++++++------
|
||||
target-s390x/translate.c | 16 ++++++++--------
|
||||
4 files changed, 19 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
|
||||
index 7d965e9..7b2c5c1 100644
|
||||
--- a/target-s390x/Makefile.objs
|
||||
+++ b/target-s390x/Makefile.objs
|
||||
@@ -3,7 +3,6 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
-$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
|
||||
index af98773..c03cd59 100644
|
||||
--- a/target-s390x/helper.h
|
||||
+++ b/target-s390x/helper.h
|
||||
@@ -12,8 +12,8 @@ DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64)
|
||||
DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32)
|
||||
DEF_HELPER_3(clm, i32, i32, i32, i64)
|
||||
DEF_HELPER_3(stcm, void, i32, i32, i64)
|
||||
-DEF_HELPER_2(mlg, void, i32, i64)
|
||||
-DEF_HELPER_2(dlg, void, i32, i64)
|
||||
+DEF_HELPER_3(mlg, void, env, i32, i64)
|
||||
+DEF_HELPER_3(dlg, void, env, i32, i64)
|
||||
DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64)
|
||||
DEF_HELPER_FLAGS_3(set_cc_addu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_3(set_cc_add32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32)
|
||||
@@ -43,8 +43,8 @@ DEF_HELPER_3(stam, void, i32, i64, i32)
|
||||
DEF_HELPER_3(lam, void, i32, i64, i32)
|
||||
DEF_HELPER_3(mvcle, i32, i32, i64, i32)
|
||||
DEF_HELPER_3(clcle, i32, i32, i64, i32)
|
||||
-DEF_HELPER_3(slb, i32, i32, i32, i32)
|
||||
-DEF_HELPER_4(slbg, i32, i32, i32, i64, i64)
|
||||
+DEF_HELPER_4(slb, i32, env, i32, i32, i32)
|
||||
+DEF_HELPER_5(slbg, i32, env, i32, i32, i64, i64)
|
||||
DEF_HELPER_3(cefbr, void, env, i32, s32)
|
||||
DEF_HELPER_3(cdfbr, void, env, i32, s32)
|
||||
DEF_HELPER_3(cxfbr, void, env, i32, s32)
|
||||
@@ -107,7 +107,7 @@ DEF_HELPER_3(lxdb, void, env, i32, i64)
|
||||
DEF_HELPER_FLAGS_3(tceb, TCG_CALL_PURE, i32, env, i32, i64)
|
||||
DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_PURE, i32, env, i32, i64)
|
||||
DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
|
||||
-DEF_HELPER_2(flogr, i32, i32, i64)
|
||||
+DEF_HELPER_3(flogr, i32, env, i32, i64)
|
||||
DEF_HELPER_3(sqdbr, void, env, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
|
||||
DEF_HELPER_3(unpk, void, i32, i64, i64)
|
||||
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
|
||||
index e2eeb07..f202a7e 100644
|
||||
--- a/target-s390x/int_helper.c
|
||||
+++ b/target-s390x/int_helper.c
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "host-utils.h"
|
||||
#include "helper.h"
|
||||
|
||||
@@ -31,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
/* 64/64 -> 128 unsigned multiplication */
|
||||
-void HELPER(mlg)(uint32_t r1, uint64_t v2)
|
||||
+void HELPER(mlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
|
||||
{
|
||||
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
|
||||
/* assuming 64-bit hosts have __uint128_t */
|
||||
@@ -46,7 +45,7 @@ void HELPER(mlg)(uint32_t r1, uint64_t v2)
|
||||
}
|
||||
|
||||
/* 128 -> 64/64 unsigned division */
|
||||
-void HELPER(dlg)(uint32_t r1, uint64_t v2)
|
||||
+void HELPER(dlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
|
||||
{
|
||||
uint64_t divisor = v2;
|
||||
|
||||
@@ -129,7 +128,7 @@ uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
|
||||
}
|
||||
|
||||
/* subtract unsigned v2 from v1 with borrow */
|
||||
-uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
|
||||
+uint32_t HELPER(slb)(CPUS390XState *env, uint32_t cc, uint32_t r1, uint32_t v2)
|
||||
{
|
||||
uint32_t v1 = env->regs[r1];
|
||||
uint32_t res = v1 + (~v2) + (cc >> 1);
|
||||
@@ -144,7 +143,8 @@ uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
|
||||
}
|
||||
|
||||
/* subtract unsigned v2 from v1 with borrow */
|
||||
-uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
|
||||
+uint32_t HELPER(slbg)(CPUS390XState *env, uint32_t cc, uint32_t r1,
|
||||
+ uint64_t v1, uint64_t v2)
|
||||
{
|
||||
uint64_t res = v1 + (~v2) + (cc >> 1);
|
||||
|
||||
@@ -158,7 +158,7 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
|
||||
}
|
||||
|
||||
/* find leftmost one */
|
||||
-uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
|
||||
+uint32_t HELPER(flogr)(CPUS390XState *env, uint32_t r1, uint64_t v2)
|
||||
{
|
||||
uint64_t res = 0;
|
||||
uint64_t ov2 = v2;
|
||||
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
|
||||
index b1f2071..2a61e92 100644
|
||||
--- a/target-s390x/translate.c
|
||||
+++ b/target-s390x/translate.c
|
||||
@@ -1803,7 +1803,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
|
||||
tmp2 = tcg_temp_new_i64();
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
|
||||
- gen_helper_mlg(tmp32_1, tmp2);
|
||||
+ gen_helper_mlg(cpu_env, tmp32_1, tmp2);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
@@ -1811,7 +1811,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
|
||||
tmp2 = tcg_temp_new_i64();
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
|
||||
- gen_helper_dlg(tmp32_1, tmp2);
|
||||
+ gen_helper_dlg(cpu_env, tmp32_1, tmp2);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
@@ -1837,7 +1837,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
|
||||
tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
|
||||
/* XXX possible optimization point */
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_slbg(cc_op, cc_op, tmp32_1, regs[r1], tmp2);
|
||||
+ gen_helper_slbg(cc_op, cpu_env, cc_op, tmp32_1, regs[r1], tmp2);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
@@ -1917,7 +1917,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
|
||||
tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
|
||||
/* XXX possible optimization point */
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_slb(cc_op, cc_op, tmp32_1, tmp32_2);
|
||||
+ gen_helper_slb(cc_op, cpu_env, cc_op, tmp32_1, tmp32_2);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
@@ -3535,7 +3535,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
|
||||
case 0x83: /* FLOGR R1,R2 [RRE] */
|
||||
tmp = load_reg(r2);
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
- gen_helper_flogr(cc_op, tmp32_1, tmp);
|
||||
+ gen_helper_flogr(cc_op, cpu_env, tmp32_1, tmp);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
@@ -3555,7 +3555,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
|
||||
case 0x87: /* DLGR R1,R2 [RRE] */
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
tmp = load_reg(r2);
|
||||
- gen_helper_dlg(tmp32_1, tmp);
|
||||
+ gen_helper_dlg(cpu_env, tmp32_1, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
@@ -3580,7 +3580,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
|
||||
tmp2 = load_reg(r2);
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_slbg(cc_op, cc_op, tmp32_1, tmp, tmp2);
|
||||
+ gen_helper_slbg(cc_op, cpu_env, cc_op, tmp32_1, tmp, tmp2);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
@@ -3647,7 +3647,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
|
||||
tmp32_1 = load_reg32(r2);
|
||||
tmp32_2 = tcg_const_i32(r1);
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_slb(cc_op, cc_op, tmp32_2, tmp32_1);
|
||||
+ gen_helper_slb(cc_op, cpu_env, cc_op, tmp32_2, tmp32_1);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
tcg_temp_free_i32(tmp32_2);
|
||||
--
|
||||
1.7.12.1
|
||||
|
190
0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch
Normal file
190
0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch
Normal file
@ -0,0 +1,190 @@
|
||||
From ead7a100e907eddd0ba9f3cebb5f84c1afb120b8 Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:33:38 +0000
|
||||
Subject: [PATCH] target-s390x: avoid AREG0 for condition code helpers
|
||||
|
||||
Make condition code helpers take a parameter for CPUState instead
|
||||
of relying on global env.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-s390x/Makefile.objs | 1 -
|
||||
target-s390x/cc_helper.c | 11 +++++------
|
||||
target-s390x/helper.h | 10 +++++-----
|
||||
target-s390x/translate.c | 16 ++++++++--------
|
||||
4 files changed, 18 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
|
||||
index 7b2c5c1..736cf33 100644
|
||||
--- a/target-s390x/Makefile.objs
|
||||
+++ b/target-s390x/Makefile.objs
|
||||
@@ -3,6 +3,5 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
-$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
|
||||
index 9c3a2c4..19ef145 100644
|
||||
--- a/target-s390x/cc_helper.c
|
||||
+++ b/target-s390x/cc_helper.c
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "helper.h"
|
||||
|
||||
/* #define DEBUG_HELPER */
|
||||
@@ -500,14 +499,14 @@ uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
|
||||
return do_calc_cc(env, cc_op, src, dst, vr);
|
||||
}
|
||||
|
||||
-uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
|
||||
- uint64_t vr)
|
||||
+uint32_t HELPER(calc_cc)(CPUS390XState *env, uint32_t cc_op, uint64_t src,
|
||||
+ uint64_t dst, uint64_t vr)
|
||||
{
|
||||
return do_calc_cc(env, cc_op, src, dst, vr);
|
||||
}
|
||||
|
||||
/* insert psw mask and condition code into r1 */
|
||||
-void HELPER(ipm)(uint32_t cc, uint32_t r1)
|
||||
+void HELPER(ipm)(CPUS390XState *env, uint32_t cc, uint32_t r1)
|
||||
{
|
||||
uint64_t r = env->regs[r1];
|
||||
|
||||
@@ -519,13 +518,13 @@ void HELPER(ipm)(uint32_t cc, uint32_t r1)
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
-void HELPER(load_psw)(uint64_t mask, uint64_t addr)
|
||||
+void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
|
||||
{
|
||||
load_psw(env, mask, addr);
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void HELPER(sacf)(uint64_t a1)
|
||||
+void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
|
||||
|
||||
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
|
||||
index c03cd59..876b88e 100644
|
||||
--- a/target-s390x/helper.h
|
||||
+++ b/target-s390x/helper.h
|
||||
@@ -36,7 +36,7 @@ DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_PURE|TCG_CALL_CONST, i64, s64)
|
||||
DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_PURE|TCG_CALL_CONST, s64, s64)
|
||||
DEF_HELPER_3(stcmh, void, i32, i64, i32)
|
||||
DEF_HELPER_3(icmh, i32, i32, i64, i32)
|
||||
-DEF_HELPER_2(ipm, void, i32, i32)
|
||||
+DEF_HELPER_3(ipm, void, env, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(addc_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
|
||||
DEF_HELPER_3(stam, void, i32, i64, i32)
|
||||
@@ -115,7 +115,7 @@ DEF_HELPER_3(tr, void, i32, i64, i64)
|
||||
|
||||
DEF_HELPER_2(servc, i32, i32, i64)
|
||||
DEF_HELPER_3(diag, i64, i32, i64, i64)
|
||||
-DEF_HELPER_2(load_psw, void, i64, i64)
|
||||
+DEF_HELPER_3(load_psw, void, env, i64, i64)
|
||||
DEF_HELPER_1(program_interrupt, void, i32)
|
||||
DEF_HELPER_FLAGS_1(stidp, TCG_CALL_CONST, void, i64)
|
||||
DEF_HELPER_FLAGS_1(spx, TCG_CALL_CONST, void, i64)
|
||||
@@ -139,14 +139,14 @@ DEF_HELPER_2(csp, i32, i32, i32)
|
||||
DEF_HELPER_3(mvcs, i32, i64, i64, i64)
|
||||
DEF_HELPER_3(mvcp, i32, i64, i64, i64)
|
||||
DEF_HELPER_3(sigp, i32, i64, i32, i64)
|
||||
-DEF_HELPER_1(sacf, void, i64)
|
||||
+DEF_HELPER_2(sacf, void, env, i64)
|
||||
DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
|
||||
DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
|
||||
DEF_HELPER_2(lra, i32, i64, i32)
|
||||
DEF_HELPER_2(stura, void, i64, i32)
|
||||
DEF_HELPER_2(cksm, void, i32, i32)
|
||||
|
||||
-DEF_HELPER_FLAGS_4(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
|
||||
- i32, i32, i64, i64, i64)
|
||||
+DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
|
||||
+ i32, env, i32, i64, i64, i64)
|
||||
|
||||
#include "def-helper.h"
|
||||
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
|
||||
index 2a61e92..1d87272 100644
|
||||
--- a/target-s390x/translate.c
|
||||
+++ b/target-s390x/translate.c
|
||||
@@ -722,7 +722,7 @@ static void gen_op_calc_cc(DisasContext *s)
|
||||
case CC_OP_NZ_F32:
|
||||
case CC_OP_NZ_F64:
|
||||
/* 1 argument */
|
||||
- gen_helper_calc_cc(cc_op, local_cc_op, dummy, cc_dst, dummy);
|
||||
+ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
|
||||
break;
|
||||
case CC_OP_ICM:
|
||||
case CC_OP_LTGT_32:
|
||||
@@ -735,7 +735,7 @@ static void gen_op_calc_cc(DisasContext *s)
|
||||
case CC_OP_LTGT_F64:
|
||||
case CC_OP_SLAG:
|
||||
/* 2 arguments */
|
||||
- gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, dummy);
|
||||
+ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
|
||||
break;
|
||||
case CC_OP_ADD_64:
|
||||
case CC_OP_ADDU_64:
|
||||
@@ -746,11 +746,11 @@ static void gen_op_calc_cc(DisasContext *s)
|
||||
case CC_OP_SUB_32:
|
||||
case CC_OP_SUBU_32:
|
||||
/* 3 arguments */
|
||||
- gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, cc_vr);
|
||||
+ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
|
||||
break;
|
||||
case CC_OP_DYNAMIC:
|
||||
/* unknown operation - assume 3 arguments and cc_op in env */
|
||||
- gen_helper_calc_cc(cc_op, cc_op, cc_src, cc_dst, cc_vr);
|
||||
+ gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
@@ -2628,7 +2628,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
case 0x22: /* IPM R1 [RRE] */
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_ipm(cc_op, tmp32_1);
|
||||
+ gen_helper_ipm(cpu_env, cc_op, tmp32_1);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
case 0x41: /* CKSM R1,R2 [RRE] */
|
||||
@@ -2916,7 +2916,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_sacf(tmp);
|
||||
+ gen_helper_sacf(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
/* addressing mode has changed, so end the block */
|
||||
s->pc += ilc * 2;
|
||||
@@ -2967,7 +2967,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s));
|
||||
tcg_gen_addi_i64(tmp, tmp, 8);
|
||||
tcg_gen_qemu_ld64(tmp3, tmp, get_mem_index(s));
|
||||
- gen_helper_load_psw(tmp2, tmp3);
|
||||
+ gen_helper_load_psw(cpu_env, tmp2, tmp3);
|
||||
/* we need to keep cc_op intact */
|
||||
s->is_jmp = DISAS_JUMP;
|
||||
tcg_temp_free_i64(tmp);
|
||||
@@ -4527,7 +4527,7 @@ static void disas_s390_insn(DisasContext *s)
|
||||
tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
|
||||
tcg_gen_addi_i64(tmp, tmp, 4);
|
||||
tcg_gen_qemu_ld32u(tmp3, tmp, get_mem_index(s));
|
||||
- gen_helper_load_psw(tmp2, tmp3);
|
||||
+ gen_helper_load_psw(cpu_env, tmp2, tmp3);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i64(tmp3);
|
||||
--
|
||||
1.7.12.1
|
||||
|
411
0014-target-s390x-avoid-AREG0-for-misc-helpers.patch
Normal file
411
0014-target-s390x-avoid-AREG0-for-misc-helpers.patch
Normal file
@ -0,0 +1,411 @@
|
||||
From 208547c7afbe6ee8a9a1f81095e67a6cbe4a37ec Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:33:39 +0000
|
||||
Subject: [PATCH] target-s390x: avoid AREG0 for misc helpers
|
||||
|
||||
Make misc helpers take a parameter for CPUState instead
|
||||
of relying on global env.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
[agraf: fix conflict]
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-s390x/Makefile.objs | 1 -
|
||||
target-s390x/helper.h | 26 +++++++++++-----------
|
||||
target-s390x/mem_helper.c | 2 +-
|
||||
target-s390x/misc_helper.c | 55 +++++++++++++++++++++++++---------------------
|
||||
target-s390x/translate.c | 32 +++++++++++++--------------
|
||||
5 files changed, 60 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
|
||||
index 736cf33..156d946 100644
|
||||
--- a/target-s390x/Makefile.objs
|
||||
+++ b/target-s390x/Makefile.objs
|
||||
@@ -4,4 +4,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
-$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
|
||||
index 876b88e..f4e0b37 100644
|
||||
--- a/target-s390x/helper.h
|
||||
+++ b/target-s390x/helper.h
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "def-helper.h"
|
||||
|
||||
-DEF_HELPER_1(exception, void, i32)
|
||||
+DEF_HELPER_2(exception, void, env, i32)
|
||||
DEF_HELPER_3(nc, i32, i32, i64, i64)
|
||||
DEF_HELPER_3(oc, i32, i32, i64, i64)
|
||||
DEF_HELPER_3(xc, i32, i32, i64, i64)
|
||||
@@ -113,20 +113,20 @@ DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
|
||||
DEF_HELPER_3(unpk, void, i32, i64, i64)
|
||||
DEF_HELPER_3(tr, void, i32, i64, i64)
|
||||
|
||||
-DEF_HELPER_2(servc, i32, i32, i64)
|
||||
-DEF_HELPER_3(diag, i64, i32, i64, i64)
|
||||
+DEF_HELPER_3(servc, i32, env, i32, i64)
|
||||
+DEF_HELPER_4(diag, i64, env, i32, i64, i64)
|
||||
DEF_HELPER_3(load_psw, void, env, i64, i64)
|
||||
DEF_HELPER_1(program_interrupt, void, i32)
|
||||
-DEF_HELPER_FLAGS_1(stidp, TCG_CALL_CONST, void, i64)
|
||||
-DEF_HELPER_FLAGS_1(spx, TCG_CALL_CONST, void, i64)
|
||||
+DEF_HELPER_FLAGS_2(stidp, TCG_CALL_CONST, void, env, i64)
|
||||
+DEF_HELPER_FLAGS_2(spx, TCG_CALL_CONST, void, env, i64)
|
||||
DEF_HELPER_FLAGS_1(sck, TCG_CALL_CONST, i32, i64)
|
||||
-DEF_HELPER_1(stck, i32, i64)
|
||||
-DEF_HELPER_1(stcke, i32, i64)
|
||||
-DEF_HELPER_FLAGS_1(sckc, TCG_CALL_CONST, void, i64)
|
||||
-DEF_HELPER_FLAGS_1(stckc, TCG_CALL_CONST, void, i64)
|
||||
-DEF_HELPER_FLAGS_1(spt, TCG_CALL_CONST, void, i64)
|
||||
-DEF_HELPER_FLAGS_1(stpt, TCG_CALL_CONST, void, i64)
|
||||
-DEF_HELPER_3(stsi, i32, i64, i32, i32)
|
||||
+DEF_HELPER_2(stck, i32, env, i64)
|
||||
+DEF_HELPER_2(stcke, i32, env, i64)
|
||||
+DEF_HELPER_FLAGS_2(sckc, TCG_CALL_CONST, void, env, i64)
|
||||
+DEF_HELPER_FLAGS_2(stckc, TCG_CALL_CONST, void, env, i64)
|
||||
+DEF_HELPER_FLAGS_2(spt, TCG_CALL_CONST, void, env, i64)
|
||||
+DEF_HELPER_FLAGS_2(stpt, TCG_CALL_CONST, void, env, i64)
|
||||
+DEF_HELPER_4(stsi, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_3(lctl, void, i32, i64, i32)
|
||||
DEF_HELPER_3(lctlg, void, i32, i64, i32)
|
||||
DEF_HELPER_3(stctl, void, i32, i64, i32)
|
||||
@@ -138,7 +138,7 @@ DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_CONST, i32, i32, i64)
|
||||
DEF_HELPER_2(csp, i32, i32, i32)
|
||||
DEF_HELPER_3(mvcs, i32, i64, i64, i64)
|
||||
DEF_HELPER_3(mvcp, i32, i64, i64, i64)
|
||||
-DEF_HELPER_3(sigp, i32, i64, i32, i64)
|
||||
+DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
|
||||
DEF_HELPER_2(sacf, void, env, i64)
|
||||
DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
|
||||
DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
|
||||
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
|
||||
index 3f8b3ba..52f2602 100644
|
||||
--- a/target-s390x/mem_helper.c
|
||||
+++ b/target-s390x/mem_helper.c
|
||||
@@ -595,7 +595,7 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
|
||||
env->psw.addr = ret - 4;
|
||||
env->int_svc_code = (insn | v1) & 0xff;
|
||||
env->int_svc_ilc = 4;
|
||||
- helper_exception(EXCP_SVC);
|
||||
+ helper_exception(env, EXCP_SVC);
|
||||
} else if ((insn & 0xff00) == 0xbf00) {
|
||||
uint32_t insn2, r1, r3, b2, d2;
|
||||
|
||||
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
|
||||
index 1d5137f..ced26c6 100644
|
||||
--- a/target-s390x/misc_helper.c
|
||||
+++ b/target-s390x/misc_helper.c
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "cpu.h"
|
||||
#include "memory.h"
|
||||
#include "cputlb.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "host-utils.h"
|
||||
#include "helper.h"
|
||||
#include <string.h>
|
||||
@@ -32,7 +31,10 @@
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
+/* temporarily disabled due to wrapper use */
|
||||
+#if 0
|
||||
#include "softmmu_exec.h"
|
||||
+#endif
|
||||
#include "sysemu.h"
|
||||
#endif
|
||||
|
||||
@@ -44,7 +46,7 @@
|
||||
#endif
|
||||
|
||||
/* raise an exception */
|
||||
-void HELPER(exception)(uint32_t excp)
|
||||
+void HELPER(exception)(CPUS390XState *env, uint32_t excp)
|
||||
{
|
||||
HELPER_LOG("%s: exception %d\n", __func__, excp);
|
||||
env->exception_index = excp;
|
||||
@@ -112,7 +114,7 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
|
||||
}
|
||||
|
||||
/* SCLP service call */
|
||||
-uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
|
||||
+uint32_t HELPER(servc)(CPUS390XState *env, uint32_t r1, uint64_t r2)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -125,7 +127,8 @@ uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
|
||||
}
|
||||
|
||||
/* DIAG */
|
||||
-uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
|
||||
+uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
|
||||
+ uint64_t code)
|
||||
{
|
||||
uint64_t r;
|
||||
|
||||
@@ -155,17 +158,17 @@ uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
|
||||
}
|
||||
|
||||
/* Store CPU ID */
|
||||
-void HELPER(stidp)(uint64_t a1)
|
||||
+void HELPER(stidp)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
- stq(a1, env->cpu_num);
|
||||
+ cpu_stq_data(env, a1, env->cpu_num);
|
||||
}
|
||||
|
||||
/* Set Prefix */
|
||||
-void HELPER(spx)(uint64_t a1)
|
||||
+void HELPER(spx)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
uint32_t prefix;
|
||||
|
||||
- prefix = ldl(a1);
|
||||
+ prefix = cpu_ldl_data(env, a1);
|
||||
env->psa = prefix & 0xfffff000;
|
||||
qemu_log("prefix: %#x\n", prefix);
|
||||
tlb_flush_page(env, 0);
|
||||
@@ -191,31 +194,31 @@ static inline uint64_t clock_value(CPUS390XState *env)
|
||||
}
|
||||
|
||||
/* Store Clock */
|
||||
-uint32_t HELPER(stck)(uint64_t a1)
|
||||
+uint32_t HELPER(stck)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
- stq(a1, clock_value(env));
|
||||
+ cpu_stq_data(env, a1, clock_value(env));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Store Clock Extended */
|
||||
-uint32_t HELPER(stcke)(uint64_t a1)
|
||||
+uint32_t HELPER(stcke)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
- stb(a1, 0);
|
||||
+ cpu_stb_data(env, a1, 0);
|
||||
/* basically the same value as stck */
|
||||
- stq(a1 + 1, clock_value(env) | env->cpu_num);
|
||||
+ cpu_stq_data(env, a1 + 1, clock_value(env) | env->cpu_num);
|
||||
/* more fine grained than stck */
|
||||
- stq(a1 + 9, 0);
|
||||
+ cpu_stq_data(env, a1 + 9, 0);
|
||||
/* XXX programmable fields */
|
||||
- stw(a1 + 17, 0);
|
||||
+ cpu_stw_data(env, a1 + 17, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set Clock Comparator */
|
||||
-void HELPER(sckc)(uint64_t a1)
|
||||
+void HELPER(sckc)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
- uint64_t time = ldq(a1);
|
||||
+ uint64_t time = cpu_ldq_data(env, a1);
|
||||
|
||||
if (time == -1ULL) {
|
||||
return;
|
||||
@@ -230,16 +233,16 @@ void HELPER(sckc)(uint64_t a1)
|
||||
}
|
||||
|
||||
/* Store Clock Comparator */
|
||||
-void HELPER(stckc)(uint64_t a1)
|
||||
+void HELPER(stckc)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
/* XXX implement */
|
||||
- stq(a1, 0);
|
||||
+ cpu_stq_data(env, a1, 0);
|
||||
}
|
||||
|
||||
/* Set CPU Timer */
|
||||
-void HELPER(spt)(uint64_t a1)
|
||||
+void HELPER(spt)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
- uint64_t time = ldq(a1);
|
||||
+ uint64_t time = cpu_ldq_data(env, a1);
|
||||
|
||||
if (time == -1ULL) {
|
||||
return;
|
||||
@@ -252,14 +255,15 @@ void HELPER(spt)(uint64_t a1)
|
||||
}
|
||||
|
||||
/* Store CPU Timer */
|
||||
-void HELPER(stpt)(uint64_t a1)
|
||||
+void HELPER(stpt)(CPUS390XState *env, uint64_t a1)
|
||||
{
|
||||
/* XXX implement */
|
||||
- stq(a1, 0);
|
||||
+ cpu_stq_data(env, a1, 0);
|
||||
}
|
||||
|
||||
/* Store System Information */
|
||||
-uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
|
||||
+uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint32_t r0,
|
||||
+ uint32_t r1)
|
||||
{
|
||||
int cc = 0;
|
||||
int sel1, sel2;
|
||||
@@ -384,7 +388,8 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
|
||||
return cc;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
|
||||
+uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
|
||||
+ uint64_t cpu_addr)
|
||||
{
|
||||
int cc = 0;
|
||||
|
||||
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
|
||||
index 1d87272..0c61e63 100644
|
||||
--- a/target-s390x/translate.c
|
||||
+++ b/target-s390x/translate.c
|
||||
@@ -312,7 +312,7 @@ static inline void gen_debug(DisasContext *s)
|
||||
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
|
||||
update_psw_addr(s);
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_exception(tmp);
|
||||
+ gen_helper_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
s->is_jmp = DISAS_EXCP;
|
||||
}
|
||||
@@ -324,7 +324,7 @@ static void gen_illegal_opcode(DisasContext *s, int ilc)
|
||||
TCGv_i32 tmp = tcg_const_i32(EXCP_SPEC);
|
||||
update_psw_addr(s);
|
||||
gen_op_calc_cc(s);
|
||||
- gen_helper_exception(tmp);
|
||||
+ gen_helper_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
s->is_jmp = DISAS_EXCP;
|
||||
}
|
||||
@@ -377,7 +377,7 @@ static void gen_program_exception(DisasContext *s, int ilc, int code)
|
||||
|
||||
/* trigger exception */
|
||||
tmp = tcg_const_i32(EXCP_PGM);
|
||||
- gen_helper_exception(tmp);
|
||||
+ gen_helper_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
|
||||
/* end TB here */
|
||||
@@ -2712,7 +2712,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_stidp(tmp);
|
||||
+ gen_helper_stidp(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x04: /* SCK D2(B2) [S] */
|
||||
@@ -2730,7 +2730,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_stck(cc_op, tmp);
|
||||
+ gen_helper_stck(cc_op, cpu_env, tmp);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
@@ -2740,7 +2740,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_sckc(tmp);
|
||||
+ gen_helper_sckc(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x07: /* STCKC D2(B2) [S] */
|
||||
@@ -2749,7 +2749,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_stckc(tmp);
|
||||
+ gen_helper_stckc(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x08: /* SPT D2(B2) [S] */
|
||||
@@ -2758,7 +2758,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_spt(tmp);
|
||||
+ gen_helper_spt(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x09: /* STPT D2(B2) [S] */
|
||||
@@ -2767,7 +2767,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_stpt(tmp);
|
||||
+ gen_helper_stpt(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x0a: /* SPKA D2(B2) [S] */
|
||||
@@ -2793,7 +2793,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_spx(tmp);
|
||||
+ gen_helper_spx(cpu_env, tmp);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x11: /* STPX D2(B2) [S] */
|
||||
@@ -2906,7 +2906,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||
tmp = get_address(s, 0, b2, d2);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_stcke(cc_op, tmp);
|
||||
+ gen_helper_stcke(cc_op, cpu_env, tmp);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
@@ -2930,7 +2930,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
tmp32_1 = load_reg32(0);
|
||||
tmp32_2 = load_reg32(1);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_stsi(cc_op, tmp, tmp32_1, tmp32_2);
|
||||
+ gen_helper_stsi(cc_op, cpu_env, tmp, tmp32_1, tmp32_2);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
@@ -2980,7 +2980,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
|
||||
potential_page_fault(s);
|
||||
tmp32_1 = load_reg32(r2);
|
||||
tmp = load_reg(r1);
|
||||
- gen_helper_servc(cc_op, tmp32_1, tmp);
|
||||
+ gen_helper_servc(cc_op, cpu_env, tmp32_1, tmp);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
tcg_temp_free_i64(tmp);
|
||||
@@ -3926,7 +3926,7 @@ static void disas_s390_insn(DisasContext *s)
|
||||
tmp32_3 = tcg_const_i32(EXCP_SVC);
|
||||
tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, int_svc_code));
|
||||
tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUS390XState, int_svc_ilc));
|
||||
- gen_helper_exception(tmp32_3);
|
||||
+ gen_helper_exception(cpu_env, tmp32_3);
|
||||
s->is_jmp = DISAS_EXCP;
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
tcg_temp_free_i32(tmp32_2);
|
||||
@@ -4543,7 +4543,7 @@ static void disas_s390_insn(DisasContext *s)
|
||||
tmp32_1 = tcg_const_i32(insn & 0xfff);
|
||||
tmp2 = load_reg(2);
|
||||
tmp3 = load_reg(1);
|
||||
- gen_helper_diag(tmp2, tmp32_1, tmp2, tmp3);
|
||||
+ gen_helper_diag(tmp2, cpu_env, tmp32_1, tmp2, tmp3);
|
||||
store_reg(2, tmp2);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
@@ -4777,7 +4777,7 @@ static void disas_s390_insn(DisasContext *s)
|
||||
tmp2 = load_reg(r3);
|
||||
tmp32_1 = tcg_const_i32(r1);
|
||||
potential_page_fault(s);
|
||||
- gen_helper_sigp(cc_op, tmp, tmp32_1, tmp2);
|
||||
+ gen_helper_sigp(cc_op, cpu_env, tmp, tmp32_1, tmp2);
|
||||
set_cc_static(s);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
--
|
||||
1.7.12.1
|
||||
|
1584
0015-target-s390x-switch-to-AREG0-free-mode.patch
Normal file
1584
0015-target-s390x-switch-to-AREG0-free-mode.patch
Normal file
File diff suppressed because it is too large
Load Diff
64
0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch
Normal file
64
0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 0b95df52ecad351c916108e9f3a9d1bc3327b495 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Sat, 8 Sep 2012 03:45:43 +0000
|
||||
Subject: [PATCH] tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0
|
||||
|
||||
The load/store slow path has been broken in e141ab52d:
|
||||
- We need to move 4 registers for store functions and 3 registers for
|
||||
load functions and not the reverse.
|
||||
- According to the s390x calling convention the arguments of a function
|
||||
should be zero extended. This means that the register shift should be
|
||||
done with TCG_TYPE_I64 to ensure the higher word is correctly zero
|
||||
extended when needed.
|
||||
|
||||
I am aware that CONFIG_TCG_PASS_AREG0 is being removed and thus that
|
||||
this patch can be improved, but doing so means it can also be applied to
|
||||
the 1.1 and 1.2 stable branches.
|
||||
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/s390/tcg-target.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
|
||||
index 04662c1..99b5339 100644
|
||||
--- a/tcg/s390/tcg-target.c
|
||||
+++ b/tcg/s390/tcg-target.c
|
||||
@@ -1509,11 +1509,13 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
|
||||
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
|
||||
#ifdef CONFIG_TCG_PASS_AREG0
|
||||
/* XXX/FIXME: suboptimal */
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
|
||||
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
|
||||
+ tcg_target_call_iarg_regs[2]);
|
||||
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
|
||||
tcg_target_call_iarg_regs[1]);
|
||||
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
|
||||
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
|
||||
tcg_target_call_iarg_regs[0]);
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
|
||||
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
|
||||
TCG_AREG0);
|
||||
#endif
|
||||
tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
|
||||
@@ -1521,13 +1523,11 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
|
||||
tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
|
||||
#ifdef CONFIG_TCG_PASS_AREG0
|
||||
/* XXX/FIXME: suboptimal */
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
|
||||
- tcg_target_call_iarg_regs[2]);
|
||||
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
|
||||
tcg_target_call_iarg_regs[1]);
|
||||
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
|
||||
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
|
||||
tcg_target_call_iarg_regs[0]);
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
|
||||
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
|
||||
TCG_AREG0);
|
||||
#endif
|
||||
tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
|
||||
--
|
||||
1.7.12.1
|
||||
|
47
0017-target-arm-Fix-potential-buffer-overflow.patch
Normal file
47
0017-target-arm-Fix-potential-buffer-overflow.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From e7c3f6b4365f3162f8e25d58f76410aca28719a2 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Weil <sw@weilnetz.de>
|
||||
Date: Tue, 4 Sep 2012 07:35:57 +0200
|
||||
Subject: [PATCH] target-arm: Fix potential buffer overflow
|
||||
|
||||
Report from smatch:
|
||||
|
||||
target-arm/helper.c:651 arm946_prbs_read(6) error:
|
||||
buffer overflow 'env->cp15.c6_region' 8 <= 8
|
||||
target-arm/helper.c:661 arm946_prbs_write(6) error:
|
||||
buffer overflow 'env->cp15.c6_region' 8 <= 8
|
||||
|
||||
c7_region is an array with 8 elements, so the index must be less than 8.
|
||||
|
||||
Signed-off-by: Stefan Weil <sw@weilnetz.de>
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-arm/helper.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target-arm/helper.c b/target-arm/helper.c
|
||||
index dceaa95..e27df96 100644
|
||||
--- a/target-arm/helper.c
|
||||
+++ b/target-arm/helper.c
|
||||
@@ -645,7 +645,7 @@ static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t *value)
|
||||
{
|
||||
- if (ri->crm > 8) {
|
||||
+ if (ri->crm >= 8) {
|
||||
return EXCP_UDEF;
|
||||
}
|
||||
*value = env->cp15.c6_region[ri->crm];
|
||||
@@ -655,7 +655,7 @@ static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
- if (ri->crm > 8) {
|
||||
+ if (ri->crm >= 8) {
|
||||
return EXCP_UDEF;
|
||||
}
|
||||
env->cp15.c6_region[ri->crm] = value;
|
||||
--
|
||||
1.7.12.1
|
||||
|
57
0018-tcg-optimize-split-expression-simplification.patch
Normal file
57
0018-tcg-optimize-split-expression-simplification.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 16f29b266435c7eaffc5081c6bba4651d56a8ce8 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:13 +0200
|
||||
Subject: [PATCH] tcg/optimize: split expression simplification
|
||||
|
||||
Split expression simplification in multiple parts so that a given op
|
||||
can appear multiple times. This patch should not change anything.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 9c65474..63f970d 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -322,7 +322,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
break;
|
||||
}
|
||||
|
||||
- /* Simplify expression if possible. */
|
||||
+ /* Simplify expression for "op r, a, 0 => mov r, a" cases */
|
||||
switch (op) {
|
||||
CASE_OP_32_64(add):
|
||||
CASE_OP_32_64(sub):
|
||||
@@ -352,6 +352,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
|
||||
+ switch (op) {
|
||||
CASE_OP_32_64(mul):
|
||||
if ((temps[args[2]].state == TCG_TEMP_CONST
|
||||
&& temps[args[2]].val == 0)) {
|
||||
@@ -362,6 +368,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Simplify expression for "op r, a, a => mov r, a" cases */
|
||||
+ switch (op) {
|
||||
CASE_OP_32_64(or):
|
||||
CASE_OP_32_64(and):
|
||||
if (args[1] == args[2]) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
30
0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch
Normal file
30
0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From f69f9bd1a7a095ee153eea5422651780aef178b0 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:14 +0200
|
||||
Subject: [PATCH] tcg/optimize: simplify or/xor r, a, 0 cases
|
||||
|
||||
or/xor r, a, 0 is equivalent to a mov r, a.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 63f970d..0db849e 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -331,6 +331,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
CASE_OP_32_64(sar):
|
||||
CASE_OP_32_64(rotl):
|
||||
CASE_OP_32_64(rotr):
|
||||
+ CASE_OP_32_64(or):
|
||||
+ CASE_OP_32_64(xor):
|
||||
if (temps[args[1]].state == TCG_TEMP_CONST) {
|
||||
/* Proceed with possible constant folding. */
|
||||
break;
|
||||
--
|
||||
1.7.12.1
|
||||
|
29
0020-tcg-optimize-simplify-and-r-a-0-cases.patch
Normal file
29
0020-tcg-optimize-simplify-and-r-a-0-cases.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From f08c59ce7dee67a95cf06d9588b4312e7d071788 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:14 +0200
|
||||
Subject: [PATCH] tcg/optimize: simplify and r, a, 0 cases
|
||||
|
||||
and r, a, 0 is equivalent to a movi r, 0.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 0db849e..c12cb2b 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -360,6 +360,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
|
||||
/* Simplify expression for "op r, a, 0 => movi r, 0" cases */
|
||||
switch (op) {
|
||||
+ CASE_OP_32_64(and):
|
||||
CASE_OP_32_64(mul):
|
||||
if ((temps[args[2]].state == TCG_TEMP_CONST
|
||||
&& temps[args[2]].val == 0)) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -0,0 +1,48 @@
|
||||
From bbed332c7ad12e9885d3f457f366fa0b29445dcd Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:14 +0200
|
||||
Subject: [PATCH] tcg/optimize: simplify shift/rot r, 0, a => movi r, 0 cases
|
||||
|
||||
shift/rot r, 0, a is equivalent to movi r, 0.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index c12cb2b..1698ba3 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -322,6 +322,26 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
|
||||
+ switch (op) {
|
||||
+ CASE_OP_32_64(shl):
|
||||
+ CASE_OP_32_64(shr):
|
||||
+ CASE_OP_32_64(sar):
|
||||
+ CASE_OP_32_64(rotl):
|
||||
+ CASE_OP_32_64(rotr):
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[1]].val == 0) {
|
||||
+ gen_opc_buf[op_index] = op_to_movi(op);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
|
||||
+ args += 3;
|
||||
+ gen_args += 2;
|
||||
+ continue;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Simplify expression for "op r, a, 0 => mov r, a" cases */
|
||||
switch (op) {
|
||||
CASE_OP_32_64(add):
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 1127ad0d084f0cef11b5658b3dbbf8505d8d3af0 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:14 +0200
|
||||
Subject: [PATCH] tcg/optimize: swap brcond/setcond arguments when possible
|
||||
|
||||
brcond and setcond ops are not commutative, but it's easy to compute the
|
||||
new condition after swapping the arguments. Try to always put the constant
|
||||
argument in second position like for commutative ops, to help backends to
|
||||
generate better code.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 1698ba3..7debc8a 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -318,6 +318,24 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args[2] = tmp;
|
||||
}
|
||||
break;
|
||||
+ CASE_OP_32_64(brcond):
|
||||
+ if (temps[args[0]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[1]].state != TCG_TEMP_CONST) {
|
||||
+ tmp = args[0];
|
||||
+ args[0] = args[1];
|
||||
+ args[1] = tmp;
|
||||
+ args[2] = tcg_swap_cond(args[2]);
|
||||
+ }
|
||||
+ break;
|
||||
+ CASE_OP_32_64(setcond):
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[2]].state != TCG_TEMP_CONST) {
|
||||
+ tmp = args[1];
|
||||
+ args[1] = args[2];
|
||||
+ args[2] = tmp;
|
||||
+ args[3] = tcg_swap_cond(args[3]);
|
||||
+ }
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
--
|
||||
1.7.12.1
|
||||
|
114
0023-tcg-optimize-add-constant-folding-for-setcond.patch
Normal file
114
0023-tcg-optimize-add-constant-folding-for-setcond.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 1bbb9ac3e775b55d0d5c57c209f47e742a9be810 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:14 +0200
|
||||
Subject: [PATCH] tcg/optimize: add constant folding for setcond
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 81 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 7debc8a..1cb1f36 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -267,6 +267,67 @@ static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
|
||||
return res;
|
||||
}
|
||||
|
||||
+static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
|
||||
+ TCGArg y, TCGCond c)
|
||||
+{
|
||||
+ switch (op_bits(op)) {
|
||||
+ case 32:
|
||||
+ switch (c) {
|
||||
+ case TCG_COND_EQ:
|
||||
+ return (uint32_t)x == (uint32_t)y;
|
||||
+ case TCG_COND_NE:
|
||||
+ return (uint32_t)x != (uint32_t)y;
|
||||
+ case TCG_COND_LT:
|
||||
+ return (int32_t)x < (int32_t)y;
|
||||
+ case TCG_COND_GE:
|
||||
+ return (int32_t)x >= (int32_t)y;
|
||||
+ case TCG_COND_LE:
|
||||
+ return (int32_t)x <= (int32_t)y;
|
||||
+ case TCG_COND_GT:
|
||||
+ return (int32_t)x > (int32_t)y;
|
||||
+ case TCG_COND_LTU:
|
||||
+ return (uint32_t)x < (uint32_t)y;
|
||||
+ case TCG_COND_GEU:
|
||||
+ return (uint32_t)x >= (uint32_t)y;
|
||||
+ case TCG_COND_LEU:
|
||||
+ return (uint32_t)x <= (uint32_t)y;
|
||||
+ case TCG_COND_GTU:
|
||||
+ return (uint32_t)x > (uint32_t)y;
|
||||
+ }
|
||||
+ break;
|
||||
+ case 64:
|
||||
+ switch (c) {
|
||||
+ case TCG_COND_EQ:
|
||||
+ return (uint64_t)x == (uint64_t)y;
|
||||
+ case TCG_COND_NE:
|
||||
+ return (uint64_t)x != (uint64_t)y;
|
||||
+ case TCG_COND_LT:
|
||||
+ return (int64_t)x < (int64_t)y;
|
||||
+ case TCG_COND_GE:
|
||||
+ return (int64_t)x >= (int64_t)y;
|
||||
+ case TCG_COND_LE:
|
||||
+ return (int64_t)x <= (int64_t)y;
|
||||
+ case TCG_COND_GT:
|
||||
+ return (int64_t)x > (int64_t)y;
|
||||
+ case TCG_COND_LTU:
|
||||
+ return (uint64_t)x < (uint64_t)y;
|
||||
+ case TCG_COND_GEU:
|
||||
+ return (uint64_t)x >= (uint64_t)y;
|
||||
+ case TCG_COND_LEU:
|
||||
+ return (uint64_t)x <= (uint64_t)y;
|
||||
+ case TCG_COND_GTU:
|
||||
+ return (uint64_t)x > (uint64_t)y;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "Unrecognized bitness %d or condition %d in "
|
||||
+ "do_constant_folding_cond.\n", op_bits(op), c);
|
||||
+ tcg_abort();
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Propagate constants and copies, fold constant expressions. */
|
||||
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
TCGArg *args, TCGOpDef *tcg_op_defs)
|
||||
@@ -522,6 +583,26 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args += 3;
|
||||
break;
|
||||
}
|
||||
+ CASE_OP_32_64(setcond):
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
+ gen_opc_buf[op_index] = op_to_movi(op);
|
||||
+ tmp = do_constant_folding_cond(op, temps[args[1]].val,
|
||||
+ temps[args[2]].val, args[3]);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
+ gen_args += 2;
|
||||
+ args += 4;
|
||||
+ break;
|
||||
+ } else {
|
||||
+ reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ gen_args[0] = args[0];
|
||||
+ gen_args[1] = args[1];
|
||||
+ gen_args[2] = args[2];
|
||||
+ gen_args[3] = args[3];
|
||||
+ gen_args += 4;
|
||||
+ args += 4;
|
||||
+ break;
|
||||
+ }
|
||||
case INDEX_op_call:
|
||||
nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
|
||||
if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
60
0024-tcg-optimize-add-constant-folding-for-brcond.patch
Normal file
60
0024-tcg-optimize-add-constant-folding-for-brcond.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 98dc31743b94d5719c02c589e7cd652e95570b25 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 6 Sep 2012 16:47:14 +0200
|
||||
Subject: [PATCH] tcg/optimize: add constant folding for brcond
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 27 ++++++++++++++++++++++++++-
|
||||
1 file changed, 26 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 1cb1f36..156e8d9 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -603,6 +603,32 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args += 4;
|
||||
break;
|
||||
}
|
||||
+ CASE_OP_32_64(brcond):
|
||||
+ if (temps[args[0]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[1]].state == TCG_TEMP_CONST) {
|
||||
+ if (do_constant_folding_cond(op, temps[args[0]].val,
|
||||
+ temps[args[1]].val, args[2])) {
|
||||
+ memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
+ gen_opc_buf[op_index] = INDEX_op_br;
|
||||
+ gen_args[0] = args[3];
|
||||
+ gen_args += 1;
|
||||
+ args += 4;
|
||||
+ } else {
|
||||
+ gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
+ args += 4;
|
||||
+ }
|
||||
+ break;
|
||||
+ } else {
|
||||
+ memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
+ reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ gen_args[0] = args[0];
|
||||
+ gen_args[1] = args[1];
|
||||
+ gen_args[2] = args[2];
|
||||
+ gen_args[3] = args[3];
|
||||
+ gen_args += 4;
|
||||
+ args += 4;
|
||||
+ break;
|
||||
+ }
|
||||
case INDEX_op_call:
|
||||
nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
|
||||
if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
|
||||
@@ -624,7 +650,6 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
case INDEX_op_set_label:
|
||||
case INDEX_op_jmp:
|
||||
case INDEX_op_br:
|
||||
- CASE_OP_32_64(brcond):
|
||||
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
for (i = 0; i < def->nb_args; i++) {
|
||||
*gen_args = *args;
|
||||
--
|
||||
1.7.12.1
|
||||
|
144
0025-tcg-optimize-fix-if-else-break-coding-style.patch
Normal file
144
0025-tcg-optimize-fix-if-else-break-coding-style.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From b7dc881b44c3698a0a81d226d6012d3c5833fd29 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 7 Sep 2012 12:24:32 +0200
|
||||
Subject: [PATCH] tcg/optimize: fix if/else/break coding style
|
||||
|
||||
optimizer.c contains some cases were the break is appearing in both the
|
||||
if and the else parts. Fix that by moving it to the outer part. Also
|
||||
move some common code there.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 34 +++++++++++-----------------------
|
||||
1 file changed, 11 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 156e8d9..fba0ed9 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -441,15 +441,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
if ((temps[args[0]].state == TCG_TEMP_COPY
|
||||
&& temps[args[0]].val == args[1])
|
||||
|| args[0] == args[1]) {
|
||||
- args += 3;
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
tcg_opt_gen_mov(s, gen_args, args[0], args[1],
|
||||
nb_temps, nb_globals);
|
||||
gen_args += 2;
|
||||
- args += 3;
|
||||
}
|
||||
+ args += 3;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -480,15 +479,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
CASE_OP_32_64(and):
|
||||
if (args[1] == args[2]) {
|
||||
if (args[1] == args[0]) {
|
||||
- args += 3;
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
|
||||
nb_globals);
|
||||
gen_args += 2;
|
||||
- args += 3;
|
||||
}
|
||||
+ args += 3;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -538,17 +536,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
tmp = do_constant_folding(op, temps[args[1]].val, 0);
|
||||
tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
- gen_args += 2;
|
||||
- args += 2;
|
||||
- break;
|
||||
} else {
|
||||
reset_temp(args[0], nb_temps, nb_globals);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
- gen_args += 2;
|
||||
- args += 2;
|
||||
- break;
|
||||
}
|
||||
+ gen_args += 2;
|
||||
+ args += 2;
|
||||
+ break;
|
||||
CASE_OP_32_64(add):
|
||||
CASE_OP_32_64(sub):
|
||||
CASE_OP_32_64(mul):
|
||||
@@ -572,17 +567,15 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
temps[args[2]].val);
|
||||
tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
gen_args += 2;
|
||||
- args += 3;
|
||||
- break;
|
||||
} else {
|
||||
reset_temp(args[0], nb_temps, nb_globals);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
gen_args[2] = args[2];
|
||||
gen_args += 3;
|
||||
- args += 3;
|
||||
- break;
|
||||
}
|
||||
+ args += 3;
|
||||
+ break;
|
||||
CASE_OP_32_64(setcond):
|
||||
if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
&& temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
@@ -591,8 +584,6 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
temps[args[2]].val, args[3]);
|
||||
tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
gen_args += 2;
|
||||
- args += 4;
|
||||
- break;
|
||||
} else {
|
||||
reset_temp(args[0], nb_temps, nb_globals);
|
||||
gen_args[0] = args[0];
|
||||
@@ -600,9 +591,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_args[2] = args[2];
|
||||
gen_args[3] = args[3];
|
||||
gen_args += 4;
|
||||
- args += 4;
|
||||
- break;
|
||||
}
|
||||
+ args += 4;
|
||||
+ break;
|
||||
CASE_OP_32_64(brcond):
|
||||
if (temps[args[0]].state == TCG_TEMP_CONST
|
||||
&& temps[args[1]].state == TCG_TEMP_CONST) {
|
||||
@@ -612,12 +603,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = INDEX_op_br;
|
||||
gen_args[0] = args[3];
|
||||
gen_args += 1;
|
||||
- args += 4;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
- args += 4;
|
||||
}
|
||||
- break;
|
||||
} else {
|
||||
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
reset_temp(args[0], nb_temps, nb_globals);
|
||||
@@ -626,9 +614,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_args[2] = args[2];
|
||||
gen_args[3] = args[3];
|
||||
gen_args += 4;
|
||||
- args += 4;
|
||||
- break;
|
||||
}
|
||||
+ args += 4;
|
||||
+ break;
|
||||
case INDEX_op_call:
|
||||
nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
|
||||
if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
1337
0026-target-s390x-avoid-cpu_single_env.patch
Normal file
1337
0026-target-s390x-avoid-cpu_single_env.patch
Normal file
File diff suppressed because it is too large
Load Diff
282
0027-target-lm32-switch-to-AREG0-free-mode.patch
Normal file
282
0027-target-lm32-switch-to-AREG0-free-mode.patch
Normal file
@ -0,0 +1,282 @@
|
||||
From 25e9a95d0571c40738daa479467d757eb477739e Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 06:57:17 +0000
|
||||
Subject: [PATCH] target-lm32: switch to AREG0 free mode
|
||||
|
||||
Add an explicit CPUState parameter instead of relying on AREG0
|
||||
and switch to AREG0 free mode.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 2 +-
|
||||
target-lm32/Makefile.objs | 2 --
|
||||
target-lm32/helper.h | 20 ++++++++++----------
|
||||
target-lm32/op_helper.c | 29 +++++++++++------------------
|
||||
target-lm32/translate.c | 28 +++++++++++++---------------
|
||||
5 files changed, 35 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 3ad6f74..1e3ea7f 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
|
||||
|
||||
|
||||
case "$target_arch2" in
|
||||
- alpha | i386 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
||||
+ alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
||||
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
|
||||
;;
|
||||
esac
|
||||
diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs
|
||||
index 2e0e093..ca20f21 100644
|
||||
--- a/target-lm32/Makefile.objs
|
||||
+++ b/target-lm32/Makefile.objs
|
||||
@@ -1,4 +1,2 @@
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
-
|
||||
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-lm32/helper.h b/target-lm32/helper.h
|
||||
index 9d335ef..07f5670 100644
|
||||
--- a/target-lm32/helper.h
|
||||
+++ b/target-lm32/helper.h
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "def-helper.h"
|
||||
|
||||
-DEF_HELPER_1(raise_exception, void, i32)
|
||||
-DEF_HELPER_0(hlt, void)
|
||||
-DEF_HELPER_1(wcsr_im, void, i32)
|
||||
-DEF_HELPER_1(wcsr_ip, void, i32)
|
||||
-DEF_HELPER_1(wcsr_jtx, void, i32)
|
||||
-DEF_HELPER_1(wcsr_jrx, void, i32)
|
||||
-DEF_HELPER_0(rcsr_im, i32)
|
||||
-DEF_HELPER_0(rcsr_ip, i32)
|
||||
-DEF_HELPER_0(rcsr_jtx, i32)
|
||||
-DEF_HELPER_0(rcsr_jrx, i32)
|
||||
+DEF_HELPER_2(raise_exception, void, env, i32)
|
||||
+DEF_HELPER_1(hlt, void, env)
|
||||
+DEF_HELPER_2(wcsr_im, void, env, i32)
|
||||
+DEF_HELPER_2(wcsr_ip, void, env, i32)
|
||||
+DEF_HELPER_2(wcsr_jtx, void, env, i32)
|
||||
+DEF_HELPER_2(wcsr_jrx, void, env, i32)
|
||||
+DEF_HELPER_1(rcsr_im, i32, env)
|
||||
+DEF_HELPER_1(rcsr_ip, i32, env)
|
||||
+DEF_HELPER_1(rcsr_jtx, i32, env)
|
||||
+DEF_HELPER_1(rcsr_jrx, i32, env)
|
||||
|
||||
#include "def-helper.h"
|
||||
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
|
||||
index 51edc1a..7b91d8c 100644
|
||||
--- a/target-lm32/op_helper.c
|
||||
+++ b/target-lm32/op_helper.c
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "helper.h"
|
||||
#include "host-utils.h"
|
||||
|
||||
@@ -18,55 +17,55 @@
|
||||
#define SHIFT 3
|
||||
#include "softmmu_template.h"
|
||||
|
||||
-void helper_raise_exception(uint32_t index)
|
||||
+void helper_raise_exception(CPULM32State *env, uint32_t index)
|
||||
{
|
||||
env->exception_index = index;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void helper_hlt(void)
|
||||
+void helper_hlt(CPULM32State *env)
|
||||
{
|
||||
env->halted = 1;
|
||||
env->exception_index = EXCP_HLT;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void helper_wcsr_im(uint32_t im)
|
||||
+void helper_wcsr_im(CPULM32State *env, uint32_t im)
|
||||
{
|
||||
lm32_pic_set_im(env->pic_state, im);
|
||||
}
|
||||
|
||||
-void helper_wcsr_ip(uint32_t im)
|
||||
+void helper_wcsr_ip(CPULM32State *env, uint32_t im)
|
||||
{
|
||||
lm32_pic_set_ip(env->pic_state, im);
|
||||
}
|
||||
|
||||
-void helper_wcsr_jtx(uint32_t jtx)
|
||||
+void helper_wcsr_jtx(CPULM32State *env, uint32_t jtx)
|
||||
{
|
||||
lm32_juart_set_jtx(env->juart_state, jtx);
|
||||
}
|
||||
|
||||
-void helper_wcsr_jrx(uint32_t jrx)
|
||||
+void helper_wcsr_jrx(CPULM32State *env, uint32_t jrx)
|
||||
{
|
||||
lm32_juart_set_jrx(env->juart_state, jrx);
|
||||
}
|
||||
|
||||
-uint32_t helper_rcsr_im(void)
|
||||
+uint32_t helper_rcsr_im(CPULM32State *env)
|
||||
{
|
||||
return lm32_pic_get_im(env->pic_state);
|
||||
}
|
||||
|
||||
-uint32_t helper_rcsr_ip(void)
|
||||
+uint32_t helper_rcsr_ip(CPULM32State *env)
|
||||
{
|
||||
return lm32_pic_get_ip(env->pic_state);
|
||||
}
|
||||
|
||||
-uint32_t helper_rcsr_jtx(void)
|
||||
+uint32_t helper_rcsr_jtx(CPULM32State *env)
|
||||
{
|
||||
return lm32_juart_get_jtx(env->juart_state);
|
||||
}
|
||||
|
||||
-uint32_t helper_rcsr_jrx(void)
|
||||
+uint32_t helper_rcsr_jrx(CPULM32State *env)
|
||||
{
|
||||
return lm32_juart_get_jrx(env->juart_state);
|
||||
}
|
||||
@@ -74,17 +73,12 @@ uint32_t helper_rcsr_jrx(void)
|
||||
/* Try to fill the TLB and return an exception if error. If retaddr is
|
||||
NULL, it means that the function was called in C code (i.e. not
|
||||
from generated code or from helper.c) */
|
||||
-/* XXX: fix it to restore all registers */
|
||||
-void tlb_fill(CPULM32State *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
+void tlb_fill(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx,
|
||||
uintptr_t retaddr)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
- CPULM32State *saved_env;
|
||||
int ret;
|
||||
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
-
|
||||
ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx);
|
||||
if (unlikely(ret)) {
|
||||
if (retaddr) {
|
||||
@@ -98,7 +92,6 @@ void tlb_fill(CPULM32State *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
}
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
- env = saved_env;
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
|
||||
index 872a2ba..5f6dcba 100644
|
||||
--- a/target-lm32/translate.c
|
||||
+++ b/target-lm32/translate.c
|
||||
@@ -116,7 +116,7 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_const_i32(index);
|
||||
|
||||
- gen_helper_raise_exception(tmp);
|
||||
+ gen_helper_raise_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ static void dec_and(DisasContext *dc)
|
||||
} else {
|
||||
if (dc->r0 == 0 && dc->r1 == 0 && dc->r2 == 0) {
|
||||
tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
|
||||
- gen_helper_hlt();
|
||||
+ gen_helper_hlt(cpu_env);
|
||||
} else {
|
||||
tcg_gen_and_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
|
||||
}
|
||||
@@ -601,10 +601,10 @@ static void dec_rcsr(DisasContext *dc)
|
||||
tcg_gen_mov_tl(cpu_R[dc->r2], cpu_ie);
|
||||
break;
|
||||
case CSR_IM:
|
||||
- gen_helper_rcsr_im(cpu_R[dc->r2]);
|
||||
+ gen_helper_rcsr_im(cpu_R[dc->r2], cpu_env);
|
||||
break;
|
||||
case CSR_IP:
|
||||
- gen_helper_rcsr_ip(cpu_R[dc->r2]);
|
||||
+ gen_helper_rcsr_ip(cpu_R[dc->r2], cpu_env);
|
||||
break;
|
||||
case CSR_CC:
|
||||
tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cc);
|
||||
@@ -622,10 +622,10 @@ static void dec_rcsr(DisasContext *dc)
|
||||
tcg_gen_mov_tl(cpu_R[dc->r2], cpu_deba);
|
||||
break;
|
||||
case CSR_JTX:
|
||||
- gen_helper_rcsr_jtx(cpu_R[dc->r2]);
|
||||
+ gen_helper_rcsr_jtx(cpu_R[dc->r2], cpu_env);
|
||||
break;
|
||||
case CSR_JRX:
|
||||
- gen_helper_rcsr_jrx(cpu_R[dc->r2]);
|
||||
+ gen_helper_rcsr_jrx(cpu_R[dc->r2], cpu_env);
|
||||
break;
|
||||
case CSR_ICC:
|
||||
case CSR_DCC:
|
||||
@@ -812,7 +812,7 @@ static void dec_wcsr(DisasContext *dc)
|
||||
if (use_icount) {
|
||||
gen_io_start();
|
||||
}
|
||||
- gen_helper_wcsr_im(cpu_R[dc->r1]);
|
||||
+ gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);
|
||||
tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
|
||||
if (use_icount) {
|
||||
gen_io_end();
|
||||
@@ -824,7 +824,7 @@ static void dec_wcsr(DisasContext *dc)
|
||||
if (use_icount) {
|
||||
gen_io_start();
|
||||
}
|
||||
- gen_helper_wcsr_ip(cpu_R[dc->r1]);
|
||||
+ gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);
|
||||
tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
|
||||
if (use_icount) {
|
||||
gen_io_end();
|
||||
@@ -844,10 +844,10 @@ static void dec_wcsr(DisasContext *dc)
|
||||
tcg_gen_mov_tl(cpu_deba, cpu_R[dc->r1]);
|
||||
break;
|
||||
case CSR_JTX:
|
||||
- gen_helper_wcsr_jtx(cpu_R[dc->r1]);
|
||||
+ gen_helper_wcsr_jtx(cpu_env, cpu_R[dc->r1]);
|
||||
break;
|
||||
case CSR_JRX:
|
||||
- gen_helper_wcsr_jrx(cpu_R[dc->r1]);
|
||||
+ gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);
|
||||
break;
|
||||
case CSR_DC:
|
||||
tcg_gen_mov_tl(cpu_dc, cpu_R[dc->r1]);
|
||||
@@ -940,15 +940,13 @@ static const DecoderInfo decinfo[] = {
|
||||
dec_cmpne
|
||||
};
|
||||
|
||||
-static inline void decode(DisasContext *dc)
|
||||
+static inline void decode(DisasContext *dc, uint32_t ir)
|
||||
{
|
||||
- uint32_t ir;
|
||||
-
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
|
||||
tcg_gen_debug_insn_start(dc->pc);
|
||||
}
|
||||
|
||||
- dc->ir = ir = ldl_code(dc->pc);
|
||||
+ dc->ir = ir;
|
||||
LOG_DIS("%8.8x\t", dc->ir);
|
||||
|
||||
/* try guessing 'empty' instruction memory, although it may be a valid
|
||||
@@ -1068,7 +1066,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
|
||||
gen_io_start();
|
||||
}
|
||||
|
||||
- decode(dc);
|
||||
+ decode(dc, cpu_ldl_code(env, dc->pc));
|
||||
dc->pc += 4;
|
||||
num_insns++;
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
502
0028-target-m68k-switch-to-AREG0-free-mode.patch
Normal file
502
0028-target-m68k-switch-to-AREG0-free-mode.patch
Normal file
@ -0,0 +1,502 @@
|
||||
From 2ace9fd11db103aecebf451aff3bc23838248667 Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:27:38 +0000
|
||||
Subject: [PATCH] target-m68k: switch to AREG0 free mode
|
||||
|
||||
Add an explicit CPUState parameter instead of relying on AREG0
|
||||
and switch to AREG0 free mode.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 2 +-
|
||||
target-m68k/Makefile.objs | 2 --
|
||||
target-m68k/helpers.h | 2 +-
|
||||
target-m68k/op_helper.c | 68 +++++++++++++++++-------------------------
|
||||
target-m68k/translate.c | 76 ++++++++++++++++++++++++-----------------------
|
||||
5 files changed, 68 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 1e3ea7f..af03942 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
|
||||
|
||||
|
||||
case "$target_arch2" in
|
||||
- alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
||||
+ alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
||||
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
|
||||
;;
|
||||
esac
|
||||
diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs
|
||||
index cda6015..7eccfab 100644
|
||||
--- a/target-m68k/Makefile.objs
|
||||
+++ b/target-m68k/Makefile.objs
|
||||
@@ -1,5 +1,3 @@
|
||||
obj-y += m68k-semi.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
-
|
||||
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
|
||||
index cb8a0c7..8112b44 100644
|
||||
--- a/target-m68k/helpers.h
|
||||
+++ b/target-m68k/helpers.h
|
||||
@@ -49,6 +49,6 @@ DEF_HELPER_3(set_mac_exts, void, env, i32, i32)
|
||||
DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_2(flush_flags, void, env, i32)
|
||||
-DEF_HELPER_1(raise_exception, void, i32)
|
||||
+DEF_HELPER_2(raise_exception, void, env, i32)
|
||||
|
||||
#include "def-helper.h"
|
||||
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
|
||||
index 1971a57..3116287 100644
|
||||
--- a/target-m68k/op_helper.c
|
||||
+++ b/target-m68k/op_helper.c
|
||||
@@ -17,17 +17,16 @@
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
||||
-void do_interrupt(CPUM68KState *env1)
|
||||
+void do_interrupt(CPUM68KState *env)
|
||||
{
|
||||
- env1->exception_index = -1;
|
||||
+ env->exception_index = -1;
|
||||
}
|
||||
|
||||
-void do_interrupt_m68k_hardirq(CPUM68KState *env1)
|
||||
+void do_interrupt_m68k_hardirq(CPUM68KState *env)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -54,16 +53,12 @@ extern int semihosting_enabled;
|
||||
/* Try to fill the TLB and return an exception if error. If retaddr is
|
||||
NULL, it means that the function was called in C code (i.e. not
|
||||
from generated code or from helper.c) */
|
||||
-/* XXX: fix it to restore all registers */
|
||||
-void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
+void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx,
|
||||
uintptr_t retaddr)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
- CPUM68KState *saved_env;
|
||||
int ret;
|
||||
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
|
||||
if (unlikely(ret)) {
|
||||
if (retaddr) {
|
||||
@@ -77,24 +72,23 @@ void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
}
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
- env = saved_env;
|
||||
}
|
||||
|
||||
-static void do_rte(void)
|
||||
+static void do_rte(CPUM68KState *env)
|
||||
{
|
||||
uint32_t sp;
|
||||
uint32_t fmt;
|
||||
|
||||
sp = env->aregs[7];
|
||||
- fmt = ldl_kernel(sp);
|
||||
- env->pc = ldl_kernel(sp + 4);
|
||||
+ fmt = cpu_ldl_kernel(env, sp);
|
||||
+ env->pc = cpu_ldl_kernel(env, sp + 4);
|
||||
sp |= (fmt >> 28) & 3;
|
||||
env->sr = fmt & 0xffff;
|
||||
m68k_switch_sp(env);
|
||||
env->aregs[7] = sp + 8;
|
||||
}
|
||||
|
||||
-static void do_interrupt_all(int is_hw)
|
||||
+static void do_interrupt_all(CPUM68KState *env, int is_hw)
|
||||
{
|
||||
uint32_t sp;
|
||||
uint32_t fmt;
|
||||
@@ -108,14 +102,14 @@ static void do_interrupt_all(int is_hw)
|
||||
switch (env->exception_index) {
|
||||
case EXCP_RTE:
|
||||
/* Return from an exception. */
|
||||
- do_rte();
|
||||
+ do_rte(env);
|
||||
return;
|
||||
case EXCP_HALT_INSN:
|
||||
if (semihosting_enabled
|
||||
&& (env->sr & SR_S) != 0
|
||||
&& (env->pc & 3) == 0
|
||||
- && lduw_code(env->pc - 4) == 0x4e71
|
||||
- && ldl_code(env->pc) == 0x4e7bf000) {
|
||||
+ && cpu_lduw_code(env, env->pc - 4) == 0x4e71
|
||||
+ && cpu_ldl_code(env, env->pc) == 0x4e7bf000) {
|
||||
env->pc += 4;
|
||||
do_m68k_semihosting(env, env->dregs[0]);
|
||||
return;
|
||||
@@ -151,44 +145,34 @@ static void do_interrupt_all(int is_hw)
|
||||
/* ??? This could cause MMU faults. */
|
||||
sp &= ~3;
|
||||
sp -= 4;
|
||||
- stl_kernel(sp, retaddr);
|
||||
+ cpu_stl_kernel(env, sp, retaddr);
|
||||
sp -= 4;
|
||||
- stl_kernel(sp, fmt);
|
||||
+ cpu_stl_kernel(env, sp, fmt);
|
||||
env->aregs[7] = sp;
|
||||
/* Jump to vector. */
|
||||
- env->pc = ldl_kernel(env->vbr + vector);
|
||||
+ env->pc = cpu_ldl_kernel(env, env->vbr + vector);
|
||||
}
|
||||
|
||||
-void do_interrupt(CPUM68KState *env1)
|
||||
+void do_interrupt(CPUM68KState *env)
|
||||
{
|
||||
- CPUM68KState *saved_env;
|
||||
-
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
- do_interrupt_all(0);
|
||||
- env = saved_env;
|
||||
+ do_interrupt_all(env, 0);
|
||||
}
|
||||
|
||||
-void do_interrupt_m68k_hardirq(CPUM68KState *env1)
|
||||
+void do_interrupt_m68k_hardirq(CPUM68KState *env)
|
||||
{
|
||||
- CPUM68KState *saved_env;
|
||||
-
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
- do_interrupt_all(1);
|
||||
- env = saved_env;
|
||||
+ do_interrupt_all(env, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
-static void raise_exception(int tt)
|
||||
+static void raise_exception(CPUM68KState *env, int tt)
|
||||
{
|
||||
env->exception_index = tt;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void HELPER(raise_exception)(uint32_t tt)
|
||||
+void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt)
|
||||
{
|
||||
- raise_exception(tt);
|
||||
+ raise_exception(env, tt);
|
||||
}
|
||||
|
||||
void HELPER(divu)(CPUM68KState *env, uint32_t word)
|
||||
@@ -202,8 +186,9 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
|
||||
num = env->div1;
|
||||
den = env->div2;
|
||||
/* ??? This needs to make sure the throwing location is accurate. */
|
||||
- if (den == 0)
|
||||
- raise_exception(EXCP_DIV0);
|
||||
+ if (den == 0) {
|
||||
+ raise_exception(env, EXCP_DIV0);
|
||||
+ }
|
||||
quot = num / den;
|
||||
rem = num % den;
|
||||
flags = 0;
|
||||
@@ -231,8 +216,9 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word)
|
||||
|
||||
num = env->div1;
|
||||
den = env->div2;
|
||||
- if (den == 0)
|
||||
- raise_exception(EXCP_DIV0);
|
||||
+ if (den == 0) {
|
||||
+ raise_exception(env, EXCP_DIV0);
|
||||
+ }
|
||||
quot = num / den;
|
||||
rem = num % den;
|
||||
flags = 0;
|
||||
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
|
||||
index 9fc1e31..10bb303 100644
|
||||
--- a/target-m68k/translate.c
|
||||
+++ b/target-m68k/translate.c
|
||||
@@ -260,9 +260,9 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
|
||||
static inline uint32_t read_im32(DisasContext *s)
|
||||
{
|
||||
uint32_t im;
|
||||
- im = ((uint32_t)lduw_code(s->pc)) << 16;
|
||||
+ im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
|
||||
s->pc += 2;
|
||||
- im |= lduw_code(s->pc);
|
||||
+ im |= cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
return im;
|
||||
}
|
||||
@@ -297,7 +297,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
uint32_t bd, od;
|
||||
|
||||
offset = s->pc;
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
|
||||
@@ -311,7 +311,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
if ((ext & 0x30) > 0x10) {
|
||||
/* base displacement */
|
||||
if ((ext & 0x30) == 0x20) {
|
||||
- bd = (int16_t)lduw_code(s->pc);
|
||||
+ bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
} else {
|
||||
bd = read_im32(s);
|
||||
@@ -360,7 +360,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
if ((ext & 3) > 1) {
|
||||
/* outer displacement */
|
||||
if ((ext & 3) == 2) {
|
||||
- od = (int16_t)lduw_code(s->pc);
|
||||
+ od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
} else {
|
||||
od = read_im32(s);
|
||||
@@ -514,7 +514,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
||||
case 5: /* Indirect displacement. */
|
||||
reg = AREG(insn, 0);
|
||||
tmp = tcg_temp_new();
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
|
||||
return tmp;
|
||||
@@ -524,7 +524,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
||||
case 7: /* Other */
|
||||
switch (insn & 7) {
|
||||
case 0: /* Absolute short. */
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
return tcg_const_i32(offset);
|
||||
case 1: /* Absolute long. */
|
||||
@@ -532,7 +532,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
||||
return tcg_const_i32(offset);
|
||||
case 2: /* pc displacement */
|
||||
offset = s->pc;
|
||||
- offset += ldsw_code(s->pc);
|
||||
+ offset += cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
return tcg_const_i32(offset);
|
||||
case 3: /* pc index+displacement. */
|
||||
@@ -638,17 +638,19 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
|
||||
/* Sign extend values for consistency. */
|
||||
switch (opsize) {
|
||||
case OS_BYTE:
|
||||
- if (what == EA_LOADS)
|
||||
- offset = ldsb_code(s->pc + 1);
|
||||
- else
|
||||
- offset = ldub_code(s->pc + 1);
|
||||
+ if (what == EA_LOADS) {
|
||||
+ offset = cpu_ldsb_code(cpu_single_env, s->pc + 1);
|
||||
+ } else {
|
||||
+ offset = cpu_ldub_code(cpu_single_env, s->pc + 1);
|
||||
+ }
|
||||
s->pc += 2;
|
||||
break;
|
||||
case OS_WORD:
|
||||
- if (what == EA_LOADS)
|
||||
- offset = ldsw_code(s->pc);
|
||||
- else
|
||||
- offset = lduw_code(s->pc);
|
||||
+ if (what == EA_LOADS) {
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ } else {
|
||||
+ offset = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ }
|
||||
s->pc += 2;
|
||||
break;
|
||||
case OS_LONG:
|
||||
@@ -815,7 +817,7 @@ static void gen_exception(DisasContext *s, uint32_t where, int nr)
|
||||
{
|
||||
gen_flush_cc_op(s);
|
||||
gen_jmp_im(s, where);
|
||||
- gen_helper_raise_exception(tcg_const_i32(nr));
|
||||
+ gen_helper_raise_exception(cpu_env, tcg_const_i32(nr));
|
||||
}
|
||||
|
||||
static inline void gen_addr_fault(DisasContext *s)
|
||||
@@ -934,7 +936,7 @@ DISAS_INSN(divl)
|
||||
TCGv reg;
|
||||
uint16_t ext;
|
||||
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
if (ext & 0x87f8) {
|
||||
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
||||
@@ -1086,7 +1088,7 @@ DISAS_INSN(movem)
|
||||
TCGv tmp;
|
||||
int is_load;
|
||||
|
||||
- mask = lduw_code(s->pc);
|
||||
+ mask = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
tmp = gen_lea(s, insn, OS_LONG);
|
||||
if (IS_NULL_QREG(tmp)) {
|
||||
@@ -1130,7 +1132,7 @@ DISAS_INSN(bitop_im)
|
||||
opsize = OS_LONG;
|
||||
op = (insn >> 6) & 3;
|
||||
|
||||
- bitnum = lduw_code(s->pc);
|
||||
+ bitnum = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
if (bitnum & 0xff00) {
|
||||
disas_undef(s, insn);
|
||||
@@ -1383,7 +1385,7 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
|
||||
else if ((insn & 0x3f) == 0x3c)
|
||||
{
|
||||
uint16_t val;
|
||||
- val = lduw_code(s->pc);
|
||||
+ val = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
gen_set_sr_im(s, val, ccr_only);
|
||||
}
|
||||
@@ -1507,7 +1509,7 @@ DISAS_INSN(mull)
|
||||
|
||||
/* The upper 32 bits of the product are discarded, so
|
||||
muls.l and mulu.l are functionally equivalent. */
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
if (ext & 0x87ff) {
|
||||
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
||||
@@ -1528,7 +1530,7 @@ DISAS_INSN(link)
|
||||
TCGv reg;
|
||||
TCGv tmp;
|
||||
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
reg = AREG(insn, 0);
|
||||
tmp = tcg_temp_new();
|
||||
@@ -1649,7 +1651,7 @@ DISAS_INSN(branch)
|
||||
op = (insn >> 8) & 0xf;
|
||||
offset = (int8_t)insn;
|
||||
if (offset == 0) {
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
} else if (offset == -1) {
|
||||
offset = read_im32(s);
|
||||
@@ -1934,13 +1936,13 @@ DISAS_INSN(strldsr)
|
||||
uint32_t addr;
|
||||
|
||||
addr = s->pc - 2;
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
if (ext != 0x46FC) {
|
||||
gen_exception(s, addr, EXCP_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
if (IS_USER(s) || (ext & SR_S) == 0) {
|
||||
gen_exception(s, addr, EXCP_PRIVILEGE);
|
||||
@@ -2008,7 +2010,7 @@ DISAS_INSN(stop)
|
||||
return;
|
||||
}
|
||||
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
gen_set_sr_im(s, ext, 0);
|
||||
@@ -2035,7 +2037,7 @@ DISAS_INSN(movec)
|
||||
return;
|
||||
}
|
||||
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
if (ext & 0x8000) {
|
||||
@@ -2100,7 +2102,7 @@ DISAS_INSN(fpu)
|
||||
int set_dest;
|
||||
int opsize;
|
||||
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
opmode = ext & 0x7f;
|
||||
switch ((ext >> 13) & 7) {
|
||||
@@ -2136,7 +2138,7 @@ DISAS_INSN(fpu)
|
||||
tcg_gen_addi_i32(tmp32, tmp32, -8);
|
||||
break;
|
||||
case 5:
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
||||
break;
|
||||
@@ -2250,12 +2252,12 @@ DISAS_INSN(fpu)
|
||||
tcg_gen_addi_i32(tmp32, tmp32, -8);
|
||||
break;
|
||||
case 5:
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
||||
break;
|
||||
case 7:
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
offset += s->pc - 2;
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
||||
@@ -2381,10 +2383,10 @@ DISAS_INSN(fbcc)
|
||||
int l1;
|
||||
|
||||
addr = s->pc;
|
||||
- offset = ldsw_code(s->pc);
|
||||
+ offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
if (insn & (1 << 6)) {
|
||||
- offset = (offset << 16) | lduw_code(s->pc);
|
||||
+ offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
}
|
||||
|
||||
@@ -2506,7 +2508,7 @@ DISAS_INSN(mac)
|
||||
s->done_mac = 1;
|
||||
}
|
||||
|
||||
- ext = lduw_code(s->pc);
|
||||
+ ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
|
||||
@@ -2941,7 +2943,7 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
|
||||
{
|
||||
uint16_t insn;
|
||||
|
||||
- insn = lduw_code(s->pc);
|
||||
+ insn = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
opcode_table[insn](s, insn);
|
||||
@@ -3028,7 +3030,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
|
||||
gen_flush_cc_op(dc);
|
||||
tcg_gen_movi_i32(QREG_PC, dc->pc);
|
||||
}
|
||||
- gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG));
|
||||
+ gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
|
||||
} else {
|
||||
switch(dc->is_jmp) {
|
||||
case DISAS_NEXT:
|
||||
--
|
||||
1.7.12.1
|
||||
|
901
0029-target-m68k-avoid-using-cpu_single_env.patch
Normal file
901
0029-target-m68k-avoid-using-cpu_single_env.patch
Normal file
@ -0,0 +1,901 @@
|
||||
From 5560cd783146734a60c446f43227044cbb580edd Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sat, 8 Sep 2012 10:48:20 +0000
|
||||
Subject: [PATCH] target-m68k: avoid using cpu_single_env
|
||||
|
||||
Pass around CPUState instead of using global cpu_single_env.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-m68k/translate.c | 270 +++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 140 insertions(+), 130 deletions(-)
|
||||
|
||||
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
|
||||
index 10bb303..fb707f2 100644
|
||||
--- a/target-m68k/translate.c
|
||||
+++ b/target-m68k/translate.c
|
||||
@@ -150,18 +150,24 @@ static void *gen_throws_exception;
|
||||
#define OS_SINGLE 4
|
||||
#define OS_DOUBLE 5
|
||||
|
||||
-typedef void (*disas_proc)(DisasContext *, uint16_t);
|
||||
+typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn);
|
||||
|
||||
#ifdef DEBUG_DISPATCH
|
||||
-#define DISAS_INSN(name) \
|
||||
- static void real_disas_##name (DisasContext *s, uint16_t insn); \
|
||||
- static void disas_##name (DisasContext *s, uint16_t insn) { \
|
||||
- qemu_log("Dispatch " #name "\n"); \
|
||||
- real_disas_##name(s, insn); } \
|
||||
- static void real_disas_##name (DisasContext *s, uint16_t insn)
|
||||
+#define DISAS_INSN(name) \
|
||||
+ static void real_disas_##name(CPUM68KState *env, DisasContext *s, \
|
||||
+ uint16_t insn); \
|
||||
+ static void disas_##name(CPUM68KState *env, DisasContext *s, \
|
||||
+ uint16_t insn) \
|
||||
+ { \
|
||||
+ qemu_log("Dispatch " #name "\n"); \
|
||||
+ real_disas_##name(s, env, insn); \
|
||||
+ } \
|
||||
+ static void real_disas_##name(CPUM68KState *env, DisasContext *s, \
|
||||
+ uint16_t insn)
|
||||
#else
|
||||
-#define DISAS_INSN(name) \
|
||||
- static void disas_##name (DisasContext *s, uint16_t insn)
|
||||
+#define DISAS_INSN(name) \
|
||||
+ static void disas_##name(CPUM68KState *env, DisasContext *s, \
|
||||
+ uint16_t insn)
|
||||
#endif
|
||||
|
||||
/* Generate a load from the specified address. Narrow values are
|
||||
@@ -257,12 +263,12 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
|
||||
}
|
||||
|
||||
/* Read a 32-bit immediate constant. */
|
||||
-static inline uint32_t read_im32(DisasContext *s)
|
||||
+static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s)
|
||||
{
|
||||
uint32_t im;
|
||||
- im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
|
||||
+ im = ((uint32_t)cpu_lduw_code(env, s->pc)) << 16;
|
||||
s->pc += 2;
|
||||
- im |= cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ im |= cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
return im;
|
||||
}
|
||||
@@ -288,7 +294,8 @@ static TCGv gen_addr_index(uint16_t ext, TCGv tmp)
|
||||
|
||||
/* Handle a base + index + displacement effective addresss.
|
||||
A NULL_QREG base means pc-relative. */
|
||||
-static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
+static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, int opsize,
|
||||
+ TCGv base)
|
||||
{
|
||||
uint32_t offset;
|
||||
uint16_t ext;
|
||||
@@ -297,7 +304,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
uint32_t bd, od;
|
||||
|
||||
offset = s->pc;
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
|
||||
@@ -311,10 +318,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
if ((ext & 0x30) > 0x10) {
|
||||
/* base displacement */
|
||||
if ((ext & 0x30) == 0x20) {
|
||||
- bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ bd = (int16_t)cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
} else {
|
||||
- bd = read_im32(s);
|
||||
+ bd = read_im32(env, s);
|
||||
}
|
||||
} else {
|
||||
bd = 0;
|
||||
@@ -360,10 +367,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
|
||||
if ((ext & 3) > 1) {
|
||||
/* outer displacement */
|
||||
if ((ext & 3) == 2) {
|
||||
- od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ od = (int16_t)cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
} else {
|
||||
- od = read_im32(s);
|
||||
+ od = read_im32(env, s);
|
||||
}
|
||||
} else {
|
||||
od = 0;
|
||||
@@ -492,7 +499,8 @@ static inline TCGv gen_extend(TCGv val, int opsize, int sign)
|
||||
|
||||
/* Generate code for an "effective address". Does not adjust the base
|
||||
register for autoincrement addressing modes. */
|
||||
-static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
||||
+static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn,
|
||||
+ int opsize)
|
||||
{
|
||||
TCGv reg;
|
||||
TCGv tmp;
|
||||
@@ -514,29 +522,29 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
||||
case 5: /* Indirect displacement. */
|
||||
reg = AREG(insn, 0);
|
||||
tmp = tcg_temp_new();
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
|
||||
return tmp;
|
||||
case 6: /* Indirect index + displacement. */
|
||||
reg = AREG(insn, 0);
|
||||
- return gen_lea_indexed(s, opsize, reg);
|
||||
+ return gen_lea_indexed(env, s, opsize, reg);
|
||||
case 7: /* Other */
|
||||
switch (insn & 7) {
|
||||
case 0: /* Absolute short. */
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
return tcg_const_i32(offset);
|
||||
case 1: /* Absolute long. */
|
||||
- offset = read_im32(s);
|
||||
+ offset = read_im32(env, s);
|
||||
return tcg_const_i32(offset);
|
||||
case 2: /* pc displacement */
|
||||
offset = s->pc;
|
||||
- offset += cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset += cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
return tcg_const_i32(offset);
|
||||
case 3: /* pc index+displacement. */
|
||||
- return gen_lea_indexed(s, opsize, NULL_QREG);
|
||||
+ return gen_lea_indexed(env, s, opsize, NULL_QREG);
|
||||
case 4: /* Immediate. */
|
||||
default:
|
||||
return NULL_QREG;
|
||||
@@ -548,15 +556,16 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
|
||||
|
||||
/* Helper function for gen_ea. Reuse the computed address between the
|
||||
for read/write operands. */
|
||||
-static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
|
||||
- TCGv val, TCGv *addrp, ea_what what)
|
||||
+static inline TCGv gen_ea_once(CPUM68KState *env, DisasContext *s,
|
||||
+ uint16_t insn, int opsize, TCGv val,
|
||||
+ TCGv *addrp, ea_what what)
|
||||
{
|
||||
TCGv tmp;
|
||||
|
||||
if (addrp && what == EA_STORE) {
|
||||
tmp = *addrp;
|
||||
} else {
|
||||
- tmp = gen_lea(s, insn, opsize);
|
||||
+ tmp = gen_lea(env, s, insn, opsize);
|
||||
if (IS_NULL_QREG(tmp))
|
||||
return tmp;
|
||||
if (addrp)
|
||||
@@ -568,8 +577,8 @@ static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
|
||||
/* Generate code to load/store a value ito/from an EA. If VAL > 0 this is
|
||||
a write otherwise it is a read (0 == sign extend, -1 == zero extend).
|
||||
ADDRP is non-null for readwrite operands. */
|
||||
-static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
|
||||
- TCGv *addrp, ea_what what)
|
||||
+static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn,
|
||||
+ int opsize, TCGv val, TCGv *addrp, ea_what what)
|
||||
{
|
||||
TCGv reg;
|
||||
TCGv result;
|
||||
@@ -609,7 +618,7 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
|
||||
if (addrp && what == EA_STORE) {
|
||||
tmp = *addrp;
|
||||
} else {
|
||||
- tmp = gen_lea(s, insn, opsize);
|
||||
+ tmp = gen_lea(env, s, insn, opsize);
|
||||
if (IS_NULL_QREG(tmp))
|
||||
return tmp;
|
||||
if (addrp)
|
||||
@@ -626,35 +635,35 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
|
||||
return result;
|
||||
case 5: /* Indirect displacement. */
|
||||
case 6: /* Indirect index + displacement. */
|
||||
- return gen_ea_once(s, insn, opsize, val, addrp, what);
|
||||
+ return gen_ea_once(env, s, insn, opsize, val, addrp, what);
|
||||
case 7: /* Other */
|
||||
switch (insn & 7) {
|
||||
case 0: /* Absolute short. */
|
||||
case 1: /* Absolute long. */
|
||||
case 2: /* pc displacement */
|
||||
case 3: /* pc index+displacement. */
|
||||
- return gen_ea_once(s, insn, opsize, val, addrp, what);
|
||||
+ return gen_ea_once(env, s, insn, opsize, val, addrp, what);
|
||||
case 4: /* Immediate. */
|
||||
/* Sign extend values for consistency. */
|
||||
switch (opsize) {
|
||||
case OS_BYTE:
|
||||
if (what == EA_LOADS) {
|
||||
- offset = cpu_ldsb_code(cpu_single_env, s->pc + 1);
|
||||
+ offset = cpu_ldsb_code(env, s->pc + 1);
|
||||
} else {
|
||||
- offset = cpu_ldub_code(cpu_single_env, s->pc + 1);
|
||||
+ offset = cpu_ldub_code(env, s->pc + 1);
|
||||
}
|
||||
s->pc += 2;
|
||||
break;
|
||||
case OS_WORD:
|
||||
if (what == EA_LOADS) {
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
} else {
|
||||
- offset = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_lduw_code(env, s->pc);
|
||||
}
|
||||
s->pc += 2;
|
||||
break;
|
||||
case OS_LONG:
|
||||
- offset = read_im32(s);
|
||||
+ offset = read_im32(env, s);
|
||||
break;
|
||||
default:
|
||||
qemu_assert(0, "Bad immediate operand");
|
||||
@@ -825,20 +834,21 @@ static inline void gen_addr_fault(DisasContext *s)
|
||||
gen_exception(s, s->insn_pc, EXCP_ADDRESS);
|
||||
}
|
||||
|
||||
-#define SRC_EA(result, opsize, op_sign, addrp) do { \
|
||||
- result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \
|
||||
- if (IS_NULL_QREG(result)) { \
|
||||
- gen_addr_fault(s); \
|
||||
- return; \
|
||||
- } \
|
||||
+#define SRC_EA(env, result, opsize, op_sign, addrp) do { \
|
||||
+ result = gen_ea(env, s, insn, opsize, NULL_QREG, addrp, \
|
||||
+ op_sign ? EA_LOADS : EA_LOADU); \
|
||||
+ if (IS_NULL_QREG(result)) { \
|
||||
+ gen_addr_fault(s); \
|
||||
+ return; \
|
||||
+ } \
|
||||
} while (0)
|
||||
|
||||
-#define DEST_EA(insn, opsize, val, addrp) do { \
|
||||
- TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \
|
||||
- if (IS_NULL_QREG(ea_result)) { \
|
||||
- gen_addr_fault(s); \
|
||||
- return; \
|
||||
- } \
|
||||
+#define DEST_EA(env, insn, opsize, val, addrp) do { \
|
||||
+ TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, EA_STORE); \
|
||||
+ if (IS_NULL_QREG(ea_result)) { \
|
||||
+ gen_addr_fault(s); \
|
||||
+ return; \
|
||||
+ } \
|
||||
} while (0)
|
||||
|
||||
/* Generate a jump to an immediate address. */
|
||||
@@ -874,8 +884,7 @@ DISAS_INSN(undef_fpu)
|
||||
DISAS_INSN(undef)
|
||||
{
|
||||
gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
|
||||
- cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
|
||||
- insn, s->pc - 2);
|
||||
+ cpu_abort(env, "Illegal instruction: %04x @ %08x", insn, s->pc - 2);
|
||||
}
|
||||
|
||||
DISAS_INSN(mulw)
|
||||
@@ -892,7 +901,7 @@ DISAS_INSN(mulw)
|
||||
tcg_gen_ext16s_i32(tmp, reg);
|
||||
else
|
||||
tcg_gen_ext16u_i32(tmp, reg);
|
||||
- SRC_EA(src, OS_WORD, sign, NULL);
|
||||
+ SRC_EA(env, src, OS_WORD, sign, NULL);
|
||||
tcg_gen_mul_i32(tmp, tmp, src);
|
||||
tcg_gen_mov_i32(reg, tmp);
|
||||
/* Unlike m68k, coldfire always clears the overflow bit. */
|
||||
@@ -913,7 +922,7 @@ DISAS_INSN(divw)
|
||||
} else {
|
||||
tcg_gen_ext16u_i32(QREG_DIV1, reg);
|
||||
}
|
||||
- SRC_EA(src, OS_WORD, sign, NULL);
|
||||
+ SRC_EA(env, src, OS_WORD, sign, NULL);
|
||||
tcg_gen_mov_i32(QREG_DIV2, src);
|
||||
if (sign) {
|
||||
gen_helper_divs(cpu_env, tcg_const_i32(1));
|
||||
@@ -936,7 +945,7 @@ DISAS_INSN(divl)
|
||||
TCGv reg;
|
||||
uint16_t ext;
|
||||
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
if (ext & 0x87f8) {
|
||||
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
||||
@@ -945,7 +954,7 @@ DISAS_INSN(divl)
|
||||
num = DREG(ext, 12);
|
||||
reg = DREG(ext, 0);
|
||||
tcg_gen_mov_i32(QREG_DIV1, num);
|
||||
- SRC_EA(den, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, den, OS_LONG, 0, NULL);
|
||||
tcg_gen_mov_i32(QREG_DIV2, den);
|
||||
if (ext & 0x0800) {
|
||||
gen_helper_divs(cpu_env, tcg_const_i32(0));
|
||||
@@ -975,11 +984,11 @@ DISAS_INSN(addsub)
|
||||
reg = DREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
if (insn & 0x100) {
|
||||
- SRC_EA(tmp, OS_LONG, 0, &addr);
|
||||
+ SRC_EA(env, tmp, OS_LONG, 0, &addr);
|
||||
src = reg;
|
||||
} else {
|
||||
tmp = reg;
|
||||
- SRC_EA(src, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, NULL);
|
||||
}
|
||||
if (add) {
|
||||
tcg_gen_add_i32(dest, tmp, src);
|
||||
@@ -992,7 +1001,7 @@ DISAS_INSN(addsub)
|
||||
}
|
||||
gen_update_cc_add(dest, src);
|
||||
if (insn & 0x100) {
|
||||
- DEST_EA(insn, OS_LONG, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
|
||||
} else {
|
||||
tcg_gen_mov_i32(reg, dest);
|
||||
}
|
||||
@@ -1022,7 +1031,7 @@ DISAS_INSN(bitop_reg)
|
||||
else
|
||||
opsize = OS_LONG;
|
||||
op = (insn >> 6) & 3;
|
||||
- SRC_EA(src1, opsize, 0, op ? &addr: NULL);
|
||||
+ SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
|
||||
src2 = DREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
|
||||
@@ -1057,7 +1066,7 @@ DISAS_INSN(bitop_reg)
|
||||
break;
|
||||
}
|
||||
if (op)
|
||||
- DEST_EA(insn, opsize, dest, &addr);
|
||||
+ DEST_EA(env, insn, opsize, dest, &addr);
|
||||
}
|
||||
|
||||
DISAS_INSN(sats)
|
||||
@@ -1088,9 +1097,9 @@ DISAS_INSN(movem)
|
||||
TCGv tmp;
|
||||
int is_load;
|
||||
|
||||
- mask = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ mask = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
- tmp = gen_lea(s, insn, OS_LONG);
|
||||
+ tmp = gen_lea(env, s, insn, OS_LONG);
|
||||
if (IS_NULL_QREG(tmp)) {
|
||||
gen_addr_fault(s);
|
||||
return;
|
||||
@@ -1132,14 +1141,14 @@ DISAS_INSN(bitop_im)
|
||||
opsize = OS_LONG;
|
||||
op = (insn >> 6) & 3;
|
||||
|
||||
- bitnum = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ bitnum = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
if (bitnum & 0xff00) {
|
||||
- disas_undef(s, insn);
|
||||
+ disas_undef(env, s, insn);
|
||||
return;
|
||||
}
|
||||
|
||||
- SRC_EA(src1, opsize, 0, op ? &addr: NULL);
|
||||
+ SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
|
||||
|
||||
gen_flush_flags(s);
|
||||
if (opsize == OS_BYTE)
|
||||
@@ -1174,7 +1183,7 @@ DISAS_INSN(bitop_im)
|
||||
default: /* btst */
|
||||
break;
|
||||
}
|
||||
- DEST_EA(insn, opsize, tmp, &addr);
|
||||
+ DEST_EA(env, insn, opsize, tmp, &addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1187,8 +1196,8 @@ DISAS_INSN(arith_im)
|
||||
TCGv addr;
|
||||
|
||||
op = (insn >> 9) & 7;
|
||||
- SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
|
||||
- im = read_im32(s);
|
||||
+ SRC_EA(env, src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
|
||||
+ im = read_im32(env, s);
|
||||
dest = tcg_temp_new();
|
||||
switch (op) {
|
||||
case 0: /* ori */
|
||||
@@ -1227,7 +1236,7 @@ DISAS_INSN(arith_im)
|
||||
abort();
|
||||
}
|
||||
if (op != 6) {
|
||||
- DEST_EA(insn, OS_LONG, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,7 +1268,7 @@ DISAS_INSN(move)
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
- SRC_EA(src, opsize, 1, NULL);
|
||||
+ SRC_EA(env, src, opsize, 1, NULL);
|
||||
op = (insn >> 6) & 7;
|
||||
if (op == 1) {
|
||||
/* movea */
|
||||
@@ -1270,7 +1279,7 @@ DISAS_INSN(move)
|
||||
/* normal move */
|
||||
uint16_t dest_ea;
|
||||
dest_ea = ((insn >> 9) & 7) | (op << 3);
|
||||
- DEST_EA(dest_ea, opsize, src, NULL);
|
||||
+ DEST_EA(env, dest_ea, opsize, src, NULL);
|
||||
/* This will be correct because loads sign extend. */
|
||||
gen_logic_cc(s, src);
|
||||
}
|
||||
@@ -1291,7 +1300,7 @@ DISAS_INSN(lea)
|
||||
TCGv tmp;
|
||||
|
||||
reg = AREG(insn, 9);
|
||||
- tmp = gen_lea(s, insn, OS_LONG);
|
||||
+ tmp = gen_lea(env, s, insn, OS_LONG);
|
||||
if (IS_NULL_QREG(tmp)) {
|
||||
gen_addr_fault(s);
|
||||
return;
|
||||
@@ -1316,7 +1325,7 @@ DISAS_INSN(clr)
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
- DEST_EA(insn, opsize, tcg_const_i32(0), NULL);
|
||||
+ DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL);
|
||||
gen_logic_cc(s, tcg_const_i32(0));
|
||||
}
|
||||
|
||||
@@ -1365,7 +1374,8 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
|
||||
}
|
||||
}
|
||||
|
||||
-static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
|
||||
+static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
|
||||
+ int ccr_only)
|
||||
{
|
||||
TCGv tmp;
|
||||
TCGv reg;
|
||||
@@ -1385,17 +1395,17 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
|
||||
else if ((insn & 0x3f) == 0x3c)
|
||||
{
|
||||
uint16_t val;
|
||||
- val = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ val = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
gen_set_sr_im(s, val, ccr_only);
|
||||
}
|
||||
else
|
||||
- disas_undef(s, insn);
|
||||
+ disas_undef(env, s, insn);
|
||||
}
|
||||
|
||||
DISAS_INSN(move_to_ccr)
|
||||
{
|
||||
- gen_set_sr(s, insn, 1);
|
||||
+ gen_set_sr(env, s, insn, 1);
|
||||
}
|
||||
|
||||
DISAS_INSN(not)
|
||||
@@ -1426,7 +1436,7 @@ DISAS_INSN(pea)
|
||||
{
|
||||
TCGv tmp;
|
||||
|
||||
- tmp = gen_lea(s, insn, OS_LONG);
|
||||
+ tmp = gen_lea(env, s, insn, OS_LONG);
|
||||
if (IS_NULL_QREG(tmp)) {
|
||||
gen_addr_fault(s);
|
||||
return;
|
||||
@@ -1472,7 +1482,7 @@ DISAS_INSN(tst)
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
- SRC_EA(tmp, opsize, 1, NULL);
|
||||
+ SRC_EA(env, tmp, opsize, 1, NULL);
|
||||
gen_logic_cc(s, tmp);
|
||||
}
|
||||
|
||||
@@ -1494,10 +1504,10 @@ DISAS_INSN(tas)
|
||||
TCGv addr;
|
||||
|
||||
dest = tcg_temp_new();
|
||||
- SRC_EA(src1, OS_BYTE, 1, &addr);
|
||||
+ SRC_EA(env, src1, OS_BYTE, 1, &addr);
|
||||
gen_logic_cc(s, src1);
|
||||
tcg_gen_ori_i32(dest, src1, 0x80);
|
||||
- DEST_EA(insn, OS_BYTE, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_BYTE, dest, &addr);
|
||||
}
|
||||
|
||||
DISAS_INSN(mull)
|
||||
@@ -1509,14 +1519,14 @@ DISAS_INSN(mull)
|
||||
|
||||
/* The upper 32 bits of the product are discarded, so
|
||||
muls.l and mulu.l are functionally equivalent. */
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
if (ext & 0x87ff) {
|
||||
gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
reg = DREG(ext, 12);
|
||||
- SRC_EA(src1, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, src1, OS_LONG, 0, NULL);
|
||||
dest = tcg_temp_new();
|
||||
tcg_gen_mul_i32(dest, src1, reg);
|
||||
tcg_gen_mov_i32(reg, dest);
|
||||
@@ -1530,7 +1540,7 @@ DISAS_INSN(link)
|
||||
TCGv reg;
|
||||
TCGv tmp;
|
||||
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
reg = AREG(insn, 0);
|
||||
tmp = tcg_temp_new();
|
||||
@@ -1574,7 +1584,7 @@ DISAS_INSN(jump)
|
||||
|
||||
/* Load the target address first to ensure correct exception
|
||||
behavior. */
|
||||
- tmp = gen_lea(s, insn, OS_LONG);
|
||||
+ tmp = gen_lea(env, s, insn, OS_LONG);
|
||||
if (IS_NULL_QREG(tmp)) {
|
||||
gen_addr_fault(s);
|
||||
return;
|
||||
@@ -1594,7 +1604,7 @@ DISAS_INSN(addsubq)
|
||||
int val;
|
||||
TCGv addr;
|
||||
|
||||
- SRC_EA(src1, OS_LONG, 0, &addr);
|
||||
+ SRC_EA(env, src1, OS_LONG, 0, &addr);
|
||||
val = (insn >> 9) & 7;
|
||||
if (val == 0)
|
||||
val = 8;
|
||||
@@ -1621,7 +1631,7 @@ DISAS_INSN(addsubq)
|
||||
}
|
||||
gen_update_cc_add(dest, src2);
|
||||
}
|
||||
- DEST_EA(insn, OS_LONG, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
|
||||
}
|
||||
|
||||
DISAS_INSN(tpf)
|
||||
@@ -1636,7 +1646,7 @@ DISAS_INSN(tpf)
|
||||
case 4: /* No extension words. */
|
||||
break;
|
||||
default:
|
||||
- disas_undef(s, insn);
|
||||
+ disas_undef(env, s, insn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1651,10 +1661,10 @@ DISAS_INSN(branch)
|
||||
op = (insn >> 8) & 0xf;
|
||||
offset = (int8_t)insn;
|
||||
if (offset == 0) {
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
} else if (offset == -1) {
|
||||
- offset = read_im32(s);
|
||||
+ offset = read_im32(env, s);
|
||||
}
|
||||
if (op == 1) {
|
||||
/* bsr */
|
||||
@@ -1693,7 +1703,7 @@ DISAS_INSN(mvzs)
|
||||
opsize = OS_WORD;
|
||||
else
|
||||
opsize = OS_BYTE;
|
||||
- SRC_EA(src, opsize, (insn & 0x80) == 0, NULL);
|
||||
+ SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL);
|
||||
reg = DREG(insn, 9);
|
||||
tcg_gen_mov_i32(reg, src);
|
||||
gen_logic_cc(s, src);
|
||||
@@ -1709,11 +1719,11 @@ DISAS_INSN(or)
|
||||
reg = DREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
if (insn & 0x100) {
|
||||
- SRC_EA(src, OS_LONG, 0, &addr);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, &addr);
|
||||
tcg_gen_or_i32(dest, src, reg);
|
||||
- DEST_EA(insn, OS_LONG, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
|
||||
} else {
|
||||
- SRC_EA(src, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, NULL);
|
||||
tcg_gen_or_i32(dest, src, reg);
|
||||
tcg_gen_mov_i32(reg, dest);
|
||||
}
|
||||
@@ -1725,7 +1735,7 @@ DISAS_INSN(suba)
|
||||
TCGv src;
|
||||
TCGv reg;
|
||||
|
||||
- SRC_EA(src, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, NULL);
|
||||
reg = AREG(insn, 9);
|
||||
tcg_gen_sub_i32(reg, reg, src);
|
||||
}
|
||||
@@ -1751,7 +1761,7 @@ DISAS_INSN(mov3q)
|
||||
val = -1;
|
||||
src = tcg_const_i32(val);
|
||||
gen_logic_cc(s, src);
|
||||
- DEST_EA(insn, OS_LONG, src, NULL);
|
||||
+ DEST_EA(env, insn, OS_LONG, src, NULL);
|
||||
}
|
||||
|
||||
DISAS_INSN(cmp)
|
||||
@@ -1779,7 +1789,7 @@ DISAS_INSN(cmp)
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
- SRC_EA(src, opsize, 1, NULL);
|
||||
+ SRC_EA(env, src, opsize, 1, NULL);
|
||||
reg = DREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
tcg_gen_sub_i32(dest, reg, src);
|
||||
@@ -1798,7 +1808,7 @@ DISAS_INSN(cmpa)
|
||||
} else {
|
||||
opsize = OS_WORD;
|
||||
}
|
||||
- SRC_EA(src, opsize, 1, NULL);
|
||||
+ SRC_EA(env, src, opsize, 1, NULL);
|
||||
reg = AREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
tcg_gen_sub_i32(dest, reg, src);
|
||||
@@ -1813,12 +1823,12 @@ DISAS_INSN(eor)
|
||||
TCGv dest;
|
||||
TCGv addr;
|
||||
|
||||
- SRC_EA(src, OS_LONG, 0, &addr);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, &addr);
|
||||
reg = DREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
tcg_gen_xor_i32(dest, src, reg);
|
||||
gen_logic_cc(s, dest);
|
||||
- DEST_EA(insn, OS_LONG, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
|
||||
}
|
||||
|
||||
DISAS_INSN(and)
|
||||
@@ -1831,11 +1841,11 @@ DISAS_INSN(and)
|
||||
reg = DREG(insn, 9);
|
||||
dest = tcg_temp_new();
|
||||
if (insn & 0x100) {
|
||||
- SRC_EA(src, OS_LONG, 0, &addr);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, &addr);
|
||||
tcg_gen_and_i32(dest, src, reg);
|
||||
- DEST_EA(insn, OS_LONG, dest, &addr);
|
||||
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
|
||||
} else {
|
||||
- SRC_EA(src, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, NULL);
|
||||
tcg_gen_and_i32(dest, src, reg);
|
||||
tcg_gen_mov_i32(reg, dest);
|
||||
}
|
||||
@@ -1847,7 +1857,7 @@ DISAS_INSN(adda)
|
||||
TCGv src;
|
||||
TCGv reg;
|
||||
|
||||
- SRC_EA(src, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, src, OS_LONG, 0, NULL);
|
||||
reg = AREG(insn, 9);
|
||||
tcg_gen_add_i32(reg, reg, src);
|
||||
}
|
||||
@@ -1936,13 +1946,13 @@ DISAS_INSN(strldsr)
|
||||
uint32_t addr;
|
||||
|
||||
addr = s->pc - 2;
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
if (ext != 0x46FC) {
|
||||
gen_exception(s, addr, EXCP_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
if (IS_USER(s) || (ext & SR_S) == 0) {
|
||||
gen_exception(s, addr, EXCP_PRIVILEGE);
|
||||
@@ -1972,7 +1982,7 @@ DISAS_INSN(move_to_sr)
|
||||
gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
|
||||
return;
|
||||
}
|
||||
- gen_set_sr(s, insn, 0);
|
||||
+ gen_set_sr(env, s, insn, 0);
|
||||
gen_lookup_tb(s);
|
||||
}
|
||||
|
||||
@@ -2010,7 +2020,7 @@ DISAS_INSN(stop)
|
||||
return;
|
||||
}
|
||||
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
gen_set_sr_im(s, ext, 0);
|
||||
@@ -2037,7 +2047,7 @@ DISAS_INSN(movec)
|
||||
return;
|
||||
}
|
||||
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
if (ext & 0x8000) {
|
||||
@@ -2102,7 +2112,7 @@ DISAS_INSN(fpu)
|
||||
int set_dest;
|
||||
int opsize;
|
||||
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
opmode = ext & 0x7f;
|
||||
switch ((ext >> 13) & 7) {
|
||||
@@ -2138,7 +2148,7 @@ DISAS_INSN(fpu)
|
||||
tcg_gen_addi_i32(tmp32, tmp32, -8);
|
||||
break;
|
||||
case 5:
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
||||
break;
|
||||
@@ -2164,7 +2174,7 @@ DISAS_INSN(fpu)
|
||||
default:
|
||||
goto undef;
|
||||
}
|
||||
- DEST_EA(insn, opsize, tmp32, NULL);
|
||||
+ DEST_EA(env, insn, opsize, tmp32, NULL);
|
||||
tcg_temp_free_i32(tmp32);
|
||||
return;
|
||||
case 4: /* fmove to control register. */
|
||||
@@ -2192,7 +2202,7 @@ DISAS_INSN(fpu)
|
||||
(ext >> 10) & 7);
|
||||
goto undef;
|
||||
}
|
||||
- DEST_EA(insn, OS_LONG, tmp32, NULL);
|
||||
+ DEST_EA(env, insn, OS_LONG, tmp32, NULL);
|
||||
break;
|
||||
case 6: /* fmovem */
|
||||
case 7:
|
||||
@@ -2202,7 +2212,7 @@ DISAS_INSN(fpu)
|
||||
int i;
|
||||
if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
|
||||
goto undef;
|
||||
- tmp32 = gen_lea(s, insn, OS_LONG);
|
||||
+ tmp32 = gen_lea(env, s, insn, OS_LONG);
|
||||
if (IS_NULL_QREG(tmp32)) {
|
||||
gen_addr_fault(s);
|
||||
return;
|
||||
@@ -2252,12 +2262,12 @@ DISAS_INSN(fpu)
|
||||
tcg_gen_addi_i32(tmp32, tmp32, -8);
|
||||
break;
|
||||
case 5:
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
||||
break;
|
||||
case 7:
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
offset += s->pc - 2;
|
||||
s->pc += 2;
|
||||
tcg_gen_addi_i32(tmp32, tmp32, offset);
|
||||
@@ -2277,7 +2287,7 @@ DISAS_INSN(fpu)
|
||||
}
|
||||
tcg_temp_free_i32(tmp32);
|
||||
} else {
|
||||
- SRC_EA(tmp32, opsize, 1, NULL);
|
||||
+ SRC_EA(env, tmp32, opsize, 1, NULL);
|
||||
src = tcg_temp_new_i64();
|
||||
switch (opsize) {
|
||||
case OS_LONG:
|
||||
@@ -2372,7 +2382,7 @@ DISAS_INSN(fpu)
|
||||
undef:
|
||||
/* FIXME: Is this right for offset addressing modes? */
|
||||
s->pc -= 2;
|
||||
- disas_undef_fpu(s, insn);
|
||||
+ disas_undef_fpu(env, s, insn);
|
||||
}
|
||||
|
||||
DISAS_INSN(fbcc)
|
||||
@@ -2383,10 +2393,10 @@ DISAS_INSN(fbcc)
|
||||
int l1;
|
||||
|
||||
addr = s->pc;
|
||||
- offset = cpu_ldsw_code(cpu_single_env, s->pc);
|
||||
+ offset = cpu_ldsw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
if (insn & (1 << 6)) {
|
||||
- offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ offset = (offset << 16) | cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
}
|
||||
|
||||
@@ -2508,18 +2518,18 @@ DISAS_INSN(mac)
|
||||
s->done_mac = 1;
|
||||
}
|
||||
|
||||
- ext = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ ext = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
|
||||
dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
|
||||
if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
|
||||
- disas_undef(s, insn);
|
||||
+ disas_undef(env, s, insn);
|
||||
return;
|
||||
}
|
||||
if (insn & 0x30) {
|
||||
/* MAC with load. */
|
||||
- tmp = gen_lea(s, insn, OS_LONG);
|
||||
+ tmp = gen_lea(env, s, insn, OS_LONG);
|
||||
addr = tcg_temp_new();
|
||||
tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
|
||||
/* Load the value now to ensure correct exception behavior.
|
||||
@@ -2733,7 +2743,7 @@ DISAS_INSN(to_mac)
|
||||
int accnum;
|
||||
accnum = (insn >> 9) & 3;
|
||||
acc = MACREG(accnum);
|
||||
- SRC_EA(val, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, val, OS_LONG, 0, NULL);
|
||||
if (s->env->macsr & MACSR_FI) {
|
||||
tcg_gen_ext_i32_i64(acc, val);
|
||||
tcg_gen_shli_i64(acc, acc, 8);
|
||||
@@ -2750,7 +2760,7 @@ DISAS_INSN(to_mac)
|
||||
DISAS_INSN(to_macsr)
|
||||
{
|
||||
TCGv val;
|
||||
- SRC_EA(val, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, val, OS_LONG, 0, NULL);
|
||||
gen_helper_set_macsr(cpu_env, val);
|
||||
gen_lookup_tb(s);
|
||||
}
|
||||
@@ -2758,7 +2768,7 @@ DISAS_INSN(to_macsr)
|
||||
DISAS_INSN(to_mask)
|
||||
{
|
||||
TCGv val;
|
||||
- SRC_EA(val, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, val, OS_LONG, 0, NULL);
|
||||
tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
|
||||
}
|
||||
|
||||
@@ -2766,7 +2776,7 @@ DISAS_INSN(to_mext)
|
||||
{
|
||||
TCGv val;
|
||||
TCGv acc;
|
||||
- SRC_EA(val, OS_LONG, 0, NULL);
|
||||
+ SRC_EA(env, val, OS_LONG, 0, NULL);
|
||||
acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
|
||||
if (s->env->macsr & MACSR_FI)
|
||||
gen_helper_set_mac_extf(cpu_env, val, acc);
|
||||
@@ -2943,10 +2953,10 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
|
||||
{
|
||||
uint16_t insn;
|
||||
|
||||
- insn = cpu_lduw_code(cpu_single_env, s->pc);
|
||||
+ insn = cpu_lduw_code(env, s->pc);
|
||||
s->pc += 2;
|
||||
|
||||
- opcode_table[insn](s, insn);
|
||||
+ opcode_table[insn](env, s, insn);
|
||||
}
|
||||
|
||||
/* generate intermediate code for basic block 'tb'. */
|
||||
--
|
||||
1.7.12.1
|
||||
|
437
0030-target-unicore32-switch-to-AREG0-free-mode.patch
Normal file
437
0030-target-unicore32-switch-to-AREG0-free-mode.patch
Normal file
@ -0,0 +1,437 @@
|
||||
From 23ff6fa6a883d210aab33e09d0bb9470df5083fc Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 07:42:33 +0000
|
||||
Subject: [PATCH] target-unicore32: switch to AREG0 free mode
|
||||
|
||||
Add an explicit CPUState parameter instead of relying on AREG0
|
||||
and switch to AREG0 free mode.
|
||||
|
||||
Tested-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 2 +-
|
||||
target-unicore32/Makefile.objs | 2 --
|
||||
target-unicore32/helper.h | 26 ++++++++---------
|
||||
target-unicore32/op_helper.c | 65 ++++++++++++++++--------------------------
|
||||
target-unicore32/translate.c | 38 ++++++++++++------------
|
||||
5 files changed, 58 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index af03942..a8827ba 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
|
||||
|
||||
|
||||
case "$target_arch2" in
|
||||
- alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
|
||||
+ alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
|
||||
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
|
||||
;;
|
||||
esac
|
||||
diff --git a/target-unicore32/Makefile.objs b/target-unicore32/Makefile.objs
|
||||
index 777f01f..8e143da 100644
|
||||
--- a/target-unicore32/Makefile.objs
|
||||
+++ b/target-unicore32/Makefile.objs
|
||||
@@ -2,5 +2,3 @@ obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-y += ucf64_helper.o
|
||||
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o softmmu.o
|
||||
-
|
||||
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-unicore32/helper.h b/target-unicore32/helper.h
|
||||
index 305318a..a4b8149 100644
|
||||
--- a/target-unicore32/helper.h
|
||||
+++ b/target-unicore32/helper.h
|
||||
@@ -17,26 +17,26 @@ DEF_HELPER_1(cp1_putc, void, i32)
|
||||
DEF_HELPER_1(clz, i32, i32)
|
||||
DEF_HELPER_1(clo, i32, i32)
|
||||
|
||||
-DEF_HELPER_1(exception, void, i32)
|
||||
+DEF_HELPER_2(exception, void, env, i32)
|
||||
|
||||
-DEF_HELPER_2(asr_write, void, i32, i32)
|
||||
-DEF_HELPER_0(asr_read, i32)
|
||||
+DEF_HELPER_3(asr_write, void, env, i32, i32)
|
||||
+DEF_HELPER_1(asr_read, i32, env)
|
||||
|
||||
-DEF_HELPER_1(get_user_reg, i32, i32)
|
||||
-DEF_HELPER_2(set_user_reg, void, i32, i32)
|
||||
+DEF_HELPER_2(get_user_reg, i32, env, i32)
|
||||
+DEF_HELPER_3(set_user_reg, void, env, i32, i32)
|
||||
|
||||
-DEF_HELPER_2(add_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(adc_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(sub_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(sbc_cc, i32, i32, i32)
|
||||
+DEF_HELPER_3(add_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(adc_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sub_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
|
||||
|
||||
DEF_HELPER_2(shl, i32, i32, i32)
|
||||
DEF_HELPER_2(shr, i32, i32, i32)
|
||||
DEF_HELPER_2(sar, i32, i32, i32)
|
||||
-DEF_HELPER_2(shl_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(shr_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(sar_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(ror_cc, i32, i32, i32)
|
||||
+DEF_HELPER_3(shl_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(shr_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sar_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(ror_cc, i32, env, i32, i32)
|
||||
|
||||
DEF_HELPER_1(ucf64_get_fpscr, i32, env)
|
||||
DEF_HELPER_2(ucf64_set_fpscr, void, env, i32)
|
||||
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
|
||||
index c63789d..f474d1b 100644
|
||||
--- a/target-unicore32/op_helper.c
|
||||
+++ b/target-unicore32/op_helper.c
|
||||
@@ -9,19 +9,18 @@
|
||||
* later version. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "helper.h"
|
||||
|
||||
#define SIGNBIT (uint32_t)0x80000000
|
||||
#define SIGNBIT64 ((uint64_t)1 << 63)
|
||||
|
||||
-void HELPER(exception)(uint32_t excp)
|
||||
+void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
|
||||
{
|
||||
env->exception_index = excp;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-static target_ulong asr_read(void)
|
||||
+static target_ulong asr_read(CPUUniCore32State *env)
|
||||
{
|
||||
int ZF;
|
||||
ZF = (env->ZF == 0);
|
||||
@@ -29,24 +28,18 @@ static target_ulong asr_read(void)
|
||||
(env->CF << 29) | ((env->VF & 0x80000000) >> 3);
|
||||
}
|
||||
|
||||
-target_ulong cpu_asr_read(CPUUniCore32State *env1)
|
||||
+target_ulong cpu_asr_read(CPUUniCore32State *env)
|
||||
{
|
||||
- CPUUniCore32State *saved_env;
|
||||
- target_ulong ret;
|
||||
-
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
- ret = asr_read();
|
||||
- env = saved_env;
|
||||
- return ret;
|
||||
+ return asr_read(env);
|
||||
}
|
||||
|
||||
-target_ulong HELPER(asr_read)(void)
|
||||
+target_ulong HELPER(asr_read)(CPUUniCore32State *env)
|
||||
{
|
||||
- return asr_read();
|
||||
+ return asr_read(env);
|
||||
}
|
||||
|
||||
-static void asr_write(target_ulong val, target_ulong mask)
|
||||
+static void asr_write(CPUUniCore32State *env, target_ulong val,
|
||||
+ target_ulong mask)
|
||||
{
|
||||
if (mask & ASR_NZCV) {
|
||||
env->ZF = (~val) & ASR_Z;
|
||||
@@ -62,23 +55,19 @@ static void asr_write(target_ulong val, target_ulong mask)
|
||||
env->uncached_asr = (env->uncached_asr & ~mask) | (val & mask);
|
||||
}
|
||||
|
||||
-void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
|
||||
+void cpu_asr_write(CPUUniCore32State *env, target_ulong val, target_ulong mask)
|
||||
{
|
||||
- CPUUniCore32State *saved_env;
|
||||
-
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
- asr_write(val, mask);
|
||||
- env = saved_env;
|
||||
+ asr_write(env, val, mask);
|
||||
}
|
||||
|
||||
-void HELPER(asr_write)(target_ulong val, target_ulong mask)
|
||||
+void HELPER(asr_write)(CPUUniCore32State *env, target_ulong val,
|
||||
+ target_ulong mask)
|
||||
{
|
||||
- asr_write(val, mask);
|
||||
+ asr_write(env, val, mask);
|
||||
}
|
||||
|
||||
/* Access to user mode registers from privileged modes. */
|
||||
-uint32_t HELPER(get_user_reg)(uint32_t regno)
|
||||
+uint32_t HELPER(get_user_reg)(CPUUniCore32State *env, uint32_t regno)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
@@ -92,7 +81,7 @@ uint32_t HELPER(get_user_reg)(uint32_t regno)
|
||||
return val;
|
||||
}
|
||||
|
||||
-void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
|
||||
+void HELPER(set_user_reg)(CPUUniCore32State *env, uint32_t regno, uint32_t val)
|
||||
{
|
||||
if (regno == 29) {
|
||||
env->banked_r29[0] = val;
|
||||
@@ -107,7 +96,7 @@ void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
|
||||
The only way to do that in TCG is a conditional branch, which clobbers
|
||||
all our temporaries. For now implement these as helper functions. */
|
||||
|
||||
-uint32_t HELPER(add_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(add_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
result = a + b;
|
||||
@@ -117,7 +106,7 @@ uint32_t HELPER(add_cc)(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(adc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!env->CF) {
|
||||
@@ -132,7 +121,7 @@ uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(sub_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
result = a - b;
|
||||
@@ -142,7 +131,7 @@ uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(sbc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!env->CF) {
|
||||
@@ -186,7 +175,7 @@ uint32_t HELPER(sar)(uint32_t x, uint32_t i)
|
||||
return (int32_t)x >> shift;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(shl_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32) {
|
||||
@@ -203,7 +192,7 @@ uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
|
||||
return x;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(shr_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32) {
|
||||
@@ -220,7 +209,7 @@ uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
|
||||
return x;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(sar_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32) {
|
||||
@@ -233,7 +222,7 @@ uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
|
||||
return x;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift1, shift;
|
||||
shift1 = i & 0xff;
|
||||
@@ -264,16 +253,13 @@ uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
|
||||
#define SHIFT 3
|
||||
#include "softmmu_template.h"
|
||||
|
||||
-void tlb_fill(CPUUniCore32State *env1, target_ulong addr, int is_write,
|
||||
- int mmu_idx, uintptr_t retaddr)
|
||||
+void tlb_fill(CPUUniCore32State *env, target_ulong addr, int is_write,
|
||||
+ int mmu_idx, uintptr_t retaddr)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
- CPUUniCore32State *saved_env;
|
||||
unsigned long pc;
|
||||
int ret;
|
||||
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
ret = uc32_cpu_handle_mmu_fault(env, addr, is_write, mmu_idx);
|
||||
if (unlikely(ret)) {
|
||||
if (retaddr) {
|
||||
@@ -287,6 +273,5 @@ void tlb_fill(CPUUniCore32State *env1, target_ulong addr, int is_write,
|
||||
}
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
- env = saved_env;
|
||||
}
|
||||
#endif
|
||||
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
|
||||
index 188bf8c..b786a6b 100644
|
||||
--- a/target-unicore32/translate.c
|
||||
+++ b/target-unicore32/translate.c
|
||||
@@ -253,7 +253,7 @@ static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
|
||||
static inline void gen_set_asr(TCGv var, uint32_t mask)
|
||||
{
|
||||
TCGv tmp_mask = tcg_const_i32(mask);
|
||||
- gen_helper_asr_write(var, tmp_mask);
|
||||
+ gen_helper_asr_write(cpu_env, var, tmp_mask);
|
||||
tcg_temp_free_i32(tmp_mask);
|
||||
}
|
||||
/* Set NZCV flags from the high 4 bits of var. */
|
||||
@@ -263,7 +263,7 @@ static void gen_exception(int excp)
|
||||
{
|
||||
TCGv tmp = new_tmp();
|
||||
tcg_gen_movi_i32(tmp, excp);
|
||||
- gen_helper_exception(tmp);
|
||||
+ gen_helper_exception(cpu_env, tmp);
|
||||
dead_tmp(tmp);
|
||||
}
|
||||
|
||||
@@ -416,16 +416,16 @@ static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
|
||||
if (flags) {
|
||||
switch (shiftop) {
|
||||
case 0:
|
||||
- gen_helper_shl_cc(var, var, shift);
|
||||
+ gen_helper_shl_cc(var, cpu_env, var, shift);
|
||||
break;
|
||||
case 1:
|
||||
- gen_helper_shr_cc(var, var, shift);
|
||||
+ gen_helper_shr_cc(var, cpu_env, var, shift);
|
||||
break;
|
||||
case 2:
|
||||
- gen_helper_sar_cc(var, var, shift);
|
||||
+ gen_helper_sar_cc(var, cpu_env, var, shift);
|
||||
break;
|
||||
case 3:
|
||||
- gen_helper_ror_cc(var, var, shift);
|
||||
+ gen_helper_ror_cc(var, cpu_env, var, shift);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -1323,11 +1323,11 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
if (IS_USER(s)) {
|
||||
ILLEGAL;
|
||||
}
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
gen_exception_return(s, tmp);
|
||||
} else {
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
tcg_gen_sub_i32(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -1336,7 +1336,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 0x03:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_sub_cc(tmp, tmp2, tmp);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
tcg_gen_sub_i32(tmp, tmp2, tmp);
|
||||
}
|
||||
@@ -1344,7 +1344,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 0x04:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
tcg_gen_add_i32(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -1352,7 +1352,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 0x05:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_adc_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
gen_add_carry(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -1360,7 +1360,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 0x06:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_sbc_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
gen_sub_carry(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -1368,7 +1368,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 0x07:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_sbc_cc(tmp, tmp2, tmp);
|
||||
+ gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
gen_sub_carry(tmp, tmp2, tmp);
|
||||
}
|
||||
@@ -1390,13 +1390,13 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 0x0a:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
dead_tmp(tmp);
|
||||
break;
|
||||
case 0x0b:
|
||||
if (UCOP_SET_S) {
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
dead_tmp(tmp);
|
||||
break;
|
||||
@@ -1536,7 +1536,7 @@ static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
tmp = load_cpu_field(bsr);
|
||||
} else {
|
||||
tmp = new_tmp();
|
||||
- gen_helper_asr_read(tmp);
|
||||
+ gen_helper_asr_read(tmp, cpu_env);
|
||||
}
|
||||
store_reg(s, UCOP_REG_D, tmp);
|
||||
return;
|
||||
@@ -1760,7 +1760,7 @@ static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
gen_bx(s, tmp);
|
||||
} else if (user) {
|
||||
tmp2 = tcg_const_i32(reg);
|
||||
- gen_helper_set_user_reg(tmp2, tmp);
|
||||
+ gen_helper_set_user_reg(cpu_env, tmp2, tmp);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
dead_tmp(tmp);
|
||||
} else if (reg == UCOP_REG_N) {
|
||||
@@ -1778,7 +1778,7 @@ static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
|
||||
} else if (user) {
|
||||
tmp = new_tmp();
|
||||
tmp2 = tcg_const_i32(reg);
|
||||
- gen_helper_get_user_reg(tmp, tmp2);
|
||||
+ gen_helper_get_user_reg(tmp, cpu_env, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
} else {
|
||||
tmp = load_reg(s, reg);
|
||||
@@ -1861,7 +1861,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
|
||||
{
|
||||
unsigned int insn;
|
||||
|
||||
- insn = ldl_code(s->pc);
|
||||
+ insn = cpu_ldl_code(env, s->pc);
|
||||
s->pc += 4;
|
||||
|
||||
/* UniCore instructions class:
|
||||
--
|
||||
1.7.12.1
|
||||
|
181
0031-target-arm-convert-void-helpers.patch
Normal file
181
0031-target-arm-convert-void-helpers.patch
Normal file
@ -0,0 +1,181 @@
|
||||
From 140048c58e4ceb4f3bac87d7154d2731bb2bcd5d Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Tue, 4 Sep 2012 20:08:34 +0000
|
||||
Subject: [PATCH] target-arm: convert void helpers
|
||||
|
||||
Add an explicit CPUState parameter instead of relying on AREG0.
|
||||
|
||||
For easier review, convert only op helpers which don't return any value.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-arm/helper.h | 8 ++++----
|
||||
target-arm/op_helper.c | 20 ++++++++++----------
|
||||
target-arm/translate.c | 8 ++++----
|
||||
3 files changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/target-arm/helper.h b/target-arm/helper.h
|
||||
index 21e9cfe..106aacd 100644
|
||||
--- a/target-arm/helper.h
|
||||
+++ b/target-arm/helper.h
|
||||
@@ -50,10 +50,10 @@ DEF_HELPER_2(usad8, i32, i32, i32)
|
||||
DEF_HELPER_1(logicq_cc, i32, i64)
|
||||
|
||||
DEF_HELPER_3(sel_flags, i32, i32, i32, i32)
|
||||
-DEF_HELPER_1(exception, void, i32)
|
||||
-DEF_HELPER_0(wfi, void)
|
||||
+DEF_HELPER_2(exception, void, env, i32)
|
||||
+DEF_HELPER_1(wfi, void, env)
|
||||
|
||||
-DEF_HELPER_2(cpsr_write, void, i32, i32)
|
||||
+DEF_HELPER_3(cpsr_write, void, env, i32, i32)
|
||||
DEF_HELPER_0(cpsr_read, i32)
|
||||
|
||||
DEF_HELPER_3(v7m_msr, void, env, i32, i32)
|
||||
@@ -68,7 +68,7 @@ DEF_HELPER_2(get_r13_banked, i32, env, i32)
|
||||
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_1(get_user_reg, i32, i32)
|
||||
-DEF_HELPER_2(set_user_reg, void, i32, i32)
|
||||
+DEF_HELPER_3(set_user_reg, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_1(vfp_get_fpscr, i32, env)
|
||||
DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
|
||||
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
|
||||
index d77bfab..b1adce3 100644
|
||||
--- a/target-arm/op_helper.c
|
||||
+++ b/target-arm/op_helper.c
|
||||
@@ -23,7 +23,7 @@
|
||||
#define SIGNBIT (uint32_t)0x80000000
|
||||
#define SIGNBIT64 ((uint64_t)1 << 63)
|
||||
|
||||
-static void raise_exception(int tt)
|
||||
+static void raise_exception(CPUARMState *env, int tt)
|
||||
{
|
||||
env->exception_index = tt;
|
||||
cpu_loop_exit(env);
|
||||
@@ -93,7 +93,7 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
cpu_restore_state(tb, env, retaddr);
|
||||
}
|
||||
}
|
||||
- raise_exception(env->exception_index);
|
||||
+ raise_exception(env, env->exception_index);
|
||||
}
|
||||
env = saved_env;
|
||||
}
|
||||
@@ -230,14 +230,14 @@ uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
|
||||
return res;
|
||||
}
|
||||
|
||||
-void HELPER(wfi)(void)
|
||||
+void HELPER(wfi)(CPUARMState *env)
|
||||
{
|
||||
env->exception_index = EXCP_HLT;
|
||||
env->halted = 1;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void HELPER(exception)(uint32_t excp)
|
||||
+void HELPER(exception)(CPUARMState *env, uint32_t excp)
|
||||
{
|
||||
env->exception_index = excp;
|
||||
cpu_loop_exit(env);
|
||||
@@ -248,7 +248,7 @@ uint32_t HELPER(cpsr_read)(void)
|
||||
return cpsr_read(env) & ~CPSR_EXEC;
|
||||
}
|
||||
|
||||
-void HELPER(cpsr_write)(uint32_t val, uint32_t mask)
|
||||
+void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
{
|
||||
cpsr_write(env, val, mask);
|
||||
}
|
||||
@@ -271,7 +271,7 @@ uint32_t HELPER(get_user_reg)(uint32_t regno)
|
||||
return val;
|
||||
}
|
||||
|
||||
-void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
|
||||
+void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
|
||||
{
|
||||
if (regno == 13) {
|
||||
env->banked_r13[0] = val;
|
||||
@@ -290,7 +290,7 @@ void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
|
||||
const ARMCPRegInfo *ri = rip;
|
||||
int excp = ri->writefn(env, ri, value);
|
||||
if (excp) {
|
||||
- raise_exception(excp);
|
||||
+ raise_exception(env, excp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
|
||||
uint64_t value;
|
||||
int excp = ri->readfn(env, ri, &value);
|
||||
if (excp) {
|
||||
- raise_exception(excp);
|
||||
+ raise_exception(env, excp);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -310,7 +310,7 @@ void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
|
||||
const ARMCPRegInfo *ri = rip;
|
||||
int excp = ri->writefn(env, ri, value);
|
||||
if (excp) {
|
||||
- raise_exception(excp);
|
||||
+ raise_exception(env, excp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
|
||||
uint64_t value;
|
||||
int excp = ri->readfn(env, ri, &value);
|
||||
if (excp) {
|
||||
- raise_exception(excp);
|
||||
+ raise_exception(env, excp);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
diff --git a/target-arm/translate.c b/target-arm/translate.c
|
||||
index edef79a..6f651d9 100644
|
||||
--- a/target-arm/translate.c
|
||||
+++ b/target-arm/translate.c
|
||||
@@ -199,7 +199,7 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
|
||||
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
|
||||
{
|
||||
TCGv tmp_mask = tcg_const_i32(mask);
|
||||
- gen_helper_cpsr_write(var, tmp_mask);
|
||||
+ gen_helper_cpsr_write(cpu_env, var, tmp_mask);
|
||||
tcg_temp_free_i32(tmp_mask);
|
||||
}
|
||||
/* Set NZCV flags from the high 4 bits of var. */
|
||||
@@ -209,7 +209,7 @@ static void gen_exception(int excp)
|
||||
{
|
||||
TCGv tmp = tcg_temp_new_i32();
|
||||
tcg_gen_movi_i32(tmp, excp);
|
||||
- gen_helper_exception(tmp);
|
||||
+ gen_helper_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
@@ -7719,7 +7719,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
tmp = gen_ld32(addr, IS_USER(s));
|
||||
if (user) {
|
||||
tmp2 = tcg_const_i32(i);
|
||||
- gen_helper_set_user_reg(tmp2, tmp);
|
||||
+ gen_helper_set_user_reg(cpu_env, tmp2, tmp);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
tcg_temp_free_i32(tmp);
|
||||
} else if (i == rn) {
|
||||
@@ -9913,7 +9913,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
|
||||
/* nothing more to generate */
|
||||
break;
|
||||
case DISAS_WFI:
|
||||
- gen_helper_wfi();
|
||||
+ gen_helper_wfi(cpu_env);
|
||||
break;
|
||||
case DISAS_SWI:
|
||||
gen_exception(EXCP_SWI);
|
||||
--
|
||||
1.7.12.1
|
||||
|
821
0032-target-arm-convert-remaining-helpers.patch
Normal file
821
0032-target-arm-convert-remaining-helpers.patch
Normal file
@ -0,0 +1,821 @@
|
||||
From 18e713cf6b5ae2e7c48bb412c959c10322bef5e5 Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Tue, 4 Sep 2012 20:19:15 +0000
|
||||
Subject: [PATCH] target-arm: convert remaining helpers
|
||||
|
||||
Convert remaining helpers to AREG0 free mode: add an explicit
|
||||
CPUState parameter instead of relying on AREG0.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-arm/helper.h | 52 +++++++++----------
|
||||
target-arm/op_helper.c | 64 +++++++++++------------
|
||||
target-arm/translate.c | 134 ++++++++++++++++++++++++-------------------------
|
||||
3 files changed, 125 insertions(+), 125 deletions(-)
|
||||
|
||||
diff --git a/target-arm/helper.h b/target-arm/helper.h
|
||||
index 106aacd..afdb2b5 100644
|
||||
--- a/target-arm/helper.h
|
||||
+++ b/target-arm/helper.h
|
||||
@@ -4,12 +4,12 @@ DEF_HELPER_1(clz, i32, i32)
|
||||
DEF_HELPER_1(sxtb16, i32, i32)
|
||||
DEF_HELPER_1(uxtb16, i32, i32)
|
||||
|
||||
-DEF_HELPER_2(add_setq, i32, i32, i32)
|
||||
-DEF_HELPER_2(add_saturate, i32, i32, i32)
|
||||
-DEF_HELPER_2(sub_saturate, i32, i32, i32)
|
||||
-DEF_HELPER_2(add_usaturate, i32, i32, i32)
|
||||
-DEF_HELPER_2(sub_usaturate, i32, i32, i32)
|
||||
-DEF_HELPER_1(double_saturate, i32, s32)
|
||||
+DEF_HELPER_3(add_setq, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(add_saturate, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sub_saturate, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(add_usaturate, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sub_usaturate, i32, env, i32, i32)
|
||||
+DEF_HELPER_2(double_saturate, i32, env, s32)
|
||||
DEF_HELPER_2(sdiv, s32, s32, s32)
|
||||
DEF_HELPER_2(udiv, i32, i32, i32)
|
||||
DEF_HELPER_1(rbit, i32, i32)
|
||||
@@ -40,10 +40,10 @@ PAS_OP(uq)
|
||||
PAS_OP(uh)
|
||||
#undef PAS_OP
|
||||
|
||||
-DEF_HELPER_2(ssat, i32, i32, i32)
|
||||
-DEF_HELPER_2(usat, i32, i32, i32)
|
||||
-DEF_HELPER_2(ssat16, i32, i32, i32)
|
||||
-DEF_HELPER_2(usat16, i32, i32, i32)
|
||||
+DEF_HELPER_3(ssat, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(usat, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(ssat16, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(usat16, i32, env, i32, i32)
|
||||
|
||||
DEF_HELPER_2(usad8, i32, i32, i32)
|
||||
|
||||
@@ -54,7 +54,7 @@ DEF_HELPER_2(exception, void, env, i32)
|
||||
DEF_HELPER_1(wfi, void, env)
|
||||
|
||||
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
|
||||
-DEF_HELPER_0(cpsr_read, i32)
|
||||
+DEF_HELPER_1(cpsr_read, i32, env)
|
||||
|
||||
DEF_HELPER_3(v7m_msr, void, env, i32, i32)
|
||||
DEF_HELPER_2(v7m_mrs, i32, env, i32)
|
||||
@@ -67,7 +67,7 @@ DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
|
||||
DEF_HELPER_2(get_r13_banked, i32, env, i32)
|
||||
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
|
||||
|
||||
-DEF_HELPER_1(get_user_reg, i32, i32)
|
||||
+DEF_HELPER_2(get_user_reg, i32, env, i32)
|
||||
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_1(vfp_get_fpscr, i32, env)
|
||||
@@ -140,20 +140,20 @@ DEF_HELPER_2(recpe_f32, f32, f32, env)
|
||||
DEF_HELPER_2(rsqrte_f32, f32, f32, env)
|
||||
DEF_HELPER_2(recpe_u32, i32, i32, env)
|
||||
DEF_HELPER_2(rsqrte_u32, i32, i32, env)
|
||||
-DEF_HELPER_4(neon_tbl, i32, i32, i32, i32, i32)
|
||||
-
|
||||
-DEF_HELPER_2(add_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(adc_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(sub_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(sbc_cc, i32, i32, i32)
|
||||
-
|
||||
-DEF_HELPER_2(shl, i32, i32, i32)
|
||||
-DEF_HELPER_2(shr, i32, i32, i32)
|
||||
-DEF_HELPER_2(sar, i32, i32, i32)
|
||||
-DEF_HELPER_2(shl_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(shr_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(sar_cc, i32, i32, i32)
|
||||
-DEF_HELPER_2(ror_cc, i32, i32, i32)
|
||||
+DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
|
||||
+
|
||||
+DEF_HELPER_3(add_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(adc_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sub_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
|
||||
+
|
||||
+DEF_HELPER_3(shl, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(shr, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sar, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(shl_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(shr_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(sar_cc, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(ror_cc, i32, env, i32, i32)
|
||||
|
||||
/* neon_helper.c */
|
||||
DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32)
|
||||
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
|
||||
index b1adce3..5b868bf 100644
|
||||
--- a/target-arm/op_helper.c
|
||||
+++ b/target-arm/op_helper.c
|
||||
@@ -29,7 +29,7 @@ static void raise_exception(CPUARMState *env, int tt)
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
|
||||
+uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
|
||||
uint32_t rn, uint32_t maxindex)
|
||||
{
|
||||
uint32_t val;
|
||||
@@ -101,7 +101,7 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
|
||||
/* FIXME: Pass an explicit pointer to QF to CPUARMState, and move saturating
|
||||
instructions into helper.c */
|
||||
-uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t res = a + b;
|
||||
if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
|
||||
@@ -109,7 +109,7 @@ uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
|
||||
return res;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t res = a + b;
|
||||
if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
|
||||
@@ -119,7 +119,7 @@ uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b)
|
||||
return res;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t res = a - b;
|
||||
if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
|
||||
@@ -129,7 +129,7 @@ uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b)
|
||||
return res;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(double_saturate)(int32_t val)
|
||||
+uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val)
|
||||
{
|
||||
uint32_t res;
|
||||
if (val >= 0x40000000) {
|
||||
@@ -144,7 +144,7 @@ uint32_t HELPER(double_saturate)(int32_t val)
|
||||
return res;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t res = a + b;
|
||||
if (res < a) {
|
||||
@@ -154,7 +154,7 @@ uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b)
|
||||
return res;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t res = a - b;
|
||||
if (res > a) {
|
||||
@@ -165,7 +165,7 @@ uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b)
|
||||
}
|
||||
|
||||
/* Signed saturation. */
|
||||
-static inline uint32_t do_ssat(int32_t val, int shift)
|
||||
+static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
|
||||
{
|
||||
int32_t top;
|
||||
uint32_t mask;
|
||||
@@ -183,7 +183,7 @@ static inline uint32_t do_ssat(int32_t val, int shift)
|
||||
}
|
||||
|
||||
/* Unsigned saturation. */
|
||||
-static inline uint32_t do_usat(int32_t val, int shift)
|
||||
+static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
|
||||
{
|
||||
uint32_t max;
|
||||
|
||||
@@ -199,34 +199,34 @@ static inline uint32_t do_usat(int32_t val, int shift)
|
||||
}
|
||||
|
||||
/* Signed saturate. */
|
||||
-uint32_t HELPER(ssat)(uint32_t x, uint32_t shift)
|
||||
+uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
|
||||
{
|
||||
- return do_ssat(x, shift);
|
||||
+ return do_ssat(env, x, shift);
|
||||
}
|
||||
|
||||
/* Dual halfword signed saturate. */
|
||||
-uint32_t HELPER(ssat16)(uint32_t x, uint32_t shift)
|
||||
+uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
- res = (uint16_t)do_ssat((int16_t)x, shift);
|
||||
- res |= do_ssat(((int32_t)x) >> 16, shift) << 16;
|
||||
+ res = (uint16_t)do_ssat(env, (int16_t)x, shift);
|
||||
+ res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Unsigned saturate. */
|
||||
-uint32_t HELPER(usat)(uint32_t x, uint32_t shift)
|
||||
+uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
|
||||
{
|
||||
- return do_usat(x, shift);
|
||||
+ return do_usat(env, x, shift);
|
||||
}
|
||||
|
||||
/* Dual halfword unsigned saturate. */
|
||||
-uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
|
||||
+uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
- res = (uint16_t)do_usat((int16_t)x, shift);
|
||||
- res |= do_usat(((int32_t)x) >> 16, shift) << 16;
|
||||
+ res = (uint16_t)do_usat(env, (int16_t)x, shift);
|
||||
+ res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ void HELPER(exception)(CPUARMState *env, uint32_t excp)
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-uint32_t HELPER(cpsr_read)(void)
|
||||
+uint32_t HELPER(cpsr_read)(CPUARMState *env)
|
||||
{
|
||||
return cpsr_read(env) & ~CPSR_EXEC;
|
||||
}
|
||||
@@ -254,7 +254,7 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
}
|
||||
|
||||
/* Access to user mode registers from privileged modes. */
|
||||
-uint32_t HELPER(get_user_reg)(uint32_t regno)
|
||||
+uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
@@ -329,7 +329,7 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
|
||||
The only way to do that in TCG is a conditional branch, which clobbers
|
||||
all our temporaries. For now implement these as helper functions. */
|
||||
|
||||
-uint32_t HELPER (add_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER (add_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
result = a + b;
|
||||
@@ -339,7 +339,7 @@ uint32_t HELPER (add_cc)(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(adc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!env->CF) {
|
||||
@@ -354,7 +354,7 @@ uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(sub_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
result = a - b;
|
||||
@@ -364,7 +364,7 @@ uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
|
||||
return result;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
|
||||
+uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t result;
|
||||
if (!env->CF) {
|
||||
@@ -381,7 +381,7 @@ uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
|
||||
|
||||
/* Similarly for variable shift instructions. */
|
||||
|
||||
-uint32_t HELPER(shl)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(shl)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32)
|
||||
@@ -389,7 +389,7 @@ uint32_t HELPER(shl)(uint32_t x, uint32_t i)
|
||||
return x << shift;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(shr)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(shr)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32)
|
||||
@@ -397,7 +397,7 @@ uint32_t HELPER(shr)(uint32_t x, uint32_t i)
|
||||
return (uint32_t)x >> shift;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sar)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(sar)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32)
|
||||
@@ -405,7 +405,7 @@ uint32_t HELPER(sar)(uint32_t x, uint32_t i)
|
||||
return (int32_t)x >> shift;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32) {
|
||||
@@ -421,7 +421,7 @@ uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
|
||||
return x;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32) {
|
||||
@@ -437,7 +437,7 @@ uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
|
||||
return x;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift = i & 0xff;
|
||||
if (shift >= 32) {
|
||||
@@ -450,7 +450,7 @@ uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
|
||||
return x;
|
||||
}
|
||||
|
||||
-uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
|
||||
+uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
||||
{
|
||||
int shift1, shift;
|
||||
shift1 = i & 0xff;
|
||||
diff --git a/target-arm/translate.c b/target-arm/translate.c
|
||||
index 6f651d9..9ae3b26 100644
|
||||
--- a/target-arm/translate.c
|
||||
+++ b/target-arm/translate.c
|
||||
@@ -490,16 +490,16 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop,
|
||||
{
|
||||
if (flags) {
|
||||
switch (shiftop) {
|
||||
- case 0: gen_helper_shl_cc(var, var, shift); break;
|
||||
- case 1: gen_helper_shr_cc(var, var, shift); break;
|
||||
- case 2: gen_helper_sar_cc(var, var, shift); break;
|
||||
- case 3: gen_helper_ror_cc(var, var, shift); break;
|
||||
+ case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
|
||||
+ case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
|
||||
+ case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
|
||||
+ case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
|
||||
}
|
||||
} else {
|
||||
switch (shiftop) {
|
||||
- case 0: gen_helper_shl(var, var, shift); break;
|
||||
- case 1: gen_helper_shr(var, var, shift); break;
|
||||
- case 2: gen_helper_sar(var, var, shift); break;
|
||||
+ case 0: gen_helper_shl(var, cpu_env, var, shift); break;
|
||||
+ case 1: gen_helper_shr(var, cpu_env, var, shift); break;
|
||||
+ case 2: gen_helper_sar(var, cpu_env, var, shift); break;
|
||||
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
|
||||
tcg_gen_rotr_i32(var, var, shift); break;
|
||||
}
|
||||
@@ -6121,7 +6121,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
|
||||
tmp2 = neon_load_reg(rm, 0);
|
||||
tmp4 = tcg_const_i32(rn);
|
||||
tmp5 = tcg_const_i32(n);
|
||||
- gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
|
||||
+ gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
|
||||
tcg_temp_free_i32(tmp);
|
||||
if (insn & (1 << 6)) {
|
||||
tmp = neon_load_reg(rd, 1);
|
||||
@@ -6130,7 +6130,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
|
||||
tcg_gen_movi_i32(tmp, 0);
|
||||
}
|
||||
tmp3 = neon_load_reg(rm, 1);
|
||||
- gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
|
||||
+ gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
|
||||
tcg_temp_free_i32(tmp5);
|
||||
tcg_temp_free_i32(tmp4);
|
||||
neon_store_reg(rd, 0, tmp2);
|
||||
@@ -6818,7 +6818,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
tmp = load_cpu_field(spsr);
|
||||
} else {
|
||||
tmp = tcg_temp_new_i32();
|
||||
- gen_helper_cpsr_read(tmp);
|
||||
+ gen_helper_cpsr_read(tmp, cpu_env);
|
||||
}
|
||||
store_reg(s, rd, tmp);
|
||||
}
|
||||
@@ -6869,11 +6869,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
tmp = load_reg(s, rm);
|
||||
tmp2 = load_reg(s, rn);
|
||||
if (op1 & 2)
|
||||
- gen_helper_double_saturate(tmp2, tmp2);
|
||||
+ gen_helper_double_saturate(tmp2, cpu_env, tmp2);
|
||||
if (op1 & 1)
|
||||
- gen_helper_sub_saturate(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_add_saturate(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
@@ -6911,7 +6911,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
tcg_temp_free_i64(tmp64);
|
||||
if ((sh & 2) == 0) {
|
||||
tmp2 = load_reg(s, rn);
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
}
|
||||
store_reg(s, rd, tmp);
|
||||
@@ -6931,7 +6931,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
} else {
|
||||
if (op1 == 0) {
|
||||
tmp2 = load_reg(s, rn);
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
}
|
||||
store_reg(s, rd, tmp);
|
||||
@@ -7005,11 +7005,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
if (IS_USER(s)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
gen_exception_return(s, tmp);
|
||||
} else {
|
||||
if (set_cc) {
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
tcg_gen_sub_i32(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -7018,7 +7018,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
break;
|
||||
case 0x03:
|
||||
if (set_cc) {
|
||||
- gen_helper_sub_cc(tmp, tmp2, tmp);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
tcg_gen_sub_i32(tmp, tmp2, tmp);
|
||||
}
|
||||
@@ -7026,7 +7026,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
break;
|
||||
case 0x04:
|
||||
if (set_cc) {
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
tcg_gen_add_i32(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -7034,7 +7034,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
break;
|
||||
case 0x05:
|
||||
if (set_cc) {
|
||||
- gen_helper_adc_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
gen_add_carry(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -7042,7 +7042,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
break;
|
||||
case 0x06:
|
||||
if (set_cc) {
|
||||
- gen_helper_sbc_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
gen_sub_carry(tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -7050,7 +7050,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
break;
|
||||
case 0x07:
|
||||
if (set_cc) {
|
||||
- gen_helper_sbc_cc(tmp, tmp2, tmp);
|
||||
+ gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
gen_sub_carry(tmp, tmp2, tmp);
|
||||
}
|
||||
@@ -7072,13 +7072,13 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
break;
|
||||
case 0x0a:
|
||||
if (set_cc) {
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
tcg_temp_free_i32(tmp);
|
||||
break;
|
||||
case 0x0b:
|
||||
if (set_cc) {
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
tcg_temp_free_i32(tmp);
|
||||
break;
|
||||
@@ -7395,9 +7395,9 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
sh = (insn >> 16) & 0x1f;
|
||||
tmp2 = tcg_const_i32(sh);
|
||||
if (insn & (1 << 22))
|
||||
- gen_helper_usat(tmp, tmp, tmp2);
|
||||
+ gen_helper_usat(tmp, cpu_env, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_ssat(tmp, tmp, tmp2);
|
||||
+ gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
} else if ((insn & 0x00300fe0) == 0x00200f20) {
|
||||
@@ -7406,9 +7406,9 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
sh = (insn >> 16) & 0x1f;
|
||||
tmp2 = tcg_const_i32(sh);
|
||||
if (insn & (1 << 22))
|
||||
- gen_helper_usat16(tmp, tmp, tmp2);
|
||||
+ gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_ssat16(tmp, tmp, tmp2);
|
||||
+ gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
|
||||
@@ -7518,7 +7518,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
* however it may overflow considered as a signed
|
||||
* operation, in which case we must set the Q flag.
|
||||
*/
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
tcg_temp_free_i32(tmp2);
|
||||
if (insn & (1 << 22)) {
|
||||
@@ -7534,7 +7534,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
if (rd != 15)
|
||||
{
|
||||
tmp2 = load_reg(s, rd);
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
}
|
||||
store_reg(s, rn, tmp);
|
||||
@@ -7738,7 +7738,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
} else if (user) {
|
||||
tmp = tcg_temp_new_i32();
|
||||
tmp2 = tcg_const_i32(i);
|
||||
- gen_helper_get_user_reg(tmp, tmp2);
|
||||
+ gen_helper_get_user_reg(tmp, cpu_env, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
} else {
|
||||
tmp = load_reg(s, i);
|
||||
@@ -7865,31 +7865,31 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG
|
||||
break;
|
||||
case 8: /* add */
|
||||
if (conds)
|
||||
- gen_helper_add_cc(t0, t0, t1);
|
||||
+ gen_helper_add_cc(t0, cpu_env, t0, t1);
|
||||
else
|
||||
tcg_gen_add_i32(t0, t0, t1);
|
||||
break;
|
||||
case 10: /* adc */
|
||||
if (conds)
|
||||
- gen_helper_adc_cc(t0, t0, t1);
|
||||
+ gen_helper_adc_cc(t0, cpu_env, t0, t1);
|
||||
else
|
||||
gen_adc(t0, t1);
|
||||
break;
|
||||
case 11: /* sbc */
|
||||
if (conds)
|
||||
- gen_helper_sbc_cc(t0, t0, t1);
|
||||
+ gen_helper_sbc_cc(t0, cpu_env, t0, t1);
|
||||
else
|
||||
gen_sub_carry(t0, t0, t1);
|
||||
break;
|
||||
case 13: /* sub */
|
||||
if (conds)
|
||||
- gen_helper_sub_cc(t0, t0, t1);
|
||||
+ gen_helper_sub_cc(t0, cpu_env, t0, t1);
|
||||
else
|
||||
tcg_gen_sub_i32(t0, t0, t1);
|
||||
break;
|
||||
case 14: /* rsb */
|
||||
if (conds)
|
||||
- gen_helper_sub_cc(t0, t1, t0);
|
||||
+ gen_helper_sub_cc(t0, cpu_env, t1, t0);
|
||||
else
|
||||
tcg_gen_sub_i32(t0, t1, t0);
|
||||
break;
|
||||
@@ -8111,7 +8111,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
gen_st32(tmp, addr, 0);
|
||||
tcg_gen_addi_i32(addr, addr, 4);
|
||||
tmp = tcg_temp_new_i32();
|
||||
- gen_helper_cpsr_read(tmp);
|
||||
+ gen_helper_cpsr_read(tmp, cpu_env);
|
||||
gen_st32(tmp, addr, 0);
|
||||
if (insn & (1 << 21)) {
|
||||
if ((insn & (1 << 24)) == 0) {
|
||||
@@ -8293,11 +8293,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
tmp = load_reg(s, rn);
|
||||
tmp2 = load_reg(s, rm);
|
||||
if (op & 1)
|
||||
- gen_helper_double_saturate(tmp, tmp);
|
||||
+ gen_helper_double_saturate(tmp, cpu_env, tmp);
|
||||
if (op & 2)
|
||||
- gen_helper_sub_saturate(tmp, tmp2, tmp);
|
||||
+ gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
|
||||
else
|
||||
- gen_helper_add_saturate(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
} else {
|
||||
tmp = load_reg(s, rn);
|
||||
@@ -8353,7 +8353,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
tcg_temp_free_i32(tmp2);
|
||||
if (rs != 15) {
|
||||
tmp2 = load_reg(s, rs);
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
}
|
||||
break;
|
||||
@@ -8370,13 +8370,13 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
* however it may overflow considered as a signed
|
||||
* operation, in which case we must set the Q flag.
|
||||
*/
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
tcg_temp_free_i32(tmp2);
|
||||
if (rs != 15)
|
||||
{
|
||||
tmp2 = load_reg(s, rs);
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
}
|
||||
break;
|
||||
@@ -8393,7 +8393,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
if (rs != 15)
|
||||
{
|
||||
tmp2 = load_reg(s, rs);
|
||||
- gen_helper_add_setq(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
}
|
||||
break;
|
||||
@@ -8632,7 +8632,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
gen_helper_v7m_mrs(tmp, cpu_env, addr);
|
||||
tcg_temp_free_i32(addr);
|
||||
} else {
|
||||
- gen_helper_cpsr_read(tmp);
|
||||
+ gen_helper_cpsr_read(tmp, cpu_env);
|
||||
}
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
@@ -8721,15 +8721,15 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
if (op & 4) {
|
||||
/* Unsigned. */
|
||||
if ((op & 1) && shift == 0)
|
||||
- gen_helper_usat16(tmp, tmp, tmp2);
|
||||
+ gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_usat(tmp, tmp, tmp2);
|
||||
+ gen_helper_usat(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
/* Signed. */
|
||||
if ((op & 1) && shift == 0)
|
||||
- gen_helper_ssat16(tmp, tmp, tmp2);
|
||||
+ gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_ssat(tmp, tmp, tmp2);
|
||||
+ gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
tcg_temp_free_i32(tmp2);
|
||||
break;
|
||||
@@ -9017,12 +9017,12 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_sub_i32(tmp, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
} else {
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_add_i32(tmp, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
}
|
||||
tcg_temp_free_i32(tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
@@ -9053,7 +9053,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
tcg_gen_movi_i32(tmp2, insn & 0xff);
|
||||
switch (op) {
|
||||
case 1: /* cmp */
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
break;
|
||||
@@ -9061,7 +9061,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_add_i32(tmp, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
@@ -9069,7 +9069,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_sub_i32(tmp, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
@@ -9105,7 +9105,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
case 1: /* cmp */
|
||||
tmp = load_reg(s, rd);
|
||||
tmp2 = load_reg(s, rm);
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
tcg_temp_free_i32(tmp2);
|
||||
tcg_temp_free_i32(tmp);
|
||||
break;
|
||||
@@ -9166,25 +9166,25 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
break;
|
||||
case 0x2: /* lsl */
|
||||
if (s->condexec_mask) {
|
||||
- gen_helper_shl(tmp2, tmp2, tmp);
|
||||
+ gen_helper_shl(tmp2, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
- gen_helper_shl_cc(tmp2, tmp2, tmp);
|
||||
+ gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
|
||||
gen_logic_CC(tmp2);
|
||||
}
|
||||
break;
|
||||
case 0x3: /* lsr */
|
||||
if (s->condexec_mask) {
|
||||
- gen_helper_shr(tmp2, tmp2, tmp);
|
||||
+ gen_helper_shr(tmp2, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
- gen_helper_shr_cc(tmp2, tmp2, tmp);
|
||||
+ gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
|
||||
gen_logic_CC(tmp2);
|
||||
}
|
||||
break;
|
||||
case 0x4: /* asr */
|
||||
if (s->condexec_mask) {
|
||||
- gen_helper_sar(tmp2, tmp2, tmp);
|
||||
+ gen_helper_sar(tmp2, cpu_env, tmp2, tmp);
|
||||
} else {
|
||||
- gen_helper_sar_cc(tmp2, tmp2, tmp);
|
||||
+ gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
|
||||
gen_logic_CC(tmp2);
|
||||
}
|
||||
break;
|
||||
@@ -9192,20 +9192,20 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
if (s->condexec_mask)
|
||||
gen_adc(tmp, tmp2);
|
||||
else
|
||||
- gen_helper_adc_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
|
||||
break;
|
||||
case 0x6: /* sbc */
|
||||
if (s->condexec_mask)
|
||||
gen_sub_carry(tmp, tmp, tmp2);
|
||||
else
|
||||
- gen_helper_sbc_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
|
||||
break;
|
||||
case 0x7: /* ror */
|
||||
if (s->condexec_mask) {
|
||||
tcg_gen_andi_i32(tmp, tmp, 0x1f);
|
||||
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
|
||||
} else {
|
||||
- gen_helper_ror_cc(tmp2, tmp2, tmp);
|
||||
+ gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
|
||||
gen_logic_CC(tmp2);
|
||||
}
|
||||
break;
|
||||
@@ -9218,14 +9218,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_neg_i32(tmp, tmp2);
|
||||
else
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
break;
|
||||
case 0xa: /* cmp */
|
||||
- gen_helper_sub_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
|
||||
rd = 16;
|
||||
break;
|
||||
case 0xb: /* cmn */
|
||||
- gen_helper_add_cc(tmp, tmp, tmp2);
|
||||
+ gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
|
||||
rd = 16;
|
||||
break;
|
||||
case 0xc: /* orr */
|
||||
--
|
||||
1.7.12.1
|
||||
|
179
0033-target-arm-final-conversion-to-AREG0-free-mode.patch
Normal file
179
0033-target-arm-final-conversion-to-AREG0-free-mode.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From 28b8f097f9fb107882aa51bd25ba87619beb033e Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Tue, 4 Sep 2012 20:25:59 +0000
|
||||
Subject: [PATCH] target-arm: final conversion to AREG0 free mode
|
||||
|
||||
Convert code load functions and switch to AREG0 free mode.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 2 +-
|
||||
target-arm/Makefile.objs | 2 --
|
||||
target-arm/cpu.h | 10 ++++++----
|
||||
target-arm/helper.c | 9 +++++----
|
||||
target-arm/op_helper.c | 8 +-------
|
||||
target-arm/translate.c | 6 +++---
|
||||
6 files changed, 16 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index a8827ba..e8806f0 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
|
||||
|
||||
|
||||
case "$target_arch2" in
|
||||
- alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
|
||||
+ alpha | arm* | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
|
||||
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
|
||||
;;
|
||||
esac
|
||||
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
|
||||
index f447c4f..b6f1a9e 100644
|
||||
--- a/target-arm/Makefile.objs
|
||||
+++ b/target-arm/Makefile.objs
|
||||
@@ -2,5 +2,3 @@ obj-y += arm-semi.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-y += neon_helper.o iwmmxt_helper.o
|
||||
-
|
||||
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
|
||||
index d7f93d9..7fac94f 100644
|
||||
--- a/target-arm/cpu.h
|
||||
+++ b/target-arm/cpu.h
|
||||
@@ -734,9 +734,10 @@ static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
|
||||
}
|
||||
|
||||
/* Load an instruction and return it in the standard little-endian order */
|
||||
-static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
|
||||
+static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
||||
+ bool do_swap)
|
||||
{
|
||||
- uint32_t insn = ldl_code(addr);
|
||||
+ uint32_t insn = cpu_ldl_code(env, addr);
|
||||
if (do_swap) {
|
||||
return bswap32(insn);
|
||||
}
|
||||
@@ -744,9 +745,10 @@ static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
|
||||
}
|
||||
|
||||
/* Ditto, for a halfword (Thumb) instruction */
|
||||
-static inline uint16_t arm_lduw_code(uint32_t addr, bool do_swap)
|
||||
+static inline uint16_t arm_lduw_code(CPUARMState *env, uint32_t addr,
|
||||
+ bool do_swap)
|
||||
{
|
||||
- uint16_t insn = lduw_code(addr);
|
||||
+ uint16_t insn = cpu_lduw_code(env, addr);
|
||||
if (do_swap) {
|
||||
return bswap16(insn);
|
||||
}
|
||||
diff --git a/target-arm/helper.c b/target-arm/helper.c
|
||||
index e27df96..58340bd 100644
|
||||
--- a/target-arm/helper.c
|
||||
+++ b/target-arm/helper.c
|
||||
@@ -1756,7 +1756,7 @@ static void do_interrupt_v7m(CPUARMState *env)
|
||||
case EXCP_BKPT:
|
||||
if (semihosting_enabled) {
|
||||
int nr;
|
||||
- nr = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
|
||||
+ nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
|
||||
if (nr == 0xab) {
|
||||
env->regs[15] += 2;
|
||||
env->regs[0] = do_arm_semihosting(env);
|
||||
@@ -1828,9 +1828,10 @@ void do_interrupt(CPUARMState *env)
|
||||
if (semihosting_enabled) {
|
||||
/* Check for semihosting interrupt. */
|
||||
if (env->thumb) {
|
||||
- mask = arm_lduw_code(env->regs[15] - 2, env->bswap_code) & 0xff;
|
||||
+ mask = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code)
|
||||
+ & 0xff;
|
||||
} else {
|
||||
- mask = arm_ldl_code(env->regs[15] - 4, env->bswap_code)
|
||||
+ mask = arm_ldl_code(env, env->regs[15] - 4, env->bswap_code)
|
||||
& 0xffffff;
|
||||
}
|
||||
/* Only intercept calls from privileged modes, to provide some
|
||||
@@ -1851,7 +1852,7 @@ void do_interrupt(CPUARMState *env)
|
||||
case EXCP_BKPT:
|
||||
/* See if this is a semihosting syscall. */
|
||||
if (env->thumb && semihosting_enabled) {
|
||||
- mask = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
|
||||
+ mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
|
||||
if (mask == 0xab
|
||||
&& (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
|
||||
env->regs[15] += 2;
|
||||
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
|
||||
index 5b868bf..f13fc3a 100644
|
||||
--- a/target-arm/op_helper.c
|
||||
+++ b/target-arm/op_helper.c
|
||||
@@ -17,7 +17,6 @@
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "helper.h"
|
||||
|
||||
#define SIGNBIT (uint32_t)0x80000000
|
||||
@@ -72,16 +71,12 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
|
||||
/* try to fill the TLB and return an exception if error. If retaddr is
|
||||
NULL, it means that the function was called in C code (i.e. not
|
||||
from generated code or from helper.c) */
|
||||
-/* XXX: fix it to restore all registers */
|
||||
-void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
+void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
|
||||
uintptr_t retaddr)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
- CPUARMState *saved_env;
|
||||
int ret;
|
||||
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);
|
||||
if (unlikely(ret)) {
|
||||
if (retaddr) {
|
||||
@@ -95,7 +90,6 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
}
|
||||
raise_exception(env, env->exception_index);
|
||||
}
|
||||
- env = saved_env;
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/target-arm/translate.c b/target-arm/translate.c
|
||||
index 9ae3b26..f4b447a 100644
|
||||
--- a/target-arm/translate.c
|
||||
+++ b/target-arm/translate.c
|
||||
@@ -6534,7 +6534,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
|
||||
TCGv addr;
|
||||
TCGv_i64 tmp64;
|
||||
|
||||
- insn = arm_ldl_code(s->pc, s->bswap_code);
|
||||
+ insn = arm_ldl_code(env, s->pc, s->bswap_code);
|
||||
s->pc += 4;
|
||||
|
||||
/* M variants do not implement ARM mode. */
|
||||
@@ -7962,7 +7962,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
/* Fall through to 32-bit decode. */
|
||||
}
|
||||
|
||||
- insn = arm_lduw_code(s->pc, s->bswap_code);
|
||||
+ insn = arm_lduw_code(env, s->pc, s->bswap_code);
|
||||
s->pc += 2;
|
||||
insn |= (uint32_t)insn_hw1 << 16;
|
||||
|
||||
@@ -8992,7 +8992,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
- insn = arm_lduw_code(s->pc, s->bswap_code);
|
||||
+ insn = arm_lduw_code(env, s->pc, s->bswap_code);
|
||||
s->pc += 2;
|
||||
|
||||
switch (insn >> 12) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
715
0034-target-microblaze-switch-to-AREG0-free-mode.patch
Normal file
715
0034-target-microblaze-switch-to-AREG0-free-mode.patch
Normal file
@ -0,0 +1,715 @@
|
||||
From 449d4f2cfbdd2b5fd00e3e82c78bf580bd81551d Mon Sep 17 00:00:00 2001
|
||||
From: Blue Swirl <blauwirbel@gmail.com>
|
||||
Date: Sun, 2 Sep 2012 08:39:22 +0000
|
||||
Subject: [PATCH] target-microblaze: switch to AREG0 free mode
|
||||
|
||||
Add an explicit CPUState parameter instead of relying on AREG0
|
||||
and switch to AREG0 free mode.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 2 +-
|
||||
target-microblaze/Makefile.objs | 2 -
|
||||
target-microblaze/helper.h | 48 ++++++++---------
|
||||
target-microblaze/op_helper.c | 115 ++++++++++++++++++----------------------
|
||||
target-microblaze/translate.c | 61 +++++++++++----------
|
||||
5 files changed, 110 insertions(+), 118 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index e8806f0..0b4ef4a 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
|
||||
|
||||
|
||||
case "$target_arch2" in
|
||||
- alpha | arm* | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
|
||||
+ alpha | arm* | i386 | lm32 | m68k | microblaze* | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
|
||||
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
|
||||
;;
|
||||
esac
|
||||
diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs
|
||||
index 4b09e8c..afb87bc 100644
|
||||
--- a/target-microblaze/Makefile.objs
|
||||
+++ b/target-microblaze/Makefile.objs
|
||||
@@ -1,4 +1,2 @@
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
|
||||
-
|
||||
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
|
||||
diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
|
||||
index 9dcfb0f..a1a732c 100644
|
||||
--- a/target-microblaze/helper.h
|
||||
+++ b/target-microblaze/helper.h
|
||||
@@ -1,39 +1,39 @@
|
||||
#include "def-helper.h"
|
||||
|
||||
-DEF_HELPER_1(raise_exception, void, i32)
|
||||
-DEF_HELPER_0(debug, void)
|
||||
+DEF_HELPER_2(raise_exception, void, env, i32)
|
||||
+DEF_HELPER_1(debug, void, env)
|
||||
DEF_HELPER_FLAGS_3(carry, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32, i32, i32)
|
||||
DEF_HELPER_2(cmp, i32, i32, i32)
|
||||
DEF_HELPER_2(cmpu, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(clz, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32)
|
||||
|
||||
-DEF_HELPER_2(divs, i32, i32, i32)
|
||||
-DEF_HELPER_2(divu, i32, i32, i32)
|
||||
-
|
||||
-DEF_HELPER_2(fadd, i32, i32, i32)
|
||||
-DEF_HELPER_2(frsub, i32, i32, i32)
|
||||
-DEF_HELPER_2(fmul, i32, i32, i32)
|
||||
-DEF_HELPER_2(fdiv, i32, i32, i32)
|
||||
-DEF_HELPER_1(flt, i32, i32)
|
||||
-DEF_HELPER_1(fint, i32, i32)
|
||||
-DEF_HELPER_1(fsqrt, i32, i32)
|
||||
-
|
||||
-DEF_HELPER_2(fcmp_un, i32, i32, i32)
|
||||
-DEF_HELPER_2(fcmp_lt, i32, i32, i32)
|
||||
-DEF_HELPER_2(fcmp_eq, i32, i32, i32)
|
||||
-DEF_HELPER_2(fcmp_le, i32, i32, i32)
|
||||
-DEF_HELPER_2(fcmp_gt, i32, i32, i32)
|
||||
-DEF_HELPER_2(fcmp_ne, i32, i32, i32)
|
||||
-DEF_HELPER_2(fcmp_ge, i32, i32, i32)
|
||||
+DEF_HELPER_3(divs, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(divu, i32, env, i32, i32)
|
||||
+
|
||||
+DEF_HELPER_3(fadd, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(frsub, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fmul, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fdiv, i32, env, i32, i32)
|
||||
+DEF_HELPER_2(flt, i32, env, i32)
|
||||
+DEF_HELPER_2(fint, i32, env, i32)
|
||||
+DEF_HELPER_2(fsqrt, i32, env, i32)
|
||||
+
|
||||
+DEF_HELPER_3(fcmp_un, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fcmp_lt, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fcmp_eq, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fcmp_le, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fcmp_gt, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fcmp_ne, i32, env, i32, i32)
|
||||
+DEF_HELPER_3(fcmp_ge, i32, env, i32, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_2(pcmpbf, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32, i32)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
-DEF_HELPER_1(mmu_read, i32, i32)
|
||||
-DEF_HELPER_2(mmu_write, void, i32, i32)
|
||||
+DEF_HELPER_2(mmu_read, i32, env, i32)
|
||||
+DEF_HELPER_3(mmu_write, void, env, i32, i32)
|
||||
#endif
|
||||
|
||||
-DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
|
||||
-DEF_HELPER_1(stackprot, void, i32)
|
||||
+DEF_HELPER_5(memalign, void, env, i32, i32, i32, i32)
|
||||
+DEF_HELPER_2(stackprot, void, env, i32)
|
||||
|
||||
DEF_HELPER_2(get, i32, i32, i32)
|
||||
DEF_HELPER_3(put, void, i32, i32, i32)
|
||||
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
|
||||
index 3b1f072..c9789f4 100644
|
||||
--- a/target-microblaze/op_helper.c
|
||||
+++ b/target-microblaze/op_helper.c
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include "cpu.h"
|
||||
-#include "dyngen-exec.h"
|
||||
#include "helper.h"
|
||||
#include "host-utils.h"
|
||||
|
||||
@@ -42,17 +41,12 @@
|
||||
/* Try to fill the TLB and return an exception if error. If retaddr is
|
||||
NULL, it means that the function was called in C code (i.e. not
|
||||
from generated code or from helper.c) */
|
||||
-/* XXX: fix it to restore all registers */
|
||||
-void tlb_fill(CPUMBState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
+void tlb_fill(CPUMBState *env, target_ulong addr, int is_write, int mmu_idx,
|
||||
uintptr_t retaddr)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
- CPUMBState *saved_env;
|
||||
int ret;
|
||||
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
-
|
||||
ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx);
|
||||
if (unlikely(ret)) {
|
||||
if (retaddr) {
|
||||
@@ -66,7 +60,6 @@ void tlb_fill(CPUMBState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
}
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
- env = saved_env;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -105,13 +98,13 @@ uint32_t helper_get(uint32_t id, uint32_t ctrl)
|
||||
return 0xdead0000 | id;
|
||||
}
|
||||
|
||||
-void helper_raise_exception(uint32_t index)
|
||||
+void helper_raise_exception(CPUMBState *env, uint32_t index)
|
||||
{
|
||||
env->exception_index = index;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void helper_debug(void)
|
||||
+void helper_debug(CPUMBState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -176,7 +169,7 @@ uint32_t helper_carry(uint32_t a, uint32_t b, uint32_t cf)
|
||||
return ncf;
|
||||
}
|
||||
|
||||
-static inline int div_prepare(uint32_t a, uint32_t b)
|
||||
+static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
if (b == 0) {
|
||||
env->sregs[SR_MSR] |= MSR_DZ;
|
||||
@@ -184,7 +177,7 @@ static inline int div_prepare(uint32_t a, uint32_t b)
|
||||
if ((env->sregs[SR_MSR] & MSR_EE)
|
||||
&& !(env->pvr.regs[2] & PVR2_DIV_ZERO_EXC_MASK)) {
|
||||
env->sregs[SR_ESR] = ESR_EC_DIVZERO;
|
||||
- helper_raise_exception(EXCP_HW_EXCP);
|
||||
+ helper_raise_exception(env, EXCP_HW_EXCP);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -192,28 +185,30 @@ static inline int div_prepare(uint32_t a, uint32_t b)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-uint32_t helper_divs(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
- if (!div_prepare(a, b))
|
||||
+ if (!div_prepare(env, a, b)) {
|
||||
return 0;
|
||||
+ }
|
||||
return (int32_t)a / (int32_t)b;
|
||||
}
|
||||
|
||||
-uint32_t helper_divu(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
- if (!div_prepare(a, b))
|
||||
+ if (!div_prepare(env, a, b)) {
|
||||
return 0;
|
||||
+ }
|
||||
return a / b;
|
||||
}
|
||||
|
||||
/* raise FPU exception. */
|
||||
-static void raise_fpu_exception(void)
|
||||
+static void raise_fpu_exception(CPUMBState *env)
|
||||
{
|
||||
env->sregs[SR_ESR] = ESR_EC_FPU;
|
||||
- helper_raise_exception(EXCP_HW_EXCP);
|
||||
+ helper_raise_exception(env, EXCP_HW_EXCP);
|
||||
}
|
||||
|
||||
-static void update_fpu_flags(int flags)
|
||||
+static void update_fpu_flags(CPUMBState *env, int flags)
|
||||
{
|
||||
int raise = 0;
|
||||
|
||||
@@ -236,11 +231,11 @@ static void update_fpu_flags(int flags)
|
||||
if (raise
|
||||
&& (env->pvr.regs[2] & PVR2_FPU_EXC_MASK)
|
||||
&& (env->sregs[SR_MSR] & MSR_EE)) {
|
||||
- raise_fpu_exception();
|
||||
+ raise_fpu_exception(env);
|
||||
}
|
||||
}
|
||||
|
||||
-uint32_t helper_fadd(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fadd(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fd, fa, fb;
|
||||
int flags;
|
||||
@@ -251,11 +246,11 @@ uint32_t helper_fadd(uint32_t a, uint32_t b)
|
||||
fd.f = float32_add(fa.f, fb.f, &env->fp_status);
|
||||
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags);
|
||||
+ update_fpu_flags(env, flags);
|
||||
return fd.l;
|
||||
}
|
||||
|
||||
-uint32_t helper_frsub(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_frsub(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fd, fa, fb;
|
||||
int flags;
|
||||
@@ -265,11 +260,11 @@ uint32_t helper_frsub(uint32_t a, uint32_t b)
|
||||
fb.l = b;
|
||||
fd.f = float32_sub(fb.f, fa.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags);
|
||||
+ update_fpu_flags(env, flags);
|
||||
return fd.l;
|
||||
}
|
||||
|
||||
-uint32_t helper_fmul(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fmul(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fd, fa, fb;
|
||||
int flags;
|
||||
@@ -279,12 +274,12 @@ uint32_t helper_fmul(uint32_t a, uint32_t b)
|
||||
fb.l = b;
|
||||
fd.f = float32_mul(fa.f, fb.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags);
|
||||
+ update_fpu_flags(env, flags);
|
||||
|
||||
return fd.l;
|
||||
}
|
||||
|
||||
-uint32_t helper_fdiv(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fd, fa, fb;
|
||||
int flags;
|
||||
@@ -294,12 +289,12 @@ uint32_t helper_fdiv(uint32_t a, uint32_t b)
|
||||
fb.l = b;
|
||||
fd.f = float32_div(fb.f, fa.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags);
|
||||
+ update_fpu_flags(env, flags);
|
||||
|
||||
return fd.l;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_un(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
uint32_t r = 0;
|
||||
@@ -308,7 +303,7 @@ uint32_t helper_fcmp_un(uint32_t a, uint32_t b)
|
||||
fb.l = b;
|
||||
|
||||
if (float32_is_signaling_nan(fa.f) || float32_is_signaling_nan(fb.f)) {
|
||||
- update_fpu_flags(float_flag_invalid);
|
||||
+ update_fpu_flags(env, float_flag_invalid);
|
||||
r = 1;
|
||||
}
|
||||
|
||||
@@ -319,7 +314,7 @@ uint32_t helper_fcmp_un(uint32_t a, uint32_t b)
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_lt(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_lt(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
int r;
|
||||
@@ -330,12 +325,12 @@ uint32_t helper_fcmp_lt(uint32_t a, uint32_t b)
|
||||
fb.l = b;
|
||||
r = float32_lt(fb.f, fa.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags & float_flag_invalid);
|
||||
+ update_fpu_flags(env, flags & float_flag_invalid);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_eq(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
int flags;
|
||||
@@ -346,12 +341,12 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
|
||||
fb.l = b;
|
||||
r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags & float_flag_invalid);
|
||||
+ update_fpu_flags(env, flags & float_flag_invalid);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_le(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_le(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
int flags;
|
||||
@@ -362,13 +357,13 @@ uint32_t helper_fcmp_le(uint32_t a, uint32_t b)
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
r = float32_le(fa.f, fb.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags & float_flag_invalid);
|
||||
+ update_fpu_flags(env, flags & float_flag_invalid);
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_gt(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_gt(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
int flags, r;
|
||||
@@ -378,11 +373,11 @@ uint32_t helper_fcmp_gt(uint32_t a, uint32_t b)
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
r = float32_lt(fa.f, fb.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags & float_flag_invalid);
|
||||
+ update_fpu_flags(env, flags & float_flag_invalid);
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_ne(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
int flags, r;
|
||||
@@ -392,12 +387,12 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags & float_flag_invalid);
|
||||
+ update_fpu_flags(env, flags & float_flag_invalid);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fcmp_ge(uint32_t a, uint32_t b)
|
||||
+uint32_t helper_fcmp_ge(CPUMBState *env, uint32_t a, uint32_t b)
|
||||
{
|
||||
CPU_FloatU fa, fb;
|
||||
int flags, r;
|
||||
@@ -407,12 +402,12 @@ uint32_t helper_fcmp_ge(uint32_t a, uint32_t b)
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
r = !float32_lt(fa.f, fb.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags & float_flag_invalid);
|
||||
+ update_fpu_flags(env, flags & float_flag_invalid);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_flt(uint32_t a)
|
||||
+uint32_t helper_flt(CPUMBState *env, uint32_t a)
|
||||
{
|
||||
CPU_FloatU fd, fa;
|
||||
|
||||
@@ -421,7 +416,7 @@ uint32_t helper_flt(uint32_t a)
|
||||
return fd.l;
|
||||
}
|
||||
|
||||
-uint32_t helper_fint(uint32_t a)
|
||||
+uint32_t helper_fint(CPUMBState *env, uint32_t a)
|
||||
{
|
||||
CPU_FloatU fa;
|
||||
uint32_t r;
|
||||
@@ -431,12 +426,12 @@ uint32_t helper_fint(uint32_t a)
|
||||
fa.l = a;
|
||||
r = float32_to_int32(fa.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags);
|
||||
+ update_fpu_flags(env, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
-uint32_t helper_fsqrt(uint32_t a)
|
||||
+uint32_t helper_fsqrt(CPUMBState *env, uint32_t a)
|
||||
{
|
||||
CPU_FloatU fd, fa;
|
||||
int flags;
|
||||
@@ -445,7 +440,7 @@ uint32_t helper_fsqrt(uint32_t a)
|
||||
fa.l = a;
|
||||
fd.l = float32_sqrt(fa.f, &env->fp_status);
|
||||
flags = get_float_exception_flags(&env->fp_status);
|
||||
- update_fpu_flags(flags);
|
||||
+ update_fpu_flags(env, flags);
|
||||
|
||||
return fd.l;
|
||||
}
|
||||
@@ -463,7 +458,8 @@ uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
|
||||
+void helper_memalign(CPUMBState *env, uint32_t addr, uint32_t dr, uint32_t wr,
|
||||
+ uint32_t mask)
|
||||
{
|
||||
if (addr & mask) {
|
||||
qemu_log_mask(CPU_LOG_INT,
|
||||
@@ -478,45 +474,39 @@ void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
|
||||
if (!(env->sregs[SR_MSR] & MSR_EE)) {
|
||||
return;
|
||||
}
|
||||
- helper_raise_exception(EXCP_HW_EXCP);
|
||||
+ helper_raise_exception(env, EXCP_HW_EXCP);
|
||||
}
|
||||
}
|
||||
|
||||
-void helper_stackprot(uint32_t addr)
|
||||
+void helper_stackprot(CPUMBState *env, uint32_t addr)
|
||||
{
|
||||
if (addr < env->slr || addr > env->shr) {
|
||||
qemu_log("Stack protector violation at %x %x %x\n",
|
||||
addr, env->slr, env->shr);
|
||||
env->sregs[SR_EAR] = addr;
|
||||
env->sregs[SR_ESR] = ESR_EC_STACKPROT;
|
||||
- helper_raise_exception(EXCP_HW_EXCP);
|
||||
+ helper_raise_exception(env, EXCP_HW_EXCP);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* Writes/reads to the MMU's special regs end up here. */
|
||||
-uint32_t helper_mmu_read(uint32_t rn)
|
||||
+uint32_t helper_mmu_read(CPUMBState *env, uint32_t rn)
|
||||
{
|
||||
return mmu_read(env, rn);
|
||||
}
|
||||
|
||||
-void helper_mmu_write(uint32_t rn, uint32_t v)
|
||||
+void helper_mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
|
||||
{
|
||||
mmu_write(env, rn, v);
|
||||
}
|
||||
|
||||
-void cpu_unassigned_access(CPUMBState *env1, target_phys_addr_t addr,
|
||||
+void cpu_unassigned_access(CPUMBState *env, target_phys_addr_t addr,
|
||||
int is_write, int is_exec, int is_asi, int size)
|
||||
{
|
||||
- CPUMBState *saved_env;
|
||||
-
|
||||
- saved_env = env;
|
||||
- env = env1;
|
||||
-
|
||||
qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
|
||||
addr, is_write, is_exec);
|
||||
if (!(env->sregs[SR_MSR] & MSR_EE)) {
|
||||
- env = saved_env;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -524,14 +514,13 @@ void cpu_unassigned_access(CPUMBState *env1, target_phys_addr_t addr,
|
||||
if (is_exec) {
|
||||
if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
|
||||
env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
|
||||
- helper_raise_exception(EXCP_HW_EXCP);
|
||||
+ helper_raise_exception(env, EXCP_HW_EXCP);
|
||||
}
|
||||
} else {
|
||||
if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
|
||||
env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
|
||||
- helper_raise_exception(EXCP_HW_EXCP);
|
||||
+ helper_raise_exception(env, EXCP_HW_EXCP);
|
||||
}
|
||||
}
|
||||
- env = saved_env;
|
||||
}
|
||||
#endif
|
||||
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
|
||||
index 7470149..9c7d77f 100644
|
||||
--- a/target-microblaze/translate.c
|
||||
+++ b/target-microblaze/translate.c
|
||||
@@ -126,7 +126,7 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
|
||||
|
||||
t_sync_flags(dc);
|
||||
tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
|
||||
- gen_helper_raise_exception(tmp);
|
||||
+ gen_helper_raise_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
dc->is_jmp = DISAS_UPDATE;
|
||||
}
|
||||
@@ -503,9 +503,9 @@ static void dec_msr(DisasContext *dc)
|
||||
sr &= 7;
|
||||
LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
|
||||
if (to)
|
||||
- gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]);
|
||||
+ gen_helper_mmu_write(cpu_env, tcg_const_tl(sr), cpu_R[dc->ra]);
|
||||
else
|
||||
- gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr));
|
||||
+ gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tcg_const_tl(sr));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -704,9 +704,11 @@ static void dec_div(DisasContext *dc)
|
||||
}
|
||||
|
||||
if (u)
|
||||
- gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
|
||||
+ gen_helper_divu(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
|
||||
+ cpu_R[dc->ra]);
|
||||
else
|
||||
- gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
|
||||
+ gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
|
||||
+ cpu_R[dc->ra]);
|
||||
if (!dc->rd)
|
||||
tcg_gen_movi_tl(cpu_R[dc->rd], 0);
|
||||
}
|
||||
@@ -912,7 +914,7 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
|
||||
tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
|
||||
if (stackprot) {
|
||||
- gen_helper_stackprot(*t);
|
||||
+ gen_helper_stackprot(cpu_env, *t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@@ -930,7 +932,7 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
|
||||
}
|
||||
|
||||
if (stackprot) {
|
||||
- gen_helper_stackprot(*t);
|
||||
+ gen_helper_stackprot(cpu_env, *t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@@ -1056,7 +1058,7 @@ static void dec_load(DisasContext *dc)
|
||||
gen_load(dc, v, *addr, size);
|
||||
|
||||
tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
|
||||
- gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
|
||||
+ gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
|
||||
tcg_const_tl(0), tcg_const_tl(size - 1));
|
||||
if (dc->rd) {
|
||||
if (rev) {
|
||||
@@ -1218,7 +1220,7 @@ static void dec_store(DisasContext *dc)
|
||||
* the alignment checks in between the probe and the mem
|
||||
* access.
|
||||
*/
|
||||
- gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
|
||||
+ gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
|
||||
tcg_const_tl(1), tcg_const_tl(size - 1));
|
||||
}
|
||||
|
||||
@@ -1493,49 +1495,53 @@ static void dec_fpu(DisasContext *dc)
|
||||
|
||||
switch (fpu_insn) {
|
||||
case 0:
|
||||
- gen_helper_fadd(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
+ gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
|
||||
+ cpu_R[dc->rb]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
- gen_helper_frsub(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
+ gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
|
||||
+ cpu_R[dc->rb]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
- gen_helper_fmul(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
+ gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
|
||||
+ cpu_R[dc->rb]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
- gen_helper_fdiv(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
+ gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
|
||||
+ cpu_R[dc->rb]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
switch ((dc->ir >> 4) & 7) {
|
||||
case 0:
|
||||
- gen_helper_fcmp_un(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 1:
|
||||
- gen_helper_fcmp_lt(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 2:
|
||||
- gen_helper_fcmp_eq(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 3:
|
||||
- gen_helper_fcmp_le(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 4:
|
||||
- gen_helper_fcmp_gt(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 5:
|
||||
- gen_helper_fcmp_ne(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
case 6:
|
||||
- gen_helper_fcmp_ge(cpu_R[dc->rd],
|
||||
+ gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
|
||||
cpu_R[dc->ra], cpu_R[dc->rb]);
|
||||
break;
|
||||
default:
|
||||
@@ -1552,21 +1558,21 @@ static void dec_fpu(DisasContext *dc)
|
||||
if (!dec_check_fpuv2(dc)) {
|
||||
return;
|
||||
}
|
||||
- gen_helper_flt(cpu_R[dc->rd], cpu_R[dc->ra]);
|
||||
+ gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (!dec_check_fpuv2(dc)) {
|
||||
return;
|
||||
}
|
||||
- gen_helper_fint(cpu_R[dc->rd], cpu_R[dc->ra]);
|
||||
+ gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (!dec_check_fpuv2(dc)) {
|
||||
return;
|
||||
}
|
||||
- gen_helper_fsqrt(cpu_R[dc->rd], cpu_R[dc->ra]);
|
||||
+ gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1654,15 +1660,14 @@ static struct decoder_info {
|
||||
{{0, 0}, dec_null}
|
||||
};
|
||||
|
||||
-static inline void decode(DisasContext *dc)
|
||||
+static inline void decode(DisasContext *dc, uint32_t ir)
|
||||
{
|
||||
- uint32_t ir;
|
||||
int i;
|
||||
|
||||
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
|
||||
tcg_gen_debug_insn_start(dc->pc);
|
||||
|
||||
- dc->ir = ir = ldl_code(dc->pc);
|
||||
+ dc->ir = ir;
|
||||
LOG_DIS("%8.8x\t", dc->ir);
|
||||
|
||||
if (dc->ir)
|
||||
@@ -1796,7 +1801,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
|
||||
gen_io_start();
|
||||
|
||||
dc->clear_imm = 1;
|
||||
- decode(dc);
|
||||
+ decode(dc, cpu_ldl_code(env, dc->pc));
|
||||
if (dc->clear_imm)
|
||||
dc->tb_flags &= ~IMM_FLAG;
|
||||
dc->pc += 4;
|
||||
@@ -1871,7 +1876,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
|
||||
if (dc->is_jmp != DISAS_JUMP) {
|
||||
tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
|
||||
}
|
||||
- gen_helper_raise_exception(tmp);
|
||||
+ gen_helper_raise_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
} else {
|
||||
switch(dc->is_jmp) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
523
0035-target-cris-Avoid-AREG0-for-helpers.patch
Normal file
523
0035-target-cris-Avoid-AREG0-for-helpers.patch
Normal file
@ -0,0 +1,523 @@
|
||||
From 1e3916b0cbfd39cb3fc8996423d5574068583145 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Thu, 30 Aug 2012 16:56:39 +0200
|
||||
Subject: [PATCH] target-cris: Avoid AREG0 for helpers
|
||||
|
||||
Add an explicit CPUCRISState parameter instead of relying on AREG0.
|
||||
|
||||
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-cris/helper.h | 37 +++++++++++----------
|
||||
target-cris/op_helper.c | 80 ++++++++++++++++++++++++---------------------
|
||||
target-cris/translate.c | 44 +++++++++++++------------
|
||||
target-cris/translate_v10.c | 4 +--
|
||||
4 files changed, 88 insertions(+), 77 deletions(-)
|
||||
|
||||
diff --git a/target-cris/helper.h b/target-cris/helper.h
|
||||
index 093063a..99fb326 100644
|
||||
--- a/target-cris/helper.h
|
||||
+++ b/target-cris/helper.h
|
||||
@@ -1,26 +1,29 @@
|
||||
#include "def-helper.h"
|
||||
|
||||
-DEF_HELPER_1(raise_exception, void, i32)
|
||||
-DEF_HELPER_1(tlb_flush_pid, void, i32)
|
||||
-DEF_HELPER_1(spc_write, void, i32)
|
||||
+DEF_HELPER_2(raise_exception, void, env, i32)
|
||||
+DEF_HELPER_2(tlb_flush_pid, void, env, i32)
|
||||
+DEF_HELPER_2(spc_write, void, env, i32)
|
||||
DEF_HELPER_3(dump, void, i32, i32, i32)
|
||||
-DEF_HELPER_0(rfe, void);
|
||||
-DEF_HELPER_0(rfn, void);
|
||||
+DEF_HELPER_1(rfe, void, env);
|
||||
+DEF_HELPER_1(rfn, void, env);
|
||||
|
||||
-DEF_HELPER_2(movl_sreg_reg, void, i32, i32)
|
||||
-DEF_HELPER_2(movl_reg_sreg, void, i32, i32)
|
||||
+DEF_HELPER_3(movl_sreg_reg, void, env, i32, i32)
|
||||
+DEF_HELPER_3(movl_reg_sreg, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_1(lz, TCG_CALL_PURE, i32, i32);
|
||||
-DEF_HELPER_FLAGS_3(btst, TCG_CALL_PURE, i32, i32, i32, i32);
|
||||
+DEF_HELPER_FLAGS_4(btst, TCG_CALL_PURE, i32, env, i32, i32, i32);
|
||||
|
||||
-DEF_HELPER_FLAGS_3(evaluate_flags_muls, TCG_CALL_PURE, i32, i32, i32, i32)
|
||||
-DEF_HELPER_FLAGS_3(evaluate_flags_mulu, TCG_CALL_PURE, i32, i32, i32, i32)
|
||||
-DEF_HELPER_FLAGS_4(evaluate_flags_mcp, TCG_CALL_PURE, i32, i32, i32, i32, i32)
|
||||
-DEF_HELPER_FLAGS_4(evaluate_flags_alu_4, TCG_CALL_PURE, i32, i32, i32, i32, i32)
|
||||
-DEF_HELPER_FLAGS_4(evaluate_flags_sub_4, TCG_CALL_PURE, i32, i32, i32, i32, i32)
|
||||
-DEF_HELPER_FLAGS_2(evaluate_flags_move_4, TCG_CALL_PURE, i32, i32, i32)
|
||||
-DEF_HELPER_FLAGS_2(evaluate_flags_move_2, TCG_CALL_PURE, i32, i32, i32)
|
||||
-DEF_HELPER_0(evaluate_flags, void)
|
||||
-DEF_HELPER_0(top_evaluate_flags, void)
|
||||
+DEF_HELPER_FLAGS_4(evaluate_flags_muls, TCG_CALL_PURE, i32, env, i32, i32, i32)
|
||||
+DEF_HELPER_FLAGS_4(evaluate_flags_mulu, TCG_CALL_PURE, i32, env, i32, i32, i32)
|
||||
+DEF_HELPER_FLAGS_5(evaluate_flags_mcp, TCG_CALL_PURE, i32, env,
|
||||
+ i32, i32, i32, i32)
|
||||
+DEF_HELPER_FLAGS_5(evaluate_flags_alu_4, TCG_CALL_PURE, i32, env,
|
||||
+ i32, i32, i32, i32)
|
||||
+DEF_HELPER_FLAGS_5(evaluate_flags_sub_4, TCG_CALL_PURE, i32, env,
|
||||
+ i32, i32, i32, i32)
|
||||
+DEF_HELPER_FLAGS_3(evaluate_flags_move_4, TCG_CALL_PURE, i32, env, i32, i32)
|
||||
+DEF_HELPER_FLAGS_3(evaluate_flags_move_2, TCG_CALL_PURE, i32, env, i32, i32)
|
||||
+DEF_HELPER_1(evaluate_flags, void, env)
|
||||
+DEF_HELPER_1(top_evaluate_flags, void, env)
|
||||
|
||||
#include "def-helper.h"
|
||||
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
|
||||
index ac7c98c..5ca85a0 100644
|
||||
--- a/target-cris/op_helper.c
|
||||
+++ b/target-cris/op_helper.c
|
||||
@@ -79,7 +79,7 @@ void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
cpu_restore_state(tb, env, retaddr);
|
||||
|
||||
/* Evaluate flags after retranslation. */
|
||||
- helper_top_evaluate_flags();
|
||||
+ helper_top_evaluate_flags(env);
|
||||
}
|
||||
}
|
||||
cpu_loop_exit(env);
|
||||
@@ -89,13 +89,13 @@ void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
|
||||
#endif
|
||||
|
||||
-void helper_raise_exception(uint32_t index)
|
||||
+void helper_raise_exception(CPUCRISState *env, uint32_t index)
|
||||
{
|
||||
env->exception_index = index;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
-void helper_tlb_flush_pid(uint32_t pid)
|
||||
+void helper_tlb_flush_pid(CPUCRISState *env, uint32_t pid)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
pid &= 0xff;
|
||||
@@ -104,7 +104,7 @@ void helper_tlb_flush_pid(uint32_t pid)
|
||||
#endif
|
||||
}
|
||||
|
||||
-void helper_spc_write(uint32_t new_spc)
|
||||
+void helper_spc_write(CPUCRISState *env, uint32_t new_spc)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
tlb_flush_page(env, env->pregs[PR_SPC]);
|
||||
@@ -121,7 +121,7 @@ void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
|
||||
#define EXTRACT_FIELD(src, start, end) \
|
||||
(((src) >> start) & ((1 << (end - start + 1)) - 1))
|
||||
|
||||
-void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
|
||||
+void helper_movl_sreg_reg(CPUCRISState *env, uint32_t sreg, uint32_t reg)
|
||||
{
|
||||
uint32_t srs;
|
||||
srs = env->pregs[PR_SRS];
|
||||
@@ -171,7 +171,7 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
|
||||
#endif
|
||||
}
|
||||
|
||||
-void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
|
||||
+void helper_movl_reg_sreg(CPUCRISState *env, uint32_t reg, uint32_t sreg)
|
||||
{
|
||||
uint32_t srs;
|
||||
env->pregs[PR_SRS] &= 3;
|
||||
@@ -216,7 +216,7 @@ static void cris_ccs_rshift(CPUCRISState *env)
|
||||
env->pregs[PR_CCS] = ccs;
|
||||
}
|
||||
|
||||
-void helper_rfe(void)
|
||||
+void helper_rfe(CPUCRISState *env)
|
||||
{
|
||||
int rflag = env->pregs[PR_CCS] & R_FLAG;
|
||||
|
||||
@@ -232,7 +232,7 @@ void helper_rfe(void)
|
||||
env->pregs[PR_CCS] |= P_FLAG;
|
||||
}
|
||||
|
||||
-void helper_rfn(void)
|
||||
+void helper_rfn(CPUCRISState *env)
|
||||
{
|
||||
int rflag = env->pregs[PR_CCS] & R_FLAG;
|
||||
|
||||
@@ -256,7 +256,7 @@ uint32_t helper_lz(uint32_t t0)
|
||||
return clz32(t0);
|
||||
}
|
||||
|
||||
-uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
|
||||
+uint32_t helper_btst(CPUCRISState *env, uint32_t t0, uint32_t t1, uint32_t ccs)
|
||||
{
|
||||
/* FIXME: clean this up. */
|
||||
|
||||
@@ -284,7 +284,8 @@ uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
|
||||
return ccs;
|
||||
}
|
||||
|
||||
-static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs)
|
||||
+static inline uint32_t evaluate_flags_writeback(CPUCRISState *env,
|
||||
+ uint32_t flags, uint32_t ccs)
|
||||
{
|
||||
unsigned int x, z, mask;
|
||||
|
||||
@@ -303,7 +304,8 @@ static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs)
|
||||
return ccs;
|
||||
}
|
||||
|
||||
-uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof)
|
||||
+uint32_t helper_evaluate_flags_muls(CPUCRISState *env,
|
||||
+ uint32_t ccs, uint32_t res, uint32_t mof)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
int64_t tmp;
|
||||
@@ -321,10 +323,11 @@ uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof)
|
||||
if ((dneg && mof != -1)
|
||||
|| (!dneg && mof != 0))
|
||||
flags |= V_FLAG;
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
|
||||
-uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof)
|
||||
+uint32_t helper_evaluate_flags_mulu(CPUCRISState *env,
|
||||
+ uint32_t ccs, uint32_t res, uint32_t mof)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
uint64_t tmp;
|
||||
@@ -339,10 +342,10 @@ uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof)
|
||||
if (mof)
|
||||
flags |= V_FLAG;
|
||||
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
|
||||
-uint32_t helper_evaluate_flags_mcp(uint32_t ccs,
|
||||
+uint32_t helper_evaluate_flags_mcp(CPUCRISState *env, uint32_t ccs,
|
||||
uint32_t src, uint32_t dst, uint32_t res)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
@@ -368,10 +371,10 @@ uint32_t helper_evaluate_flags_mcp(uint32_t ccs,
|
||||
flags |= R_FLAG;
|
||||
}
|
||||
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
|
||||
-uint32_t helper_evaluate_flags_alu_4(uint32_t ccs,
|
||||
+uint32_t helper_evaluate_flags_alu_4(CPUCRISState *env, uint32_t ccs,
|
||||
uint32_t src, uint32_t dst, uint32_t res)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
@@ -397,10 +400,10 @@ uint32_t helper_evaluate_flags_alu_4(uint32_t ccs,
|
||||
flags |= C_FLAG;
|
||||
}
|
||||
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
|
||||
-uint32_t helper_evaluate_flags_sub_4(uint32_t ccs,
|
||||
+uint32_t helper_evaluate_flags_sub_4(CPUCRISState *env, uint32_t ccs,
|
||||
uint32_t src, uint32_t dst, uint32_t res)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
@@ -427,10 +430,11 @@ uint32_t helper_evaluate_flags_sub_4(uint32_t ccs,
|
||||
}
|
||||
|
||||
flags ^= C_FLAG;
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
|
||||
-uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res)
|
||||
+uint32_t helper_evaluate_flags_move_4(CPUCRISState *env,
|
||||
+ uint32_t ccs, uint32_t res)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
@@ -439,9 +443,10 @@ uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res)
|
||||
else if (res == 0L)
|
||||
flags |= Z_FLAG;
|
||||
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
-uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res)
|
||||
+uint32_t helper_evaluate_flags_move_2(CPUCRISState *env,
|
||||
+ uint32_t ccs, uint32_t res)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
@@ -450,12 +455,12 @@ uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res)
|
||||
else if (res == 0)
|
||||
flags |= Z_FLAG;
|
||||
|
||||
- return evaluate_flags_writeback(flags, ccs);
|
||||
+ return evaluate_flags_writeback(env, flags, ccs);
|
||||
}
|
||||
|
||||
/* TODO: This is expensive. We could split things up and only evaluate part of
|
||||
CCR on a need to know basis. For now, we simply re-evaluate everything. */
|
||||
-void helper_evaluate_flags(void)
|
||||
+void helper_evaluate_flags(CPUCRISState *env)
|
||||
{
|
||||
uint32_t src, dst, res;
|
||||
uint32_t flags = 0;
|
||||
@@ -571,25 +576,26 @@ void helper_evaluate_flags(void)
|
||||
if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
|
||||
flags ^= C_FLAG;
|
||||
|
||||
- env->pregs[PR_CCS] = evaluate_flags_writeback(flags, env->pregs[PR_CCS]);
|
||||
+ env->pregs[PR_CCS] = evaluate_flags_writeback(env, flags,
|
||||
+ env->pregs[PR_CCS]);
|
||||
}
|
||||
|
||||
-void helper_top_evaluate_flags(void)
|
||||
+void helper_top_evaluate_flags(CPUCRISState *env)
|
||||
{
|
||||
switch (env->cc_op)
|
||||
{
|
||||
case CC_OP_MCP:
|
||||
- env->pregs[PR_CCS] = helper_evaluate_flags_mcp(
|
||||
+ env->pregs[PR_CCS] = helper_evaluate_flags_mcp(env,
|
||||
env->pregs[PR_CCS], env->cc_src,
|
||||
env->cc_dest, env->cc_result);
|
||||
break;
|
||||
case CC_OP_MULS:
|
||||
- env->pregs[PR_CCS] = helper_evaluate_flags_muls(
|
||||
+ env->pregs[PR_CCS] = helper_evaluate_flags_muls(env,
|
||||
env->pregs[PR_CCS], env->cc_result,
|
||||
env->pregs[PR_MOF]);
|
||||
break;
|
||||
case CC_OP_MULU:
|
||||
- env->pregs[PR_CCS] = helper_evaluate_flags_mulu(
|
||||
+ env->pregs[PR_CCS] = helper_evaluate_flags_mulu(env,
|
||||
env->pregs[PR_CCS], env->cc_result,
|
||||
env->pregs[PR_MOF]);
|
||||
break;
|
||||
@@ -604,18 +610,18 @@ void helper_top_evaluate_flags(void)
|
||||
{
|
||||
case 4:
|
||||
env->pregs[PR_CCS] =
|
||||
- helper_evaluate_flags_move_4(
|
||||
+ helper_evaluate_flags_move_4(env,
|
||||
env->pregs[PR_CCS],
|
||||
env->cc_result);
|
||||
break;
|
||||
case 2:
|
||||
env->pregs[PR_CCS] =
|
||||
- helper_evaluate_flags_move_2(
|
||||
+ helper_evaluate_flags_move_2(env,
|
||||
env->pregs[PR_CCS],
|
||||
env->cc_result);
|
||||
break;
|
||||
default:
|
||||
- helper_evaluate_flags();
|
||||
+ helper_evaluate_flags(env);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -626,12 +632,12 @@ void helper_top_evaluate_flags(void)
|
||||
case CC_OP_CMP:
|
||||
if (env->cc_size == 4)
|
||||
env->pregs[PR_CCS] =
|
||||
- helper_evaluate_flags_sub_4(
|
||||
+ helper_evaluate_flags_sub_4(env,
|
||||
env->pregs[PR_CCS],
|
||||
env->cc_src, env->cc_dest,
|
||||
env->cc_result);
|
||||
else
|
||||
- helper_evaluate_flags();
|
||||
+ helper_evaluate_flags(env);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@@ -639,13 +645,13 @@ void helper_top_evaluate_flags(void)
|
||||
{
|
||||
case 4:
|
||||
env->pregs[PR_CCS] =
|
||||
- helper_evaluate_flags_alu_4(
|
||||
+ helper_evaluate_flags_alu_4(env,
|
||||
env->pregs[PR_CCS],
|
||||
env->cc_src, env->cc_dest,
|
||||
env->cc_result);
|
||||
break;
|
||||
default:
|
||||
- helper_evaluate_flags();
|
||||
+ helper_evaluate_flags(env);
|
||||
break;
|
||||
}
|
||||
}
|
||||
diff --git a/target-cris/translate.c b/target-cris/translate.c
|
||||
index ad31877..283dd98 100644
|
||||
--- a/target-cris/translate.c
|
||||
+++ b/target-cris/translate.c
|
||||
@@ -211,9 +211,9 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
|
||||
tcg_gen_andi_tl(cpu_PR[r], tn, 3);
|
||||
else {
|
||||
if (r == PR_PID)
|
||||
- gen_helper_tlb_flush_pid(tn);
|
||||
+ gen_helper_tlb_flush_pid(cpu_env, tn);
|
||||
if (dc->tb_flags & S_FLAG && r == PR_SPC)
|
||||
- gen_helper_spc_write(tn);
|
||||
+ gen_helper_spc_write(cpu_env, tn);
|
||||
else if (r == PR_CCS)
|
||||
dc->cpustate_changed = 1;
|
||||
tcg_gen_mov_tl(cpu_PR[r], tn);
|
||||
@@ -278,7 +278,7 @@ static void cris_lock_irq(DisasContext *dc)
|
||||
static inline void t_gen_raise_exception(uint32_t index)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_const_i32(index);
|
||||
- gen_helper_raise_exception(tmp);
|
||||
+ gen_helper_raise_exception(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
@@ -624,17 +624,17 @@ static void cris_evaluate_flags(DisasContext *dc)
|
||||
switch (dc->cc_op)
|
||||
{
|
||||
case CC_OP_MCP:
|
||||
- gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
|
||||
+ gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
|
||||
cpu_PR[PR_CCS], cc_src,
|
||||
cc_dest, cc_result);
|
||||
break;
|
||||
case CC_OP_MULS:
|
||||
- gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
|
||||
+ gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
|
||||
cpu_PR[PR_CCS], cc_result,
|
||||
cpu_PR[PR_MOF]);
|
||||
break;
|
||||
case CC_OP_MULU:
|
||||
- gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
|
||||
+ gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
|
||||
cpu_PR[PR_CCS], cc_result,
|
||||
cpu_PR[PR_MOF]);
|
||||
break;
|
||||
@@ -648,15 +648,15 @@ static void cris_evaluate_flags(DisasContext *dc)
|
||||
switch (dc->cc_size)
|
||||
{
|
||||
case 4:
|
||||
- gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
|
||||
- cpu_PR[PR_CCS], cc_result);
|
||||
+ gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
|
||||
+ cpu_env, cpu_PR[PR_CCS], cc_result);
|
||||
break;
|
||||
case 2:
|
||||
- gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
|
||||
- cpu_PR[PR_CCS], cc_result);
|
||||
+ gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
|
||||
+ cpu_env, cpu_PR[PR_CCS], cc_result);
|
||||
break;
|
||||
default:
|
||||
- gen_helper_evaluate_flags();
|
||||
+ gen_helper_evaluate_flags(cpu_env);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -666,21 +666,21 @@ static void cris_evaluate_flags(DisasContext *dc)
|
||||
case CC_OP_SUB:
|
||||
case CC_OP_CMP:
|
||||
if (dc->cc_size == 4)
|
||||
- gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
|
||||
+ gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
|
||||
cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
|
||||
else
|
||||
- gen_helper_evaluate_flags();
|
||||
+ gen_helper_evaluate_flags(cpu_env);
|
||||
|
||||
break;
|
||||
default:
|
||||
switch (dc->cc_size)
|
||||
{
|
||||
case 4:
|
||||
- gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
|
||||
+ gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
|
||||
cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
|
||||
break;
|
||||
default:
|
||||
- gen_helper_evaluate_flags();
|
||||
+ gen_helper_evaluate_flags(cpu_env);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1475,7 +1475,7 @@ static int dec_btstq(DisasContext *dc)
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
cris_evaluate_flags(dc);
|
||||
- gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
|
||||
+ gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
|
||||
tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
|
||||
cris_alu(dc, CC_OP_MOVE,
|
||||
cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
|
||||
@@ -1925,7 +1925,7 @@ static int dec_btst_r(DisasContext *dc)
|
||||
dc->op1, dc->op2);
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
cris_evaluate_flags(dc);
|
||||
- gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
|
||||
+ gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
|
||||
cpu_R[dc->op1], cpu_PR[PR_CCS]);
|
||||
cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
|
||||
cpu_R[dc->op2], cpu_R[dc->op2], 4);
|
||||
@@ -2135,14 +2135,16 @@ static int dec_move_rs(DisasContext *dc)
|
||||
{
|
||||
LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
|
||||
cris_cc_mask(dc, 0);
|
||||
- gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
|
||||
+ gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
|
||||
+ tcg_const_tl(dc->op1));
|
||||
return 2;
|
||||
}
|
||||
static int dec_move_sr(DisasContext *dc)
|
||||
{
|
||||
LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
|
||||
cris_cc_mask(dc, 0);
|
||||
- gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
|
||||
+ gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
|
||||
+ tcg_const_tl(dc->op2));
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -2906,14 +2908,14 @@ static int dec_rfe_etc(DisasContext *dc)
|
||||
/* rfe. */
|
||||
LOG_DIS("rfe\n");
|
||||
cris_evaluate_flags(dc);
|
||||
- gen_helper_rfe();
|
||||
+ gen_helper_rfe(cpu_env);
|
||||
dc->is_jmp = DISAS_UPDATE;
|
||||
break;
|
||||
case 5:
|
||||
/* rfn. */
|
||||
LOG_DIS("rfn\n");
|
||||
cris_evaluate_flags(dc);
|
||||
- gen_helper_rfn();
|
||||
+ gen_helper_rfn(cpu_env);
|
||||
dc->is_jmp = DISAS_UPDATE;
|
||||
break;
|
||||
case 6:
|
||||
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
|
||||
index 3629629..9a39c6a 100644
|
||||
--- a/target-cris/translate_v10.c
|
||||
+++ b/target-cris/translate_v10.c
|
||||
@@ -289,7 +289,7 @@ static unsigned int dec10_quick_imm(DisasContext *dc)
|
||||
} else {
|
||||
/* BTST */
|
||||
cris_update_cc_op(dc, CC_OP_FLAGS, 4);
|
||||
- gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
|
||||
+ gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst],
|
||||
tcg_const_tl(imm), cpu_PR[PR_CCS]);
|
||||
}
|
||||
break;
|
||||
@@ -723,7 +723,7 @@ static unsigned int dec10_reg(DisasContext *dc)
|
||||
LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
cris_update_cc_op(dc, CC_OP_FLAGS, 4);
|
||||
- gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
|
||||
+ gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst],
|
||||
cpu_R[dc->src], cpu_PR[PR_CCS]);
|
||||
break;
|
||||
case CRISV10_REG_DSTEP:
|
||||
--
|
||||
1.7.12.1
|
||||
|
1538
0036-target-cris-Switch-to-AREG0-free-mode.patch
Normal file
1538
0036-target-cris-Switch-to-AREG0-free-mode.patch
Normal file
File diff suppressed because it is too large
Load Diff
1060
0037-target-sh4-switch-to-AREG0-free-mode.patch
Normal file
1060
0037-target-sh4-switch-to-AREG0-free-mode.patch
Normal file
File diff suppressed because it is too large
Load Diff
6336
0038-target-mips-switch-to-AREG0-free-mode.patch
Normal file
6336
0038-target-mips-switch-to-AREG0-free-mode.patch
Normal file
File diff suppressed because it is too large
Load Diff
1683
0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch
Normal file
1683
0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch
Normal file
File diff suppressed because it is too large
Load Diff
114
0040-tcg-i386-allow-constants-in-load-store-ops.patch
Normal file
114
0040-tcg-i386-allow-constants-in-load-store-ops.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 83b25655bcd988054a2bb2a0a38dc662d4901b08 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Mon, 10 Sep 2012 13:56:24 +0200
|
||||
Subject: [PATCH] tcg/i386: allow constants in load/store ops
|
||||
|
||||
On x86, it is possible to move a constant value to memory. Add code to
|
||||
handle a constant argument to load/store ops.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/i386/tcg-target.c | 50 +++++++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 37 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
|
||||
index 34c2df8..3017858 100644
|
||||
--- a/tcg/i386/tcg-target.c
|
||||
+++ b/tcg/i386/tcg-target.c
|
||||
@@ -263,6 +263,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
|
||||
#define OPC_MOVB_EvGv (0x88) /* stores, more or less */
|
||||
#define OPC_MOVL_EvGv (0x89) /* stores, more or less */
|
||||
#define OPC_MOVL_GvEv (0x8b) /* loads, more or less */
|
||||
+#define OPC_MOVB_EvIz (0xc6)
|
||||
#define OPC_MOVL_EvIz (0xc7)
|
||||
#define OPC_MOVL_Iv (0xb8)
|
||||
#define OPC_MOVSBL (0xbe | P_EXT)
|
||||
@@ -1543,18 +1544,35 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
break;
|
||||
|
||||
OP_32_64(st8):
|
||||
- tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
|
||||
- args[0], args[1], args[2]);
|
||||
+ if (const_args[0]) {
|
||||
+ tcg_out_modrm_offset(s, OPC_MOVB_EvIz,
|
||||
+ 0, args[1], args[2]);
|
||||
+ tcg_out8(s, args[0]);
|
||||
+ } else {
|
||||
+ tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
|
||||
+ args[0], args[1], args[2]);
|
||||
+ }
|
||||
break;
|
||||
OP_32_64(st16):
|
||||
- tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
|
||||
- args[0], args[1], args[2]);
|
||||
+ if (const_args[0]) {
|
||||
+ tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16,
|
||||
+ 0, args[1], args[2]);
|
||||
+ tcg_out16(s, args[0]);
|
||||
+ } else {
|
||||
+ tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
|
||||
+ args[0], args[1], args[2]);
|
||||
+ }
|
||||
break;
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
case INDEX_op_st32_i64:
|
||||
#endif
|
||||
case INDEX_op_st_i32:
|
||||
- tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
|
||||
+ if (const_args[0]) {
|
||||
+ tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, args[1], args[2]);
|
||||
+ tcg_out32(s, args[0]);
|
||||
+ } else {
|
||||
+ tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
|
||||
+ }
|
||||
break;
|
||||
|
||||
OP_32_64(add):
|
||||
@@ -1758,7 +1776,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
|
||||
break;
|
||||
case INDEX_op_st_i64:
|
||||
- tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
|
||||
+ if (const_args[0]) {
|
||||
+ tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW,
|
||||
+ 0, args[1], args[2]);
|
||||
+ tcg_out32(s, args[0]);
|
||||
+ } else {
|
||||
+ tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
|
||||
+ }
|
||||
break;
|
||||
case INDEX_op_qemu_ld32s:
|
||||
tcg_out_qemu_ld(s, args, 2 | 4);
|
||||
@@ -1820,9 +1844,9 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
||||
{ INDEX_op_ld16u_i32, { "r", "r" } },
|
||||
{ INDEX_op_ld16s_i32, { "r", "r" } },
|
||||
{ INDEX_op_ld_i32, { "r", "r" } },
|
||||
- { INDEX_op_st8_i32, { "q", "r" } },
|
||||
- { INDEX_op_st16_i32, { "r", "r" } },
|
||||
- { INDEX_op_st_i32, { "r", "r" } },
|
||||
+ { INDEX_op_st8_i32, { "qi", "r" } },
|
||||
+ { INDEX_op_st16_i32, { "ri", "r" } },
|
||||
+ { INDEX_op_st_i32, { "ri", "r" } },
|
||||
|
||||
{ INDEX_op_add_i32, { "r", "r", "ri" } },
|
||||
{ INDEX_op_sub_i32, { "r", "0", "ri" } },
|
||||
@@ -1873,10 +1897,10 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
||||
{ INDEX_op_ld32u_i64, { "r", "r" } },
|
||||
{ INDEX_op_ld32s_i64, { "r", "r" } },
|
||||
{ INDEX_op_ld_i64, { "r", "r" } },
|
||||
- { INDEX_op_st8_i64, { "r", "r" } },
|
||||
- { INDEX_op_st16_i64, { "r", "r" } },
|
||||
- { INDEX_op_st32_i64, { "r", "r" } },
|
||||
- { INDEX_op_st_i64, { "r", "r" } },
|
||||
+ { INDEX_op_st8_i64, { "ri", "r" } },
|
||||
+ { INDEX_op_st16_i64, { "ri", "r" } },
|
||||
+ { INDEX_op_st32_i64, { "ri", "r" } },
|
||||
+ { INDEX_op_st_i64, { "re", "r" } },
|
||||
|
||||
{ INDEX_op_add_i64, { "r", "0", "re" } },
|
||||
{ INDEX_op_mul_i64, { "r", "0", "re" } },
|
||||
--
|
||||
1.7.12.1
|
||||
|
53
0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch
Normal file
53
0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 1610a0e56c0be3e4bfd3034e5323188b1d05badd Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Mon, 10 Sep 2012 14:23:49 +0200
|
||||
Subject: [PATCH] tcg: mark set_label with TCG_OPF_BB_END flag
|
||||
|
||||
set_label is effectively the end of a basic block, as no optimization
|
||||
can be made accross it. It was treated as such in the liveness analysis
|
||||
code, but as a special case.
|
||||
|
||||
Mark it with TCG_OPF_BB_END flag so that this information can be used
|
||||
by other parts of the TCG code, and remove the special case in the liveness
|
||||
analysis code.
|
||||
|
||||
Cc: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/tcg-opc.h | 2 +-
|
||||
tcg/tcg.c | 5 -----
|
||||
2 files changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
|
||||
index 8e06d03..d12e8d0 100644
|
||||
--- a/tcg/tcg-opc.h
|
||||
+++ b/tcg/tcg-opc.h
|
||||
@@ -36,7 +36,7 @@ DEF(nopn, 0, 0, 1, 0) /* variable number of parameters */
|
||||
|
||||
DEF(discard, 1, 0, 0, 0)
|
||||
|
||||
-DEF(set_label, 0, 0, 1, 0)
|
||||
+DEF(set_label, 0, 0, 1, TCG_OPF_BB_END)
|
||||
DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
|
||||
DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
|
||||
diff --git a/tcg/tcg.c b/tcg/tcg.c
|
||||
index 8386b70..c002a88 100644
|
||||
--- a/tcg/tcg.c
|
||||
+++ b/tcg/tcg.c
|
||||
@@ -1297,11 +1297,6 @@ static void tcg_liveness_analysis(TCGContext *s)
|
||||
args--;
|
||||
}
|
||||
break;
|
||||
- case INDEX_op_set_label:
|
||||
- args--;
|
||||
- /* mark end of basic block */
|
||||
- tcg_la_bb_end(s, dead_temps);
|
||||
- break;
|
||||
case INDEX_op_debug_insn_start:
|
||||
args -= def->nb_args;
|
||||
break;
|
||||
--
|
||||
1.7.12.1
|
||||
|
85
0042-revert-TCG-fix-copy-propagation.patch
Normal file
85
0042-revert-TCG-fix-copy-propagation.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 2b8d0049e88c17749ccb978509d3f8fda180d35f Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Mon, 10 Sep 2012 13:14:12 +0200
|
||||
Subject: [PATCH] revert "TCG: fix copy propagation"
|
||||
|
||||
Given the copy propagation breakage on 32-bit hosts has been fixed
|
||||
commit e31b0a7c050711884ad570fe73df806520953618 can be reverted.
|
||||
|
||||
Cc: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 15 ++++++---------
|
||||
tcg/tcg.h | 5 -----
|
||||
2 files changed, 6 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index fba0ed9..10d9773 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -107,15 +107,12 @@ static TCGOpcode op_to_movi(TCGOpcode op)
|
||||
}
|
||||
}
|
||||
|
||||
-static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst,
|
||||
- TCGArg src, int nb_temps, int nb_globals)
|
||||
+static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
|
||||
+ int nb_temps, int nb_globals)
|
||||
{
|
||||
reset_temp(dst, nb_temps, nb_globals);
|
||||
assert(temps[src].state != TCG_TEMP_COPY);
|
||||
- /* Don't try to copy if one of temps is a global or either one
|
||||
- is local and another is register */
|
||||
- if (src >= nb_globals && dst >= nb_globals &&
|
||||
- tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) {
|
||||
+ if (src >= nb_globals) {
|
||||
assert(temps[src].state != TCG_TEMP_CONST);
|
||||
if (temps[src].state != TCG_TEMP_HAS_COPY) {
|
||||
temps[src].state = TCG_TEMP_HAS_COPY;
|
||||
@@ -444,7 +441,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
- tcg_opt_gen_mov(s, gen_args, args[0], args[1],
|
||||
+ tcg_opt_gen_mov(gen_args, args[0], args[1],
|
||||
nb_temps, nb_globals);
|
||||
gen_args += 2;
|
||||
}
|
||||
@@ -482,7 +479,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
- tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
|
||||
+ tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
|
||||
nb_globals);
|
||||
gen_args += 2;
|
||||
}
|
||||
@@ -507,7 +504,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
break;
|
||||
}
|
||||
if (temps[args[1]].state != TCG_TEMP_CONST) {
|
||||
- tcg_opt_gen_mov(s, gen_args, args[0], args[1],
|
||||
+ tcg_opt_gen_mov(gen_args, args[0], args[1],
|
||||
nb_temps, nb_globals);
|
||||
gen_args += 2;
|
||||
args += 2;
|
||||
diff --git a/tcg/tcg.h b/tcg/tcg.h
|
||||
index d710694..8fbbc81 100644
|
||||
--- a/tcg/tcg.h
|
||||
+++ b/tcg/tcg.h
|
||||
@@ -458,11 +458,6 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void)
|
||||
void tcg_temp_free_i64(TCGv_i64 arg);
|
||||
char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
|
||||
|
||||
-static inline bool tcg_arg_is_local(TCGContext *s, TCGArg arg)
|
||||
-{
|
||||
- return s->temps[arg].temp_local;
|
||||
-}
|
||||
-
|
||||
#if defined(CONFIG_DEBUG_TCG)
|
||||
/* If you call tcg_clear_temp_count() at the start of a section of
|
||||
* code which is not supposed to leak any TCG temporaries, then
|
||||
--
|
||||
1.7.12.1
|
||||
|
55
0043-target-mips-Set-opn-in-gen_ldst_multiple.patch
Normal file
55
0043-target-mips-Set-opn-in-gen_ldst_multiple.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 3380afc68a701604e51fa22637ef48d93514d678 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Tue, 18 Sep 2012 21:55:32 -0700
|
||||
Subject: [PATCH] target-mips: Set opn in gen_ldst_multiple.
|
||||
|
||||
Used by MIPS_DEBUG, when enabled.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Acked-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-mips/translate.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/target-mips/translate.c b/target-mips/translate.c
|
||||
index 7ab769f..c31f91c 100644
|
||||
--- a/target-mips/translate.c
|
||||
+++ b/target-mips/translate.c
|
||||
@@ -9855,6 +9855,7 @@ static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
|
||||
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
|
||||
int base, int16_t offset)
|
||||
{
|
||||
+ const char *opn = "ldst_multiple";
|
||||
TCGv t0, t1;
|
||||
TCGv_i32 t2;
|
||||
|
||||
@@ -9874,19 +9875,24 @@ static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
|
||||
switch (opc) {
|
||||
case LWM32:
|
||||
gen_helper_lwm(cpu_env, t0, t1, t2);
|
||||
+ opn = "lwm";
|
||||
break;
|
||||
case SWM32:
|
||||
gen_helper_swm(cpu_env, t0, t1, t2);
|
||||
+ opn = "swm";
|
||||
break;
|
||||
#ifdef TARGET_MIPS64
|
||||
case LDM:
|
||||
gen_helper_ldm(cpu_env, t0, t1, t2);
|
||||
+ opn = "ldm";
|
||||
break;
|
||||
case SDM:
|
||||
gen_helper_sdm(cpu_env, t0, t1, t2);
|
||||
+ opn = "sdm";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
+ (void)opn;
|
||||
MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free(t1);
|
||||
--
|
||||
1.7.12.1
|
||||
|
288
0044-target-mips-Fix-MIPS_DEBUG.patch
Normal file
288
0044-target-mips-Fix-MIPS_DEBUG.patch
Normal file
@ -0,0 +1,288 @@
|
||||
From 5dd8e9207a39d8fe41eaa110edfdba5e37064562 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Tue, 18 Sep 2012 21:55:33 -0700
|
||||
Subject: [PATCH] target-mips: Fix MIPS_DEBUG.
|
||||
|
||||
The macro uses the DisasContext. Pass it around as needed.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Acked-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-mips/translate.c | 74 +++++++++++++++++++++++++------------------------
|
||||
1 file changed, 38 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/target-mips/translate.c b/target-mips/translate.c
|
||||
index c31f91c..4937f6b 100644
|
||||
--- a/target-mips/translate.c
|
||||
+++ b/target-mips/translate.c
|
||||
@@ -1431,7 +1431,8 @@ static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
}
|
||||
|
||||
/* Logic with immediate operand */
|
||||
-static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
|
||||
+static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
+ int rt, int rs, int16_t imm)
|
||||
{
|
||||
target_ulong uimm;
|
||||
const char *opn = "imm logic";
|
||||
@@ -1474,7 +1475,8 @@ static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int1
|
||||
}
|
||||
|
||||
/* Set on less than with immediate operand */
|
||||
-static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
|
||||
+static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
+ int rt, int rs, int16_t imm)
|
||||
{
|
||||
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
|
||||
const char *opn = "imm arith";
|
||||
@@ -1775,7 +1777,8 @@ static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
}
|
||||
|
||||
/* Conditional move */
|
||||
-static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
|
||||
+static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
+ int rd, int rs, int rt)
|
||||
{
|
||||
const char *opn = "cond move";
|
||||
int l1;
|
||||
@@ -1813,7 +1816,8 @@ static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int
|
||||
}
|
||||
|
||||
/* Logic */
|
||||
-static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
|
||||
+static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
+ int rd, int rs, int rt)
|
||||
{
|
||||
const char *opn = "logic";
|
||||
|
||||
@@ -1874,7 +1878,8 @@ static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
|
||||
}
|
||||
|
||||
/* Set on lower than */
|
||||
-static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
|
||||
+static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
|
||||
+ int rd, int rs, int rt)
|
||||
{
|
||||
const char *opn = "slt";
|
||||
TCGv t0, t1;
|
||||
@@ -8778,10 +8783,10 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
|
||||
break;
|
||||
case M16_OPC_SLTI:
|
||||
- gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
|
||||
+ gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
|
||||
break;
|
||||
case M16_OPC_SLTIU:
|
||||
- gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
|
||||
+ gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
|
||||
break;
|
||||
case M16_OPC_I8:
|
||||
switch (funct) {
|
||||
@@ -8992,15 +8997,13 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case M16_OPC_SLTI:
|
||||
{
|
||||
int16_t imm = (uint8_t) ctx->opcode;
|
||||
-
|
||||
- gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
|
||||
+ gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
|
||||
}
|
||||
break;
|
||||
case M16_OPC_SLTIU:
|
||||
{
|
||||
int16_t imm = (uint8_t) ctx->opcode;
|
||||
-
|
||||
- gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
|
||||
+ gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
|
||||
}
|
||||
break;
|
||||
case M16_OPC_I8:
|
||||
@@ -9075,8 +9078,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case M16_OPC_CMPI:
|
||||
{
|
||||
int16_t imm = (uint8_t) ctx->opcode;
|
||||
-
|
||||
- gen_logic_imm(env, OPC_XORI, 24, rx, imm);
|
||||
+ gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
|
||||
}
|
||||
break;
|
||||
#if defined(TARGET_MIPS64)
|
||||
@@ -9188,10 +9190,10 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
}
|
||||
break;
|
||||
case RR_SLT:
|
||||
- gen_slt(env, OPC_SLT, 24, rx, ry);
|
||||
+ gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
|
||||
break;
|
||||
case RR_SLTU:
|
||||
- gen_slt(env, OPC_SLTU, 24, rx, ry);
|
||||
+ gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
|
||||
break;
|
||||
case RR_BREAK:
|
||||
generate_exception(ctx, EXCP_BREAK);
|
||||
@@ -9212,22 +9214,22 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
break;
|
||||
#endif
|
||||
case RR_CMP:
|
||||
- gen_logic(env, OPC_XOR, 24, rx, ry);
|
||||
+ gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
|
||||
break;
|
||||
case RR_NEG:
|
||||
gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
|
||||
break;
|
||||
case RR_AND:
|
||||
- gen_logic(env, OPC_AND, rx, rx, ry);
|
||||
+ gen_logic(env, ctx, OPC_AND, rx, rx, ry);
|
||||
break;
|
||||
case RR_OR:
|
||||
- gen_logic(env, OPC_OR, rx, rx, ry);
|
||||
+ gen_logic(env, ctx, OPC_OR, rx, rx, ry);
|
||||
break;
|
||||
case RR_XOR:
|
||||
- gen_logic(env, OPC_XOR, rx, rx, ry);
|
||||
+ gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
|
||||
break;
|
||||
case RR_NOT:
|
||||
- gen_logic(env, OPC_NOR, rx, ry, 0);
|
||||
+ gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
|
||||
break;
|
||||
case RR_MFHI:
|
||||
gen_HILO(ctx, OPC_MFHI, rx);
|
||||
@@ -9849,7 +9851,7 @@ static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
|
||||
int rs = mmreg(uMIPS_RS(ctx->opcode));
|
||||
int encoded = ZIMM(ctx->opcode, 0, 4);
|
||||
|
||||
- gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
|
||||
+ gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
|
||||
}
|
||||
|
||||
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
|
||||
@@ -9911,25 +9913,25 @@ static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_bran
|
||||
case NOT16 + 1:
|
||||
case NOT16 + 2:
|
||||
case NOT16 + 3:
|
||||
- gen_logic(env, OPC_NOR, rd, rs, 0);
|
||||
+ gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
|
||||
break;
|
||||
case XOR16 + 0:
|
||||
case XOR16 + 1:
|
||||
case XOR16 + 2:
|
||||
case XOR16 + 3:
|
||||
- gen_logic(env, OPC_XOR, rd, rd, rs);
|
||||
+ gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
|
||||
break;
|
||||
case AND16 + 0:
|
||||
case AND16 + 1:
|
||||
case AND16 + 2:
|
||||
case AND16 + 3:
|
||||
- gen_logic(env, OPC_AND, rd, rd, rs);
|
||||
+ gen_logic(env, ctx, OPC_AND, rd, rd, rs);
|
||||
break;
|
||||
case OR16 + 0:
|
||||
case OR16 + 1:
|
||||
case OR16 + 2:
|
||||
case OR16 + 3:
|
||||
- gen_logic(env, OPC_OR, rd, rd, rs);
|
||||
+ gen_logic(env, ctx, OPC_OR, rd, rd, rs);
|
||||
break;
|
||||
case LWM16 + 0:
|
||||
case LWM16 + 1:
|
||||
@@ -10743,7 +10745,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case XOR32:
|
||||
mips32_op = OPC_XOR;
|
||||
do_logic:
|
||||
- gen_logic(env, mips32_op, rd, rs, rt);
|
||||
+ gen_logic(env, ctx, mips32_op, rd, rs, rt);
|
||||
break;
|
||||
/* Set less than */
|
||||
case SLT:
|
||||
@@ -10752,7 +10754,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case SLTU:
|
||||
mips32_op = OPC_SLTU;
|
||||
do_slt:
|
||||
- gen_slt(env, mips32_op, rd, rs, rt);
|
||||
+ gen_slt(env, ctx, mips32_op, rd, rs, rt);
|
||||
break;
|
||||
default:
|
||||
goto pool32a_invalid;
|
||||
@@ -10768,7 +10770,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case MOVZ:
|
||||
mips32_op = OPC_MOVZ;
|
||||
do_cmov:
|
||||
- gen_cond_move(env, mips32_op, rd, rs, rt);
|
||||
+ gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
|
||||
break;
|
||||
case LWXS:
|
||||
gen_ldxs(ctx, rs, rt, rd);
|
||||
@@ -11181,7 +11183,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
target. */
|
||||
break;
|
||||
case LUI:
|
||||
- gen_logic_imm(env, OPC_LUI, rs, -1, imm);
|
||||
+ gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
|
||||
break;
|
||||
case SYNCI:
|
||||
break;
|
||||
@@ -11300,7 +11302,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case ANDI32:
|
||||
mips32_op = OPC_ANDI;
|
||||
do_logici:
|
||||
- gen_logic_imm(env, mips32_op, rt, rs, imm);
|
||||
+ gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
|
||||
break;
|
||||
|
||||
/* Set less than immediate */
|
||||
@@ -11310,7 +11312,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||
case SLTIU32:
|
||||
mips32_op = OPC_SLTIU;
|
||||
do_slti:
|
||||
- gen_slt_imm(env, mips32_op, rt, rs, imm);
|
||||
+ gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
|
||||
break;
|
||||
case JALX32:
|
||||
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
|
||||
@@ -11787,7 +11789,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
|
||||
case OPC_MOVZ:
|
||||
check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
|
||||
INSN_LOONGSON2E | INSN_LOONGSON2F);
|
||||
- gen_cond_move(env, op1, rd, rs, rt);
|
||||
+ gen_cond_move(env, ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
case OPC_ADD ... OPC_SUBU:
|
||||
gen_arith(env, ctx, op1, rd, rs, rt);
|
||||
@@ -11814,13 +11816,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
|
||||
break;
|
||||
case OPC_SLT: /* Set on less than */
|
||||
case OPC_SLTU:
|
||||
- gen_slt(env, op1, rd, rs, rt);
|
||||
+ gen_slt(env, ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
case OPC_AND: /* Logic*/
|
||||
case OPC_OR:
|
||||
case OPC_NOR:
|
||||
case OPC_XOR:
|
||||
- gen_logic(env, op1, rd, rs, rt);
|
||||
+ gen_logic(env, ctx, op1, rd, rs, rt);
|
||||
break;
|
||||
case OPC_MULT ... OPC_DIVU:
|
||||
if (sa) {
|
||||
@@ -12221,13 +12223,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
|
||||
break;
|
||||
case OPC_SLTI: /* Set on less than with immediate opcode */
|
||||
case OPC_SLTIU:
|
||||
- gen_slt_imm(env, op, rt, rs, imm);
|
||||
+ gen_slt_imm(env, ctx, op, rt, rs, imm);
|
||||
break;
|
||||
case OPC_ANDI: /* Arithmetic with immediate opcode */
|
||||
case OPC_LUI:
|
||||
case OPC_ORI:
|
||||
case OPC_XORI:
|
||||
- gen_logic_imm(env, op, rt, rs, imm);
|
||||
+ gen_logic_imm(env, ctx, op, rt, rs, imm);
|
||||
break;
|
||||
case OPC_J ... OPC_JAL: /* Jump */
|
||||
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -0,0 +1,70 @@
|
||||
From e6f923b4e3e71661343f6d2eecd7f102022e5635 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Tue, 18 Sep 2012 21:55:34 -0700
|
||||
Subject: [PATCH] target-mips: Always evaluate debugging macro arguments
|
||||
|
||||
this will prevent some of the compilation errors with debugging
|
||||
enabled from creeping back in.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-mips/translate.c | 31 +++++++++++++++++--------------
|
||||
1 file changed, 17 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/target-mips/translate.c b/target-mips/translate.c
|
||||
index 4937f6b..aba7935 100644
|
||||
--- a/target-mips/translate.c
|
||||
+++ b/target-mips/translate.c
|
||||
@@ -28,7 +28,7 @@
|
||||
#define GEN_HELPER 1
|
||||
#include "helper.h"
|
||||
|
||||
-//#define MIPS_DEBUG_DISAS
|
||||
+#define MIPS_DEBUG_DISAS 0
|
||||
//#define MIPS_DEBUG_SIGN_EXTENSIONS
|
||||
|
||||
/* MIPS major opcodes */
|
||||
@@ -566,22 +566,25 @@ static const char *fregnames[] =
|
||||
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
|
||||
|
||||
-#ifdef MIPS_DEBUG_DISAS
|
||||
-#define MIPS_DEBUG(fmt, ...) \
|
||||
- qemu_log_mask(CPU_LOG_TB_IN_ASM, \
|
||||
- TARGET_FMT_lx ": %08x " fmt "\n", \
|
||||
- ctx->pc, ctx->opcode , ## __VA_ARGS__)
|
||||
-#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
|
||||
-#else
|
||||
-#define MIPS_DEBUG(fmt, ...) do { } while(0)
|
||||
-#define LOG_DISAS(...) do { } while (0)
|
||||
-#endif
|
||||
+#define MIPS_DEBUG(fmt, ...) \
|
||||
+ do { \
|
||||
+ if (MIPS_DEBUG_DISAS) { \
|
||||
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, \
|
||||
+ TARGET_FMT_lx ": %08x " fmt "\n", \
|
||||
+ ctx->pc, ctx->opcode , ## __VA_ARGS__); \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
+
|
||||
+#define LOG_DISAS(...) \
|
||||
+ do { \
|
||||
+ if (MIPS_DEBUG_DISAS) { \
|
||||
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
|
||||
#define MIPS_INVAL(op) \
|
||||
-do { \
|
||||
MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
|
||||
- ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
|
||||
-} while (0)
|
||||
+ ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
|
||||
|
||||
/* General purpose registers moves. */
|
||||
static inline void gen_load_gpr (TCGv t, int reg)
|
||||
--
|
||||
1.7.12.1
|
||||
|
62
0046-tcg-optimize-fix-end-of-basic-block-detection.patch
Normal file
62
0046-tcg-optimize-fix-end-of-basic-block-detection.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 4ce7a1e0aaecb220016af9b4f390b76f7fffcce8 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Wed, 19 Sep 2012 21:40:30 +0200
|
||||
Subject: [PATCH] tcg/optimize: fix end of basic block detection
|
||||
|
||||
Commit e31b0a7c050711884ad570fe73df806520953618 fixed copy propagation on
|
||||
32-bit host by restricting the copy between different types. This was the
|
||||
wrong fix.
|
||||
|
||||
The real problem is that the all temps states should be reset at the end
|
||||
of a basic block. This was done by adding such operations in the switch,
|
||||
but brcond2 was forgotten (that's why the crash was only observed on 32-bit
|
||||
hosts).
|
||||
|
||||
Fix that by looking at the TCG_OPF_BB_END instead. We need to keep the case
|
||||
for op_set_label as temps might be modified through another path.
|
||||
|
||||
Cc: Blue Swirl <blauwirbel@gmail.com>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 22 +++++++++-------------
|
||||
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 10d9773..9da333c 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -632,21 +632,17 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
i--;
|
||||
}
|
||||
break;
|
||||
- case INDEX_op_set_label:
|
||||
- case INDEX_op_jmp:
|
||||
- case INDEX_op_br:
|
||||
- memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
- for (i = 0; i < def->nb_args; i++) {
|
||||
- *gen_args = *args;
|
||||
- args++;
|
||||
- gen_args++;
|
||||
- }
|
||||
- break;
|
||||
default:
|
||||
/* Default case: we do know nothing about operation so no
|
||||
- propagation is done. We only trash output args. */
|
||||
- for (i = 0; i < def->nb_oargs; i++) {
|
||||
- reset_temp(args[i], nb_temps, nb_globals);
|
||||
+ propagation is done. We trash everything if the operation
|
||||
+ is the end of a basic block, otherwise we only trash the
|
||||
+ output args. */
|
||||
+ if (def->flags & TCG_OPF_BB_END) {
|
||||
+ memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
+ } else {
|
||||
+ for (i = 0; i < def->nb_oargs; i++) {
|
||||
+ reset_temp(args[i], nb_temps, nb_globals);
|
||||
+ }
|
||||
}
|
||||
for (i = 0; i < def->nb_args; i++) {
|
||||
gen_args[i] = args[i];
|
||||
--
|
||||
1.7.12.1
|
||||
|
57
0047-target-xtensa-fix-extui-shift-amount.patch
Normal file
57
0047-target-xtensa-fix-extui-shift-amount.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 1c596a9498830485a1b2f4a4445643a149179b99 Mon Sep 17 00:00:00 2001
|
||||
From: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Date: Fri, 21 Sep 2012 02:59:49 +0400
|
||||
Subject: [PATCH] target-xtensa: fix extui shift amount
|
||||
|
||||
extui opcode only uses lowermost op1 bit for sa4.
|
||||
|
||||
Reported-by: malc <av1474@comtv.ru>
|
||||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Cc: qemu-stable <qemu-stable@nongnu.org>
|
||||
Signed-off-by: malc <av1474@comtv.ru>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-xtensa/translate.c | 24 +++++++++++++++++++++---
|
||||
1 file changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
|
||||
index 1900bd5..7a1c528 100644
|
||||
--- a/target-xtensa/translate.c
|
||||
+++ b/target-xtensa/translate.c
|
||||
@@ -1778,12 +1778,30 @@ static void disas_xtensa_insn(DisasContext *dc)
|
||||
case 5:
|
||||
gen_window_check2(dc, RRR_R, RRR_T);
|
||||
{
|
||||
- int shiftimm = RRR_S | (OP1 << 4);
|
||||
+ int shiftimm = RRR_S | ((OP1 & 1) << 4);
|
||||
int maskimm = (1 << (OP2 + 1)) - 1;
|
||||
|
||||
TCGv_i32 tmp = tcg_temp_new_i32();
|
||||
- tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
|
||||
- tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
|
||||
+
|
||||
+ if (shiftimm) {
|
||||
+ tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
|
||||
+ } else {
|
||||
+ tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
|
||||
+ }
|
||||
+
|
||||
+ switch (maskimm) {
|
||||
+ case 0xff:
|
||||
+ tcg_gen_ext8u_i32(cpu_R[RRR_R], tmp);
|
||||
+ break;
|
||||
+
|
||||
+ case 0xffff:
|
||||
+ tcg_gen_ext16u_i32(cpu_R[RRR_R], tmp);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
|
||||
+ break;
|
||||
+ }
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
break;
|
||||
--
|
||||
1.7.12.1
|
||||
|
35
0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch
Normal file
35
0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From ba9c2acb955f0453ae80077a791a4d1c27b5d6e6 Mon Sep 17 00:00:00 2001
|
||||
From: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Date: Fri, 21 Sep 2012 02:59:50 +0400
|
||||
Subject: [PATCH] target-xtensa: don't emit extra tcg_gen_goto_tb
|
||||
|
||||
Unconditional gen_check_loop_end at the end of disas_xtensa_insn
|
||||
can emit tcg_gen_goto_tb with slot id already used in the TB (e.g. when
|
||||
TB ends at LEND with a branch).
|
||||
|
||||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Cc: qemu-stable <qemu-stable@nongnu.org>
|
||||
Signed-off-by: malc <av1474@comtv.ru>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-xtensa/translate.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
|
||||
index 7a1c528..b6643eb 100644
|
||||
--- a/target-xtensa/translate.c
|
||||
+++ b/target-xtensa/translate.c
|
||||
@@ -2520,7 +2520,9 @@ static void disas_xtensa_insn(DisasContext *dc)
|
||||
break;
|
||||
}
|
||||
|
||||
- gen_check_loop_end(dc, 0);
|
||||
+ if (dc->is_jmp == DISAS_NEXT) {
|
||||
+ gen_check_loop_end(dc, 0);
|
||||
+ }
|
||||
dc->pc = dc->next_pc;
|
||||
|
||||
return;
|
||||
--
|
||||
1.7.12.1
|
||||
|
333
0049-tcg-Introduce-movcond.patch
Normal file
333
0049-tcg-Introduce-movcond.patch
Normal file
@ -0,0 +1,333 @@
|
||||
From a977d2c7f02eb2ed7fc879979d6f5525c017a881 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:13:34 -0700
|
||||
Subject: [PATCH] tcg: Introduce movcond
|
||||
|
||||
Implemented with setcond if the target does not provide
|
||||
the optional opcode.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/README | 6 ++++++
|
||||
tcg/arm/tcg-target.h | 1 +
|
||||
tcg/hppa/tcg-target.h | 1 +
|
||||
tcg/i386/tcg-target.h | 2 ++
|
||||
tcg/ia64/tcg-target.h | 2 ++
|
||||
tcg/mips/tcg-target.h | 1 +
|
||||
tcg/ppc/tcg-target.h | 1 +
|
||||
tcg/ppc64/tcg-target.h | 2 ++
|
||||
tcg/s390/tcg-target.h | 2 ++
|
||||
tcg/sparc/tcg-target.h | 2 ++
|
||||
tcg/tcg-op.h | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
tcg/tcg-opc.h | 2 ++
|
||||
tcg/tcg.c | 11 +++++------
|
||||
tcg/tcg.h | 1 +
|
||||
tcg/tci/tcg-target.h | 2 ++
|
||||
15 files changed, 70 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tcg/README b/tcg/README
|
||||
index cfdfd96..d03ae05 100644
|
||||
--- a/tcg/README
|
||||
+++ b/tcg/README
|
||||
@@ -307,6 +307,12 @@ dest = (t1 cond t2)
|
||||
|
||||
Set DEST to 1 if (T1 cond T2) is true, otherwise set to 0.
|
||||
|
||||
+* movcond_i32/i64 cond, dest, c1, c2, v1, v2
|
||||
+
|
||||
+dest = (c1 cond c2 ? v1 : v2)
|
||||
+
|
||||
+Set DEST to V1 if (C1 cond C2) is true, otherwise set to V2.
|
||||
+
|
||||
********* Type conversions
|
||||
|
||||
* ext_i32_i64 t0, t1
|
||||
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
|
||||
index c0b8f72..e2299ca 100644
|
||||
--- a/tcg/arm/tcg-target.h
|
||||
+++ b/tcg/arm/tcg-target.h
|
||||
@@ -73,6 +73,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#define TCG_TARGET_HAS_GUEST_BASE
|
||||
|
||||
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
|
||||
index 01ef960..4defd28 100644
|
||||
--- a/tcg/hppa/tcg-target.h
|
||||
+++ b/tcg/hppa/tcg-target.h
|
||||
@@ -96,6 +96,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 1
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, 0, rs */
|
||||
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
|
||||
index 8be42f3..504f953 100644
|
||||
--- a/tcg/i386/tcg-target.h
|
||||
+++ b/tcg/i386/tcg-target.h
|
||||
@@ -86,6 +86,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 1
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_HAS_div2_i64 1
|
||||
@@ -107,6 +108,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i64 0
|
||||
#define TCG_TARGET_HAS_nor_i64 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 1
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
#endif
|
||||
|
||||
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
|
||||
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
|
||||
index c22962a..368aee4 100644
|
||||
--- a/tcg/ia64/tcg-target.h
|
||||
+++ b/tcg/ia64/tcg-target.h
|
||||
@@ -133,6 +133,8 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_rot_i64 1
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
#define TCG_TARGET_HAS_neg_i32 0 /* sub r1, r0, r3 */
|
||||
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
|
||||
index 1c61931..9c68a32 100644
|
||||
--- a/tcg/mips/tcg-target.h
|
||||
+++ b/tcg/mips/tcg-target.h
|
||||
@@ -90,6 +90,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_eqv_i32 0
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */
|
||||
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
|
||||
index 2f37fd2..177eea1 100644
|
||||
--- a/tcg/ppc/tcg-target.h
|
||||
+++ b/tcg/ppc/tcg-target.h
|
||||
@@ -92,6 +92,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 1
|
||||
#define TCG_TARGET_HAS_nor_i32 1
|
||||
#define TCG_TARGET_HAS_deposit_i32 1
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#define TCG_AREG0 TCG_REG_R27
|
||||
|
||||
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
|
||||
index 97eec08..57569e8 100644
|
||||
--- a/tcg/ppc64/tcg-target.h
|
||||
+++ b/tcg/ppc64/tcg-target.h
|
||||
@@ -83,6 +83,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#define TCG_TARGET_HAS_div_i64 1
|
||||
#define TCG_TARGET_HAS_rot_i64 0
|
||||
@@ -103,6 +104,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i64 0
|
||||
#define TCG_TARGET_HAS_nor_i64 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 0
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
|
||||
#define TCG_AREG0 TCG_REG_R27
|
||||
|
||||
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
|
||||
index 4f7dfab..ed55c33 100644
|
||||
--- a/tcg/s390/tcg-target.h
|
||||
+++ b/tcg/s390/tcg-target.h
|
||||
@@ -63,6 +63,7 @@ typedef enum TCGReg {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_HAS_div2_i64 1
|
||||
@@ -84,6 +85,7 @@ typedef enum TCGReg {
|
||||
#define TCG_TARGET_HAS_nand_i64 0
|
||||
#define TCG_TARGET_HAS_nor_i64 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 0
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
#endif
|
||||
|
||||
#define TCG_TARGET_HAS_GUEST_BASE
|
||||
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
|
||||
index 0ea87be..d762574 100644
|
||||
--- a/tcg/sparc/tcg-target.h
|
||||
+++ b/tcg/sparc/tcg-target.h
|
||||
@@ -102,6 +102,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_HAS_div_i64 1
|
||||
@@ -123,6 +124,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i64 0
|
||||
#define TCG_TARGET_HAS_nor_i64 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 0
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOLARIS
|
||||
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
|
||||
index 169d3b2..6d28f82 100644
|
||||
--- a/tcg/tcg-op.h
|
||||
+++ b/tcg/tcg-op.h
|
||||
@@ -2118,6 +2118,44 @@ static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
|
||||
tcg_temp_free_i64(t1);
|
||||
}
|
||||
|
||||
+static inline void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret,
|
||||
+ TCGv_i32 c1, TCGv_i32 c2,
|
||||
+ TCGv_i32 v1, TCGv_i32 v2)
|
||||
+{
|
||||
+ if (TCG_TARGET_HAS_movcond_i32) {
|
||||
+ tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
|
||||
+ } else {
|
||||
+ TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
+ TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
+ tcg_gen_setcond_i32(cond, t0, c1, c2);
|
||||
+ tcg_gen_neg_i32(t0, t0);
|
||||
+ tcg_gen_and_i32(t1, v1, t0);
|
||||
+ tcg_gen_andc_i32(ret, v2, t0);
|
||||
+ tcg_gen_or_i32(ret, ret, t1);
|
||||
+ tcg_temp_free_i32(t0);
|
||||
+ tcg_temp_free_i32(t1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret,
|
||||
+ TCGv_i64 c1, TCGv_i64 c2,
|
||||
+ TCGv_i64 v1, TCGv_i64 v2)
|
||||
+{
|
||||
+ if (TCG_TARGET_HAS_movcond_i64) {
|
||||
+ tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
|
||||
+ } else {
|
||||
+ TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
+ TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
+ tcg_gen_setcond_i64(cond, t0, c1, c2);
|
||||
+ tcg_gen_neg_i64(t0, t0);
|
||||
+ tcg_gen_and_i64(t1, v1, t0);
|
||||
+ tcg_gen_andc_i64(ret, v2, t0);
|
||||
+ tcg_gen_or_i64(ret, ret, t1);
|
||||
+ tcg_temp_free_i64(t0);
|
||||
+ tcg_temp_free_i64(t1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/***************************************/
|
||||
/* QEMU specific operations. Their type depend on the QEMU CPU
|
||||
type. */
|
||||
@@ -2434,6 +2472,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
|
||||
#define tcg_gen_deposit_tl tcg_gen_deposit_i64
|
||||
#define tcg_const_tl tcg_const_i64
|
||||
#define tcg_const_local_tl tcg_const_local_i64
|
||||
+#define tcg_gen_movcond_tl tcg_gen_movcond_i64
|
||||
#else
|
||||
#define tcg_gen_movi_tl tcg_gen_movi_i32
|
||||
#define tcg_gen_mov_tl tcg_gen_mov_i32
|
||||
@@ -2505,6 +2544,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
|
||||
#define tcg_gen_deposit_tl tcg_gen_deposit_i32
|
||||
#define tcg_const_tl tcg_const_i32
|
||||
#define tcg_const_local_tl tcg_const_local_i32
|
||||
+#define tcg_gen_movcond_tl tcg_gen_movcond_i32
|
||||
#endif
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
|
||||
index d12e8d0..dbb0e39 100644
|
||||
--- a/tcg/tcg-opc.h
|
||||
+++ b/tcg/tcg-opc.h
|
||||
@@ -51,6 +51,7 @@ DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
|
||||
DEF(mov_i32, 1, 1, 0, 0)
|
||||
DEF(movi_i32, 1, 0, 1, 0)
|
||||
DEF(setcond_i32, 1, 2, 1, 0)
|
||||
+DEF(movcond_i32, 1, 4, 1, IMPL(TCG_TARGET_HAS_movcond_i32))
|
||||
/* load/store */
|
||||
DEF(ld8u_i32, 1, 1, 1, 0)
|
||||
DEF(ld8s_i32, 1, 1, 1, 0)
|
||||
@@ -107,6 +108,7 @@ DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32))
|
||||
DEF(mov_i64, 1, 1, 0, IMPL64)
|
||||
DEF(movi_i64, 1, 0, 1, IMPL64)
|
||||
DEF(setcond_i64, 1, 2, 1, IMPL64)
|
||||
+DEF(movcond_i64, 1, 4, 1, IMPL64 | IMPL(TCG_TARGET_HAS_movcond_i64))
|
||||
/* load/store */
|
||||
DEF(ld8u_i64, 1, 1, 1, IMPL64)
|
||||
DEF(ld8s_i64, 1, 1, 1, IMPL64)
|
||||
diff --git a/tcg/tcg.c b/tcg/tcg.c
|
||||
index c002a88..24ce830 100644
|
||||
--- a/tcg/tcg.c
|
||||
+++ b/tcg/tcg.c
|
||||
@@ -991,16 +991,15 @@ void tcg_dump_ops(TCGContext *s)
|
||||
}
|
||||
switch (c) {
|
||||
case INDEX_op_brcond_i32:
|
||||
-#if TCG_TARGET_REG_BITS == 32
|
||||
- case INDEX_op_brcond2_i32:
|
||||
-#elif TCG_TARGET_REG_BITS == 64
|
||||
- case INDEX_op_brcond_i64:
|
||||
-#endif
|
||||
case INDEX_op_setcond_i32:
|
||||
+ case INDEX_op_movcond_i32:
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
+ case INDEX_op_brcond2_i32:
|
||||
case INDEX_op_setcond2_i32:
|
||||
-#elif TCG_TARGET_REG_BITS == 64
|
||||
+#else
|
||||
+ case INDEX_op_brcond_i64:
|
||||
case INDEX_op_setcond_i64:
|
||||
+ case INDEX_op_movcond_i64:
|
||||
#endif
|
||||
if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
|
||||
qemu_log(",%s", cond_name[args[k++]]);
|
||||
diff --git a/tcg/tcg.h b/tcg/tcg.h
|
||||
index 8fbbc81..f454107 100644
|
||||
--- a/tcg/tcg.h
|
||||
+++ b/tcg/tcg.h
|
||||
@@ -79,6 +79,7 @@ typedef uint64_t TCGRegSet;
|
||||
#define TCG_TARGET_HAS_nand_i64 0
|
||||
#define TCG_TARGET_HAS_nor_i64 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 0
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
#endif
|
||||
|
||||
#ifndef TCG_TARGET_deposit_i32_valid
|
||||
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
|
||||
index 30a0f21..6d89495 100644
|
||||
--- a/tcg/tci/tcg-target.h
|
||||
+++ b/tcg/tci/tcg-target.h
|
||||
@@ -75,6 +75,7 @@
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
#define TCG_TARGET_HAS_orc_i32 0
|
||||
#define TCG_TARGET_HAS_rot_i32 1
|
||||
+#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_HAS_bswap16_i64 1
|
||||
@@ -98,6 +99,7 @@
|
||||
#define TCG_TARGET_HAS_not_i64 1
|
||||
#define TCG_TARGET_HAS_orc_i64 0
|
||||
#define TCG_TARGET_HAS_rot_i64 1
|
||||
+#define TCG_TARGET_HAS_movcond_i64 0
|
||||
#endif /* TCG_TARGET_REG_BITS == 64 */
|
||||
|
||||
/* Offset to user memory in user mode. */
|
||||
--
|
||||
1.7.12.1
|
||||
|
160
0050-target-alpha-Use-movcond.patch
Normal file
160
0050-target-alpha-Use-movcond.patch
Normal file
@ -0,0 +1,160 @@
|
||||
From 4bf321d3f494134fe2e03c9cbc042e28ec3a1045 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:13:35 -0700
|
||||
Subject: [PATCH] target-alpha: Use movcond
|
||||
|
||||
For proper cmov insns, as well as the non-goto-tb case
|
||||
of conditional branch.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
target-alpha/translate.c | 102 ++++++++++++++++++++++-------------------------
|
||||
1 file changed, 48 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
|
||||
index 12de6a3..4a9011a 100644
|
||||
--- a/target-alpha/translate.c
|
||||
+++ b/target-alpha/translate.c
|
||||
@@ -426,27 +426,15 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
|
||||
|
||||
return EXIT_GOTO_TB;
|
||||
} else {
|
||||
- int lab_over = gen_new_label();
|
||||
-
|
||||
- /* ??? Consider using either
|
||||
- movi pc, next
|
||||
- addi tmp, pc, disp
|
||||
- movcond pc, cond, 0, tmp, pc
|
||||
- or
|
||||
- setcond tmp, cond, 0
|
||||
- movi pc, next
|
||||
- neg tmp, tmp
|
||||
- andi tmp, tmp, disp
|
||||
- add pc, pc, tmp
|
||||
- The current diamond subgraph surely isn't efficient. */
|
||||
+ TCGv_i64 z = tcg_const_i64(0);
|
||||
+ TCGv_i64 d = tcg_const_i64(dest);
|
||||
+ TCGv_i64 p = tcg_const_i64(ctx->pc);
|
||||
|
||||
- tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
|
||||
- tcg_gen_movi_i64(cpu_pc, ctx->pc);
|
||||
- tcg_gen_br(lab_over);
|
||||
- gen_set_label(lab_true);
|
||||
- tcg_gen_movi_i64(cpu_pc, dest);
|
||||
- gen_set_label(lab_over);
|
||||
+ tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
|
||||
|
||||
+ tcg_temp_free_i64(z);
|
||||
+ tcg_temp_free_i64(d);
|
||||
+ tcg_temp_free_i64(p);
|
||||
return EXIT_PC_UPDATED;
|
||||
}
|
||||
}
|
||||
@@ -521,61 +509,67 @@ static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
|
||||
static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
|
||||
int islit, uint8_t lit, int mask)
|
||||
{
|
||||
- TCGCond inv_cond = tcg_invert_cond(cond);
|
||||
- int l1;
|
||||
+ TCGv_i64 c1, z, v1;
|
||||
|
||||
- if (unlikely(rc == 31))
|
||||
+ if (unlikely(rc == 31)) {
|
||||
return;
|
||||
+ }
|
||||
|
||||
- l1 = gen_new_label();
|
||||
-
|
||||
- if (ra != 31) {
|
||||
- if (mask) {
|
||||
- TCGv tmp = tcg_temp_new();
|
||||
- tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
|
||||
- tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
|
||||
- tcg_temp_free(tmp);
|
||||
- } else
|
||||
- tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
|
||||
- } else {
|
||||
+ if (ra == 31) {
|
||||
/* Very uncommon case - Do not bother to optimize. */
|
||||
- TCGv tmp = tcg_const_i64(0);
|
||||
- tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
|
||||
- tcg_temp_free(tmp);
|
||||
+ c1 = tcg_const_i64(0);
|
||||
+ } else if (mask) {
|
||||
+ c1 = tcg_const_i64(1);
|
||||
+ tcg_gen_and_i64(c1, c1, cpu_ir[ra]);
|
||||
+ } else {
|
||||
+ c1 = cpu_ir[ra];
|
||||
}
|
||||
+ if (islit) {
|
||||
+ v1 = tcg_const_i64(lit);
|
||||
+ } else {
|
||||
+ v1 = cpu_ir[rb];
|
||||
+ }
|
||||
+ z = tcg_const_i64(0);
|
||||
|
||||
- if (islit)
|
||||
- tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
- else
|
||||
- tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
- gen_set_label(l1);
|
||||
+ tcg_gen_movcond_i64(cond, cpu_ir[rc], c1, z, v1, cpu_ir[rc]);
|
||||
+
|
||||
+ tcg_temp_free_i64(z);
|
||||
+ if (ra == 31 || mask) {
|
||||
+ tcg_temp_free_i64(c1);
|
||||
+ }
|
||||
+ if (islit) {
|
||||
+ tcg_temp_free_i64(v1);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
|
||||
{
|
||||
- TCGv cmp_tmp;
|
||||
- int l1;
|
||||
+ TCGv_i64 c1, z, v1;
|
||||
|
||||
if (unlikely(rc == 31)) {
|
||||
return;
|
||||
}
|
||||
|
||||
- cmp_tmp = tcg_temp_new();
|
||||
+ c1 = tcg_temp_new_i64();
|
||||
if (unlikely(ra == 31)) {
|
||||
- tcg_gen_movi_i64(cmp_tmp, 0);
|
||||
+ tcg_gen_movi_i64(c1, 0);
|
||||
+ } else {
|
||||
+ gen_fold_mzero(cond, c1, cpu_fir[ra]);
|
||||
+ }
|
||||
+ if (rb == 31) {
|
||||
+ v1 = tcg_const_i64(0);
|
||||
} else {
|
||||
- gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
|
||||
+ v1 = cpu_fir[rb];
|
||||
}
|
||||
+ z = tcg_const_i64(0);
|
||||
|
||||
- l1 = gen_new_label();
|
||||
- tcg_gen_brcondi_i64(tcg_invert_cond(cond), cmp_tmp, 0, l1);
|
||||
- tcg_temp_free(cmp_tmp);
|
||||
+ tcg_gen_movcond_i64(cond, cpu_fir[rc], c1, z, v1, cpu_fir[rc]);
|
||||
|
||||
- if (rb != 31)
|
||||
- tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
|
||||
- else
|
||||
- tcg_gen_movi_i64(cpu_fir[rc], 0);
|
||||
- gen_set_label(l1);
|
||||
+ tcg_temp_free_i64(z);
|
||||
+ tcg_temp_free_i64(c1);
|
||||
+ if (rb == 31) {
|
||||
+ tcg_temp_free_i64(v1);
|
||||
+ }
|
||||
}
|
||||
|
||||
#define QUAL_RM_N 0x080 /* Round mode nearest even */
|
||||
--
|
||||
1.7.12.1
|
||||
|
118
0051-tcg-i386-Implement-movcond.patch
Normal file
118
0051-tcg-i386-Implement-movcond.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From 7a6273e2995b6c439441316467ab19bd6a48f03f Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:13:36 -0700
|
||||
Subject: [PATCH] tcg-i386: Implement movcond
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/i386/tcg-target.c | 29 +++++++++++++++++++++++++++++
|
||||
tcg/i386/tcg-target.h | 7 ++++++-
|
||||
2 files changed, 35 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
|
||||
index 3017858..aa1fa9f 100644
|
||||
--- a/tcg/i386/tcg-target.c
|
||||
+++ b/tcg/i386/tcg-target.c
|
||||
@@ -249,6 +249,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
|
||||
#define OPC_ADD_GvEv (OPC_ARITH_GvEv | (ARITH_ADD << 3))
|
||||
#define OPC_BSWAP (0xc8 | P_EXT)
|
||||
#define OPC_CALL_Jz (0xe8)
|
||||
+#define OPC_CMOVCC (0x40 | P_EXT) /* ... plus condition code */
|
||||
#define OPC_CMP_GvEv (OPC_ARITH_GvEv | (ARITH_CMP << 3))
|
||||
#define OPC_DEC_r32 (0x48)
|
||||
#define OPC_IMUL_GvEv (0xaf | P_EXT)
|
||||
@@ -936,6 +937,24 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
|
||||
}
|
||||
#endif
|
||||
|
||||
+static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGArg dest,
|
||||
+ TCGArg c1, TCGArg c2, int const_c2,
|
||||
+ TCGArg v1)
|
||||
+{
|
||||
+ tcg_out_cmp(s, c1, c2, const_c2, 0);
|
||||
+ tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
|
||||
+}
|
||||
+
|
||||
+#if TCG_TARGET_REG_BITS == 64
|
||||
+static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest,
|
||||
+ TCGArg c1, TCGArg c2, int const_c2,
|
||||
+ TCGArg v1)
|
||||
+{
|
||||
+ tcg_out_cmp(s, c1, c2, const_c2, P_REXW);
|
||||
+ tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | P_REXW, dest, v1);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
|
||||
{
|
||||
tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
|
||||
@@ -1668,6 +1687,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
tcg_out_setcond32(s, args[3], args[0], args[1],
|
||||
args[2], const_args[2]);
|
||||
break;
|
||||
+ case INDEX_op_movcond_i32:
|
||||
+ tcg_out_movcond32(s, args[5], args[0], args[1],
|
||||
+ args[2], const_args[2], args[3]);
|
||||
+ break;
|
||||
|
||||
OP_32_64(bswap16):
|
||||
tcg_out_rolw_8(s, args[0]);
|
||||
@@ -1796,6 +1819,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
tcg_out_setcond64(s, args[3], args[0], args[1],
|
||||
args[2], const_args[2]);
|
||||
break;
|
||||
+ case INDEX_op_movcond_i64:
|
||||
+ tcg_out_movcond64(s, args[5], args[0], args[1],
|
||||
+ args[2], const_args[2], args[3]);
|
||||
+ break;
|
||||
|
||||
case INDEX_op_bswap64_i64:
|
||||
tcg_out_bswap64(s, args[0]);
|
||||
@@ -1880,6 +1907,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
||||
{ INDEX_op_setcond_i32, { "q", "r", "ri" } },
|
||||
|
||||
{ INDEX_op_deposit_i32, { "Q", "0", "Q" } },
|
||||
+ { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
{ INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
|
||||
@@ -1934,6 +1962,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
|
||||
{ INDEX_op_ext32u_i64, { "r", "r" } },
|
||||
|
||||
{ INDEX_op_deposit_i64, { "Q", "0", "Q" } },
|
||||
+ { INDEX_op_movcond_i64, { "r", "r", "re", "r", "0" } },
|
||||
#endif
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
|
||||
index 504f953..b356d76 100644
|
||||
--- a/tcg/i386/tcg-target.h
|
||||
+++ b/tcg/i386/tcg-target.h
|
||||
@@ -86,7 +86,12 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
#define TCG_TARGET_HAS_nor_i32 0
|
||||
#define TCG_TARGET_HAS_deposit_i32 1
|
||||
+#if defined(__x86_64__) || defined(__i686__)
|
||||
+/* Use cmov only if the compiler is already doing so. */
|
||||
+#define TCG_TARGET_HAS_movcond_i32 1
|
||||
+#else
|
||||
#define TCG_TARGET_HAS_movcond_i32 0
|
||||
+#endif
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_HAS_div2_i64 1
|
||||
@@ -108,7 +113,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i64 0
|
||||
#define TCG_TARGET_HAS_nor_i64 0
|
||||
#define TCG_TARGET_HAS_deposit_i64 1
|
||||
-#define TCG_TARGET_HAS_movcond_i64 0
|
||||
+#define TCG_TARGET_HAS_movcond_i64 1
|
||||
#endif
|
||||
|
||||
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
|
||||
--
|
||||
1.7.12.1
|
||||
|
73
0052-tcg-Optimize-movcond-for-constant-comparisons.patch
Normal file
73
0052-tcg-Optimize-movcond-for-constant-comparisons.patch
Normal file
@ -0,0 +1,73 @@
|
||||
From c489b380d3f827be91b5f8b80b88585fb4014fbb Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:13:37 -0700
|
||||
Subject: [PATCH] tcg: Optimize movcond for constant comparisons
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 9da333c..26038a6 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -394,6 +394,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args[3] = tcg_swap_cond(args[3]);
|
||||
}
|
||||
break;
|
||||
+ CASE_OP_32_64(movcond):
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[2]].state != TCG_TEMP_CONST) {
|
||||
+ tmp = args[1];
|
||||
+ args[1] = args[2];
|
||||
+ args[2] = tmp;
|
||||
+ args[5] = tcg_swap_cond(args[5]);
|
||||
+ }
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -614,6 +622,38 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
}
|
||||
args += 4;
|
||||
break;
|
||||
+ CASE_OP_32_64(movcond):
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
+ tmp = do_constant_folding_cond(op, temps[args[1]].val,
|
||||
+ temps[args[2]].val, args[5]);
|
||||
+ if (args[0] == args[4-tmp]
|
||||
+ || (temps[args[4-tmp]].state == TCG_TEMP_COPY
|
||||
+ && temps[args[4-tmp]].val == args[0])) {
|
||||
+ gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
+ } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
|
||||
+ gen_opc_buf[op_index] = op_to_movi(op);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val,
|
||||
+ nb_temps, nb_globals);
|
||||
+ gen_args += 2;
|
||||
+ } else {
|
||||
+ gen_opc_buf[op_index] = op_to_mov(op);
|
||||
+ tcg_opt_gen_mov(gen_args, args[0], args[4-tmp],
|
||||
+ nb_temps, nb_globals);
|
||||
+ gen_args += 2;
|
||||
+ }
|
||||
+ } else {
|
||||
+ reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ gen_args[0] = args[0];
|
||||
+ gen_args[1] = args[1];
|
||||
+ gen_args[2] = args[2];
|
||||
+ gen_args[3] = args[3];
|
||||
+ gen_args[4] = args[4];
|
||||
+ gen_args[5] = args[5];
|
||||
+ gen_args += 6;
|
||||
+ }
|
||||
+ args += 6;
|
||||
+ break;
|
||||
case INDEX_op_call:
|
||||
nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
|
||||
if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
57
0053-tcg-Optimize-two-address-commutative-operations.patch
Normal file
57
0053-tcg-Optimize-two-address-commutative-operations.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From af2bf6bcc6614622c87d28e9d763b57408c17500 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:13:38 -0700
|
||||
Subject: [PATCH] tcg: Optimize two-address commutative operations
|
||||
|
||||
While swapping constants to the second operand, swap
|
||||
sources matching destinations to the first operand.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 15 ++++++++++++++-
|
||||
1 file changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 26038a6..1be7631 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -334,6 +334,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
const TCGOpDef *def;
|
||||
TCGArg *gen_args;
|
||||
TCGArg tmp;
|
||||
+ TCGCond cond;
|
||||
+
|
||||
/* Array VALS has an element for each temp.
|
||||
If this temp holds a constant then its value is kept in VALS' element.
|
||||
If this temp is a copy of other ones then this equivalence class'
|
||||
@@ -395,13 +397,24 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
}
|
||||
break;
|
||||
CASE_OP_32_64(movcond):
|
||||
+ cond = args[5];
|
||||
if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
&& temps[args[2]].state != TCG_TEMP_CONST) {
|
||||
tmp = args[1];
|
||||
args[1] = args[2];
|
||||
args[2] = tmp;
|
||||
- args[5] = tcg_swap_cond(args[5]);
|
||||
+ cond = tcg_swap_cond(cond);
|
||||
+ }
|
||||
+ /* For movcond, we canonicalize the "false" input reg to match
|
||||
+ the destination reg so that the tcg backend can implement
|
||||
+ a "move if true" operation. */
|
||||
+ if (args[0] == args[3]) {
|
||||
+ tmp = args[3];
|
||||
+ args[3] = args[4];
|
||||
+ args[4] = tmp;
|
||||
+ cond = tcg_invert_cond(cond);
|
||||
}
|
||||
+ args[5] = cond;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
--
|
||||
1.7.12.1
|
||||
|
192
0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch
Normal file
192
0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch
Normal file
@ -0,0 +1,192 @@
|
||||
From b6407e30c30268cdeddec6e2b115f419647cc07f Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Sun, 16 Sep 2012 13:12:21 +0200
|
||||
Subject: [PATCH] gdbstub/sh4: fix build with USE_SOFTFLOAT_STRUCT_TYPES
|
||||
|
||||
We have to use different type to access float values when
|
||||
USE_SOFTFLOAT_STRUCT_TYPES is defined.
|
||||
|
||||
Rework SH4 version of cpu_gdb_{read,write}_register() using
|
||||
a single case, and fixing the coding style. Use ldll_p() and
|
||||
stfl_p() to access float values.
|
||||
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
gdbstub.c | 144 +++++++++++++++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 90 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/gdbstub.c b/gdbstub.c
|
||||
index 5d37dd9..a91709f 100644
|
||||
--- a/gdbstub.c
|
||||
+++ b/gdbstub.c
|
||||
@@ -1226,33 +1226,48 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env,
|
||||
|
||||
static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
- if (n < 8) {
|
||||
+ switch (n) {
|
||||
+ case 0 ... 7:
|
||||
if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
|
||||
GET_REGL(env->gregs[n + 16]);
|
||||
} else {
|
||||
GET_REGL(env->gregs[n]);
|
||||
}
|
||||
- } else if (n < 16) {
|
||||
+ case 8 ... 15:
|
||||
GET_REGL(env->gregs[n]);
|
||||
- } else if (n >= 25 && n < 41) {
|
||||
- GET_REGL(env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
|
||||
- } else if (n >= 43 && n < 51) {
|
||||
- GET_REGL(env->gregs[n - 43]);
|
||||
- } else if (n >= 51 && n < 59) {
|
||||
- GET_REGL(env->gregs[n - (51 - 16)]);
|
||||
- }
|
||||
- switch (n) {
|
||||
- case 16: GET_REGL(env->pc);
|
||||
- case 17: GET_REGL(env->pr);
|
||||
- case 18: GET_REGL(env->gbr);
|
||||
- case 19: GET_REGL(env->vbr);
|
||||
- case 20: GET_REGL(env->mach);
|
||||
- case 21: GET_REGL(env->macl);
|
||||
- case 22: GET_REGL(env->sr);
|
||||
- case 23: GET_REGL(env->fpul);
|
||||
- case 24: GET_REGL(env->fpscr);
|
||||
- case 41: GET_REGL(env->ssr);
|
||||
- case 42: GET_REGL(env->spc);
|
||||
+ case 16:
|
||||
+ GET_REGL(env->pc);
|
||||
+ case 17:
|
||||
+ GET_REGL(env->pr);
|
||||
+ case 18:
|
||||
+ GET_REGL(env->gbr);
|
||||
+ case 19:
|
||||
+ GET_REGL(env->vbr);
|
||||
+ case 20:
|
||||
+ GET_REGL(env->mach);
|
||||
+ case 21:
|
||||
+ GET_REGL(env->macl);
|
||||
+ case 22:
|
||||
+ GET_REGL(env->sr);
|
||||
+ case 23:
|
||||
+ GET_REGL(env->fpul);
|
||||
+ case 24:
|
||||
+ GET_REGL(env->fpscr);
|
||||
+ case 25 ... 40:
|
||||
+ if (env->fpscr & FPSCR_FR) {
|
||||
+ stfl_p(mem_buf, env->fregs[n - 9]);
|
||||
+ } else {
|
||||
+ stfl_p(mem_buf, env->fregs[n - 25]);
|
||||
+ }
|
||||
+ return 4;
|
||||
+ case 41:
|
||||
+ GET_REGL(env->ssr);
|
||||
+ case 42:
|
||||
+ GET_REGL(env->spc);
|
||||
+ case 43 ... 50:
|
||||
+ GET_REGL(env->gregs[n - 43]);
|
||||
+ case 51 ... 58:
|
||||
+ GET_REGL(env->gregs[n - (51 - 16)]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1260,42 +1275,63 @@ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
|
||||
|
||||
static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
- uint32_t tmp;
|
||||
-
|
||||
- tmp = ldl_p(mem_buf);
|
||||
-
|
||||
- if (n < 8) {
|
||||
+ switch (n) {
|
||||
+ case 0 ... 7:
|
||||
if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
|
||||
- env->gregs[n + 16] = tmp;
|
||||
+ env->gregs[n + 16] = ldl_p(mem_buf);
|
||||
} else {
|
||||
- env->gregs[n] = tmp;
|
||||
+ env->gregs[n] = ldl_p(mem_buf);
|
||||
}
|
||||
- return 4;
|
||||
- } else if (n < 16) {
|
||||
- env->gregs[n] = tmp;
|
||||
- return 4;
|
||||
- } else if (n >= 25 && n < 41) {
|
||||
- env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)] = tmp;
|
||||
- return 4;
|
||||
- } else if (n >= 43 && n < 51) {
|
||||
- env->gregs[n - 43] = tmp;
|
||||
- return 4;
|
||||
- } else if (n >= 51 && n < 59) {
|
||||
- env->gregs[n - (51 - 16)] = tmp;
|
||||
- return 4;
|
||||
- }
|
||||
- switch (n) {
|
||||
- case 16: env->pc = tmp; break;
|
||||
- case 17: env->pr = tmp; break;
|
||||
- case 18: env->gbr = tmp; break;
|
||||
- case 19: env->vbr = tmp; break;
|
||||
- case 20: env->mach = tmp; break;
|
||||
- case 21: env->macl = tmp; break;
|
||||
- case 22: env->sr = tmp; break;
|
||||
- case 23: env->fpul = tmp; break;
|
||||
- case 24: env->fpscr = tmp; break;
|
||||
- case 41: env->ssr = tmp; break;
|
||||
- case 42: env->spc = tmp; break;
|
||||
+ break;
|
||||
+ case 8 ... 15:
|
||||
+ env->gregs[n] = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 16:
|
||||
+ env->pc = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 17:
|
||||
+ env->pr = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 18:
|
||||
+ env->gbr = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 19:
|
||||
+ env->vbr = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 20:
|
||||
+ env->mach = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 21:
|
||||
+ env->macl = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 22:
|
||||
+ env->sr = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 23:
|
||||
+ env->fpul = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 24:
|
||||
+ env->fpscr = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 25 ... 40:
|
||||
+ if (env->fpscr & FPSCR_FR) {
|
||||
+ env->fregs[n - 9] = ldfl_p(mem_buf);
|
||||
+ } else {
|
||||
+ env->fregs[n - 25] = ldfl_p(mem_buf);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 41:
|
||||
+ env->ssr = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 42:
|
||||
+ env->spc = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 43 ... 50:
|
||||
+ env->gregs[n - 43] = ldl_p(mem_buf);
|
||||
+ break;
|
||||
+ case 51 ... 58:
|
||||
+ env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
|
||||
+ break;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
35
0055-tcg-Fix-USE_DIRECT_JUMP.patch
Normal file
35
0055-tcg-Fix-USE_DIRECT_JUMP.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 03ddebf0c48dc78070c846b7cfdc2665fe7df854 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Mon, 17 Sep 2012 08:28:52 -0700
|
||||
Subject: [PATCH] tcg: Fix !USE_DIRECT_JUMP
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Commit 6375e09e changed the type of TranslationBlock.tb_next,
|
||||
but failed to change the type of TCGContext.tb_next.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Reviewed-by: Andreas Färber <afaerber@suse.de>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/tcg.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/tcg.h b/tcg/tcg.h
|
||||
index f454107..609ed86 100644
|
||||
--- a/tcg/tcg.h
|
||||
+++ b/tcg/tcg.h
|
||||
@@ -344,7 +344,7 @@ struct TCGContext {
|
||||
|
||||
/* goto_tb support */
|
||||
uint8_t *code_buf;
|
||||
- unsigned long *tb_next;
|
||||
+ uintptr_t *tb_next;
|
||||
uint16_t *tb_next_offset;
|
||||
uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
108
0056-tcg-hppa-Fix-brcond2-and-setcond2.patch
Normal file
108
0056-tcg-hppa-Fix-brcond2-and-setcond2.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 3616400bc0065f7114172ad7801d9d88332ef981 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Tue, 18 Sep 2012 19:59:47 -0700
|
||||
Subject: [PATCH] tcg-hppa: Fix brcond2 and setcond2
|
||||
|
||||
Neither of these functions were performing double-word
|
||||
compares properly.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/hppa/tcg-target.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 42 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
|
||||
index 8b81b70..a76569d 100644
|
||||
--- a/tcg/hppa/tcg-target.c
|
||||
+++ b/tcg/hppa/tcg-target.c
|
||||
@@ -820,19 +820,34 @@ static void tcg_out_comclr(TCGContext *s, int cond, TCGArg ret,
|
||||
tcg_out32(s, op);
|
||||
}
|
||||
|
||||
+static TCGCond const tcg_high_cond[] = {
|
||||
+ [TCG_COND_EQ] = TCG_COND_EQ,
|
||||
+ [TCG_COND_NE] = TCG_COND_NE,
|
||||
+ [TCG_COND_LT] = TCG_COND_LT,
|
||||
+ [TCG_COND_LE] = TCG_COND_LT,
|
||||
+ [TCG_COND_GT] = TCG_COND_GT,
|
||||
+ [TCG_COND_GE] = TCG_COND_GT,
|
||||
+ [TCG_COND_LTU] = TCG_COND_LTU,
|
||||
+ [TCG_COND_LEU] = TCG_COND_LTU,
|
||||
+ [TCG_COND_GTU] = TCG_COND_GTU,
|
||||
+ [TCG_COND_GEU] = TCG_COND_GTU
|
||||
+};
|
||||
+
|
||||
static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah,
|
||||
TCGArg bl, int blconst, TCGArg bh, int bhconst,
|
||||
int label_index)
|
||||
{
|
||||
switch (cond) {
|
||||
case TCG_COND_EQ:
|
||||
+ tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, al, bl, blconst);
|
||||
+ tcg_out_brcond(s, TCG_COND_EQ, ah, bh, bhconst, label_index);
|
||||
+ break;
|
||||
case TCG_COND_NE:
|
||||
- tcg_out_comclr(s, tcg_invert_cond(cond), TCG_REG_R0, al, bl, blconst);
|
||||
- tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
|
||||
+ tcg_out_brcond(s, TCG_COND_NE, al, bl, bhconst, label_index);
|
||||
+ tcg_out_brcond(s, TCG_COND_NE, ah, bh, bhconst, label_index);
|
||||
break;
|
||||
-
|
||||
default:
|
||||
- tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
|
||||
+ tcg_out_brcond(s, tcg_high_cond[cond], ah, bh, bhconst, label_index);
|
||||
tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, ah, bh, bhconst);
|
||||
tcg_out_brcond(s, tcg_unsigned_cond(cond),
|
||||
al, bl, blconst, label_index);
|
||||
@@ -853,9 +868,8 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
|
||||
{
|
||||
int scratch = TCG_REG_R20;
|
||||
|
||||
- if (ret != al && ret != ah
|
||||
- && (blconst || ret != bl)
|
||||
- && (bhconst || ret != bh)) {
|
||||
+ /* Note that the low parts are fully consumed before scratch is set. */
|
||||
+ if (ret != ah && (bhconst || ret != bh)) {
|
||||
scratch = ret;
|
||||
}
|
||||
|
||||
@@ -867,13 +881,32 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
|
||||
tcg_out_movi(s, TCG_TYPE_I32, scratch, cond == TCG_COND_NE);
|
||||
break;
|
||||
|
||||
- default:
|
||||
+ case TCG_COND_GE:
|
||||
+ case TCG_COND_GEU:
|
||||
+ case TCG_COND_LT:
|
||||
+ case TCG_COND_LTU:
|
||||
+ /* Optimize compares with low part zero. */
|
||||
+ if (bl == 0) {
|
||||
+ tcg_out_setcond(s, cond, ret, ah, bh, bhconst);
|
||||
+ return;
|
||||
+ }
|
||||
+ /* FALLTHRU */
|
||||
+
|
||||
+ case TCG_COND_LE:
|
||||
+ case TCG_COND_LEU:
|
||||
+ case TCG_COND_GT:
|
||||
+ case TCG_COND_GTU:
|
||||
+ /* <= : ah < bh | (ah == bh && al <= bl) */
|
||||
tcg_out_setcond(s, tcg_unsigned_cond(cond), scratch, al, bl, blconst);
|
||||
tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
|
||||
tcg_out_movi(s, TCG_TYPE_I32, scratch, 0);
|
||||
- tcg_out_comclr(s, cond, TCG_REG_R0, ah, bh, bhconst);
|
||||
+ tcg_out_comclr(s, tcg_invert_cond(tcg_high_cond[cond]),
|
||||
+ TCG_REG_R0, ah, bh, bhconst);
|
||||
tcg_out_movi(s, TCG_TYPE_I32, scratch, 1);
|
||||
break;
|
||||
+
|
||||
+ default:
|
||||
+ tcg_abort();
|
||||
}
|
||||
|
||||
tcg_out_mov(s, TCG_TYPE_I32, ret, scratch);
|
||||
--
|
||||
1.7.12.1
|
||||
|
249
0057-tcg-hppa-Fix-broken-load-store-helpers.patch
Normal file
249
0057-tcg-hppa-Fix-broken-load-store-helpers.patch
Normal file
@ -0,0 +1,249 @@
|
||||
From c13ecfea174994d3f7f7d392f0faaed6d40efd9e Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Tue, 18 Sep 2012 19:59:48 -0700
|
||||
Subject: [PATCH] tcg-hppa: Fix broken load/store helpers
|
||||
|
||||
The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers
|
||||
was not respecting the ABI requirement for 64-bit values
|
||||
being aligned in registers.
|
||||
|
||||
Mirror the ARM port in use of helper functions to marshal
|
||||
arguments into the correct registers.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/hppa/tcg-target.c | 136 +++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 74 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
|
||||
index a76569d..5385d45 100644
|
||||
--- a/tcg/hppa/tcg-target.c
|
||||
+++ b/tcg/hppa/tcg-target.c
|
||||
@@ -976,10 +976,11 @@ static int tcg_out_tlb_read(TCGContext *s, int r0, int r1, int addrlo,
|
||||
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, r1, offset);
|
||||
}
|
||||
|
||||
- /* Compute the value that ought to appear in the TLB for a hit, namely, the page
|
||||
- of the address. We include the low N bits of the address to catch unaligned
|
||||
- accesses and force them onto the slow path. Do this computation after having
|
||||
- issued the load from the TLB slot to give the load time to complete. */
|
||||
+ /* Compute the value that ought to appear in the TLB for a hit, namely,
|
||||
+ the page of the address. We include the low N bits of the address
|
||||
+ to catch unaligned accesses and force them onto the slow path. Do
|
||||
+ this computation after having issued the load from the TLB slot to
|
||||
+ give the load time to complete. */
|
||||
tcg_out_andi(s, r0, addrlo, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
|
||||
|
||||
/* If not equal, jump to lab_miss. */
|
||||
@@ -992,6 +993,36 @@ static int tcg_out_tlb_read(TCGContext *s, int r0, int r1, int addrlo,
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+static int tcg_out_arg_reg32(TCGContext *s, int argno, TCGArg v, bool vconst)
|
||||
+{
|
||||
+ if (argno < 4) {
|
||||
+ if (vconst) {
|
||||
+ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[argno], v);
|
||||
+ } else {
|
||||
+ tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[argno], v);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (vconst && v != 0) {
|
||||
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R20, v);
|
||||
+ v = TCG_REG_R20;
|
||||
+ }
|
||||
+ tcg_out_st(s, TCG_TYPE_I32, v, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - ((argno - 3) * 4));
|
||||
+ }
|
||||
+ return argno + 1;
|
||||
+}
|
||||
+
|
||||
+static int tcg_out_arg_reg64(TCGContext *s, int argno, TCGArg vl, TCGArg vh)
|
||||
+{
|
||||
+ /* 64-bit arguments must go in even reg pairs and stack slots. */
|
||||
+ if (argno & 1) {
|
||||
+ argno++;
|
||||
+ }
|
||||
+ argno = tcg_out_arg_reg32(s, argno, vl, false);
|
||||
+ argno = tcg_out_arg_reg32(s, argno, vh, false);
|
||||
+ return argno;
|
||||
+}
|
||||
#endif
|
||||
|
||||
static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo_reg, int datahi_reg,
|
||||
@@ -1072,39 +1103,36 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
|
||||
/* Note that addrhi_reg is only used for 64-bit guests. */
|
||||
int addrhi_reg = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
|
||||
int mem_index = *args;
|
||||
- int lab1, lab2, argreg, offset;
|
||||
+ int lab1, lab2, argno, offset;
|
||||
|
||||
lab1 = gen_new_label();
|
||||
lab2 = gen_new_label();
|
||||
|
||||
offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
|
||||
- offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
|
||||
- opc & 3, lab1, offset);
|
||||
+ offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg,
|
||||
+ addrhi_reg, opc & 3, lab1, offset);
|
||||
|
||||
/* TLB Hit. */
|
||||
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
|
||||
+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20,
|
||||
+ (offset ? TCG_REG_R1 : TCG_REG_R25),
|
||||
offsetof(CPUArchState, tlb_table[mem_index][0].addend) - offset);
|
||||
- tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg, TCG_REG_R20, opc);
|
||||
+ tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg,
|
||||
+ TCG_REG_R20, opc);
|
||||
tcg_out_branch(s, lab2, 1);
|
||||
|
||||
/* TLB Miss. */
|
||||
/* label1: */
|
||||
tcg_out_label(s, lab1, s->code_ptr);
|
||||
|
||||
- argreg = TCG_REG_R26;
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrlo_reg);
|
||||
+ argno = 0;
|
||||
+ argno = tcg_out_arg_reg32(s, argno, TCG_AREG0, false);
|
||||
if (TARGET_LONG_BITS == 64) {
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrhi_reg);
|
||||
+ argno = tcg_out_arg_reg64(s, argno, addrlo_reg, addrhi_reg);
|
||||
+ } else {
|
||||
+ argno = tcg_out_arg_reg32(s, argno, addrlo_reg, false);
|
||||
}
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
|
||||
-
|
||||
- /* XXX/FIXME: suboptimal */
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
|
||||
- tcg_target_call_iarg_regs[1]);
|
||||
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
|
||||
- tcg_target_call_iarg_regs[0]);
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
|
||||
- TCG_AREG0);
|
||||
+ argno = tcg_out_arg_reg32(s, argno, mem_index, true);
|
||||
+
|
||||
tcg_out_call(s, qemu_ld_helpers[opc & 3]);
|
||||
|
||||
switch (opc) {
|
||||
@@ -1140,8 +1168,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
|
||||
#endif
|
||||
}
|
||||
|
||||
-static void tcg_out_qemu_st_direct(TCGContext *s, int datalo_reg, int datahi_reg,
|
||||
- int addr_reg, int opc)
|
||||
+static void tcg_out_qemu_st_direct(TCGContext *s, int datalo_reg,
|
||||
+ int datahi_reg, int addr_reg, int opc)
|
||||
{
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
const int bswap = 0;
|
||||
@@ -1194,17 +1222,18 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
|
||||
/* Note that addrhi_reg is only used for 64-bit guests. */
|
||||
int addrhi_reg = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
|
||||
int mem_index = *args;
|
||||
- int lab1, lab2, argreg, offset;
|
||||
+ int lab1, lab2, argno, next, offset;
|
||||
|
||||
lab1 = gen_new_label();
|
||||
lab2 = gen_new_label();
|
||||
|
||||
offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
|
||||
- offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
|
||||
- opc, lab1, offset);
|
||||
+ offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg,
|
||||
+ addrhi_reg, opc, lab1, offset);
|
||||
|
||||
/* TLB Hit. */
|
||||
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
|
||||
+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20,
|
||||
+ (offset ? TCG_REG_R1 : TCG_REG_R25),
|
||||
offsetof(CPUArchState, tlb_table[mem_index][0].addend) - offset);
|
||||
|
||||
/* There are no indexed stores, so we must do this addition explitly.
|
||||
@@ -1217,63 +1246,46 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
|
||||
/* label1: */
|
||||
tcg_out_label(s, lab1, s->code_ptr);
|
||||
|
||||
- argreg = TCG_REG_R26;
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrlo_reg);
|
||||
+ argno = 0;
|
||||
+ argno = tcg_out_arg_reg32(s, argno, TCG_AREG0, false);
|
||||
if (TARGET_LONG_BITS == 64) {
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrhi_reg);
|
||||
+ argno = tcg_out_arg_reg64(s, argno, addrlo_reg, addrhi_reg);
|
||||
+ } else {
|
||||
+ argno = tcg_out_arg_reg32(s, argno, addrlo_reg, false);
|
||||
}
|
||||
|
||||
+ next = (argno < 4 ? tcg_target_call_iarg_regs[argno] : TCG_REG_R20);
|
||||
switch(opc) {
|
||||
case 0:
|
||||
- tcg_out_andi(s, argreg--, datalo_reg, 0xff);
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
|
||||
+ tcg_out_andi(s, next, datalo_reg, 0xff);
|
||||
+ argno = tcg_out_arg_reg32(s, argno, next, false);
|
||||
break;
|
||||
case 1:
|
||||
- tcg_out_andi(s, argreg--, datalo_reg, 0xffff);
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
|
||||
+ tcg_out_andi(s, next, datalo_reg, 0xffff);
|
||||
+ argno = tcg_out_arg_reg32(s, argno, next, false);
|
||||
break;
|
||||
case 2:
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, argreg--, datalo_reg);
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
|
||||
+ argno = tcg_out_arg_reg32(s, argno, datalo_reg, false);
|
||||
break;
|
||||
case 3:
|
||||
- /* Because of the alignment required by the 64-bit data argument,
|
||||
- we will always use R23/R24. Also, we will always run out of
|
||||
- argument registers for storing mem_index, so that will have
|
||||
- to go on the stack. */
|
||||
- if (mem_index == 0) {
|
||||
- argreg = TCG_REG_R0;
|
||||
- } else {
|
||||
- argreg = TCG_REG_R20;
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
|
||||
- }
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R23, datahi_reg);
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R24, datalo_reg);
|
||||
- tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - 4);
|
||||
+ argno = tcg_out_arg_reg64(s, argno, datalo_reg, datahi_reg);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
}
|
||||
+ argno = tcg_out_arg_reg32(s, argno, mem_index, true);
|
||||
|
||||
- /* XXX/FIXME: suboptimal */
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
|
||||
- tcg_target_call_iarg_regs[2]);
|
||||
- tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
|
||||
- tcg_target_call_iarg_regs[1]);
|
||||
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
|
||||
- tcg_target_call_iarg_regs[0]);
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
|
||||
- TCG_AREG0);
|
||||
tcg_out_call(s, qemu_st_helpers[opc]);
|
||||
|
||||
/* label2: */
|
||||
tcg_out_label(s, lab2, s->code_ptr);
|
||||
#else
|
||||
- /* There are no indexed stores, so if GUEST_BASE is set we must do the add
|
||||
- explicitly. Careful to avoid R20, which is used for the bswaps to follow. */
|
||||
+ /* There are no indexed stores, so if GUEST_BASE is set we must do
|
||||
+ the add explicitly. Careful to avoid R20, which is used for the
|
||||
+ bswaps to follow. */
|
||||
if (GUEST_BASE != 0) {
|
||||
- tcg_out_arith(s, TCG_REG_R31, addrlo_reg, TCG_GUEST_BASE_REG, INSN_ADDL);
|
||||
+ tcg_out_arith(s, TCG_REG_R31, addrlo_reg,
|
||||
+ TCG_GUEST_BASE_REG, INSN_ADDL);
|
||||
addrlo_reg = TCG_REG_R31;
|
||||
}
|
||||
tcg_out_qemu_st_direct(s, datalo_reg, datahi_reg, addrlo_reg, opc);
|
||||
--
|
||||
1.7.12.1
|
||||
|
65
0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch
Normal file
65
0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 061d22ad76512e8ec10af89eda1dcc7c185360d2 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:25 +0200
|
||||
Subject: [PATCH] tcg-mips: fix wrong usage of 'Z' constraint
|
||||
|
||||
The 'Z' constraint has been introduced to map the zero register. However
|
||||
when the op also accept a constant, there is no point to accept the zero
|
||||
register in addition.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 74db83d..9293745 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -1453,24 +1453,24 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_st16_i32, { "rZ", "r" } },
|
||||
{ INDEX_op_st_i32, { "rZ", "r" } },
|
||||
|
||||
- { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
|
||||
+ { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
|
||||
{ INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_div_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
|
||||
- { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
|
||||
+ { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
|
||||
|
||||
- { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
|
||||
+ { INDEX_op_and_i32, { "r", "rZ", "rI" } },
|
||||
{ INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_not_i32, { "r", "rZ" } },
|
||||
{ INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
|
||||
{ INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
|
||||
|
||||
- { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
|
||||
- { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
|
||||
- { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
|
||||
+ { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
|
||||
+ { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
|
||||
+ { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
|
||||
|
||||
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
|
||||
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
|
||||
@@ -1479,8 +1479,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
|
||||
|
||||
- { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
|
||||
- { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
|
||||
+ { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
|
||||
+ { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
|
||||
{ INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
|
||||
|
||||
#if TARGET_LONG_BITS == 32
|
||||
--
|
||||
1.7.12.1
|
||||
|
166
0059-tcg-mips-kill-warnings-in-user-mode.patch
Normal file
166
0059-tcg-mips-kill-warnings-in-user-mode.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From e63a3c6c70c9933320c6d8b23c3ea4cf4724d316 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:25 +0200
|
||||
Subject: [PATCH] tcg/mips: kill warnings in user mode
|
||||
|
||||
Recent versions of GCC emit warnings when compiling user mode targets.
|
||||
Kill them by reordering a bit the #ifdef.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 84 ++++++++++++++++++++++++++-------------------------
|
||||
1 file changed, 43 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 9293745..a09c0d6 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -842,18 +842,16 @@ static const void * const qemu_st_helpers[4] = {
|
||||
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
int opc)
|
||||
{
|
||||
- int addr_regl, addr_meml;
|
||||
- int data_regl, data_regh, data_reg1, data_reg2;
|
||||
- int mem_index, s_bits;
|
||||
+ int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
void *label1_ptr, *label2_ptr;
|
||||
int arg_num;
|
||||
-#endif
|
||||
-#if TARGET_LONG_BITS == 64
|
||||
-# if defined(CONFIG_SOFTMMU)
|
||||
+ int mem_index, s_bits;
|
||||
+ int addr_meml;
|
||||
+# if TARGET_LONG_BITS == 64
|
||||
uint8_t *label3_ptr;
|
||||
-# endif
|
||||
int addr_regh, addr_memh;
|
||||
+# endif
|
||||
#endif
|
||||
data_regl = *args++;
|
||||
if (opc == 3)
|
||||
@@ -861,11 +859,22 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
else
|
||||
data_regh = 0;
|
||||
addr_regl = *args++;
|
||||
-#if TARGET_LONG_BITS == 64
|
||||
+#if defined(CONFIG_SOFTMMU)
|
||||
+# if TARGET_LONG_BITS == 64
|
||||
addr_regh = *args++;
|
||||
-#endif
|
||||
+# if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
+ addr_memh = 0;
|
||||
+ addr_meml = 4;
|
||||
+# else
|
||||
+ addr_memh = 4;
|
||||
+ addr_meml = 0;
|
||||
+# endif
|
||||
+# else
|
||||
+ addr_meml = 0;
|
||||
+# endif
|
||||
mem_index = *args;
|
||||
s_bits = opc & 3;
|
||||
+#endif
|
||||
|
||||
if (opc == 3) {
|
||||
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
@@ -879,18 +888,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
data_reg1 = data_regl;
|
||||
data_reg2 = 0;
|
||||
}
|
||||
-#if TARGET_LONG_BITS == 64
|
||||
-# if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
- addr_memh = 0;
|
||||
- addr_meml = 4;
|
||||
-# else
|
||||
- addr_memh = 4;
|
||||
- addr_meml = 0;
|
||||
-# endif
|
||||
-#else
|
||||
- addr_meml = 0;
|
||||
-#endif
|
||||
-
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
|
||||
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
|
||||
@@ -1029,50 +1026,55 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||
int opc)
|
||||
{
|
||||
- int addr_regl, addr_meml;
|
||||
- int data_regl, data_regh, data_reg1, data_reg2;
|
||||
- int mem_index, s_bits;
|
||||
+ int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
uint8_t *label1_ptr, *label2_ptr;
|
||||
int arg_num;
|
||||
+ int mem_index, s_bits;
|
||||
+ int addr_meml;
|
||||
#endif
|
||||
#if TARGET_LONG_BITS == 64
|
||||
# if defined(CONFIG_SOFTMMU)
|
||||
uint8_t *label3_ptr;
|
||||
-# endif
|
||||
int addr_regh, addr_memh;
|
||||
+# endif
|
||||
#endif
|
||||
-
|
||||
data_regl = *args++;
|
||||
if (opc == 3) {
|
||||
data_regh = *args++;
|
||||
-#if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
- data_reg1 = data_regh;
|
||||
- data_reg2 = data_regl;
|
||||
-#else
|
||||
- data_reg1 = data_regl;
|
||||
- data_reg2 = data_regh;
|
||||
-#endif
|
||||
} else {
|
||||
- data_reg1 = data_regl;
|
||||
- data_reg2 = 0;
|
||||
data_regh = 0;
|
||||
}
|
||||
addr_regl = *args++;
|
||||
-#if TARGET_LONG_BITS == 64
|
||||
+#if defined(CONFIG_SOFTMMU)
|
||||
+# if TARGET_LONG_BITS == 64
|
||||
addr_regh = *args++;
|
||||
-# if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
+# if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
addr_memh = 0;
|
||||
addr_meml = 4;
|
||||
-# else
|
||||
+# else
|
||||
addr_memh = 4;
|
||||
addr_meml = 0;
|
||||
-# endif
|
||||
-#else
|
||||
+# endif
|
||||
+# else
|
||||
addr_meml = 0;
|
||||
-#endif
|
||||
+# endif
|
||||
mem_index = *args;
|
||||
s_bits = opc;
|
||||
+#endif
|
||||
+
|
||||
+ if (opc == 3) {
|
||||
+#if defined(TCG_TARGET_WORDS_BIGENDIAN)
|
||||
+ data_reg1 = data_regh;
|
||||
+ data_reg2 = data_regl;
|
||||
+#else
|
||||
+ data_reg1 = data_regl;
|
||||
+ data_reg2 = data_regh;
|
||||
+#endif
|
||||
+ } else {
|
||||
+ data_reg1 = data_regl;
|
||||
+ data_reg2 = 0;
|
||||
+ }
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
|
||||
--
|
||||
1.7.12.1
|
||||
|
246
0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch
Normal file
246
0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch
Normal file
@ -0,0 +1,246 @@
|
||||
From 7b817977fbb87ee2e34018d92b64907197974a75 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: use TCGArg or TCGReg instead of int
|
||||
|
||||
Instead of int, use the correct TCGArg and TCGReg type: TCGReg when
|
||||
representing a TCG target register, TCGArg when representing the latter
|
||||
or a constant.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 63 ++++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 35 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index a09c0d6..8b38f98 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -68,7 +68,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
|
||||
#endif
|
||||
|
||||
/* check if we really need so many registers :P */
|
||||
-static const int tcg_target_reg_alloc_order[] = {
|
||||
+static const TCGReg tcg_target_reg_alloc_order[] = {
|
||||
TCG_REG_S0,
|
||||
TCG_REG_S1,
|
||||
TCG_REG_S2,
|
||||
@@ -94,14 +94,14 @@ static const int tcg_target_reg_alloc_order[] = {
|
||||
TCG_REG_V1
|
||||
};
|
||||
|
||||
-static const int tcg_target_call_iarg_regs[4] = {
|
||||
+static const TCGReg tcg_target_call_iarg_regs[4] = {
|
||||
TCG_REG_A0,
|
||||
TCG_REG_A1,
|
||||
TCG_REG_A2,
|
||||
TCG_REG_A3
|
||||
};
|
||||
|
||||
-static const int tcg_target_call_oarg_regs[2] = {
|
||||
+static const TCGReg tcg_target_call_oarg_regs[2] = {
|
||||
TCG_REG_V0,
|
||||
TCG_REG_V1
|
||||
};
|
||||
@@ -327,7 +327,8 @@ enum {
|
||||
/*
|
||||
* Type reg
|
||||
*/
|
||||
-static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
|
||||
+static inline void tcg_out_opc_reg(TCGContext *s, int opc,
|
||||
+ TCGReg rd, TCGReg rs, TCGReg rt)
|
||||
{
|
||||
int32_t inst;
|
||||
|
||||
@@ -341,7 +342,8 @@ static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int r
|
||||
/*
|
||||
* Type immediate
|
||||
*/
|
||||
-static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
|
||||
+static inline void tcg_out_opc_imm(TCGContext *s, int opc,
|
||||
+ TCGReg rt, TCGReg rs, TCGArg imm)
|
||||
{
|
||||
int32_t inst;
|
||||
|
||||
@@ -355,7 +357,8 @@ static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int i
|
||||
/*
|
||||
* Type branch
|
||||
*/
|
||||
-static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
|
||||
+static inline void tcg_out_opc_br(TCGContext *s, int opc,
|
||||
+ TCGReg rt, TCGReg rs)
|
||||
{
|
||||
/* We pay attention here to not modify the branch target by reading
|
||||
the existing value and using it again. This ensure that caches and
|
||||
@@ -368,7 +371,8 @@ static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
|
||||
/*
|
||||
* Type sa
|
||||
*/
|
||||
-static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
|
||||
+static inline void tcg_out_opc_sa(TCGContext *s, int opc,
|
||||
+ TCGReg rd, TCGReg rt, TCGArg sa)
|
||||
{
|
||||
int32_t inst;
|
||||
|
||||
@@ -407,7 +411,7 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
|
||||
}
|
||||
}
|
||||
|
||||
-static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
|
||||
+static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
/* ret and arg can't be register at */
|
||||
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
|
||||
@@ -422,7 +426,7 @@ static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
|
||||
}
|
||||
|
||||
-static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
|
||||
+static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
/* ret and arg can't be register at */
|
||||
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
|
||||
@@ -437,7 +441,7 @@ static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
|
||||
}
|
||||
|
||||
-static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
|
||||
+static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
/* ret and arg must be different and can't be register at */
|
||||
if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
|
||||
@@ -458,7 +462,7 @@ static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
|
||||
}
|
||||
|
||||
-static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
|
||||
+static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
#ifdef _MIPS_ARCH_MIPS32R2
|
||||
tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
|
||||
@@ -468,7 +472,7 @@ static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
-static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
|
||||
+static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
#ifdef _MIPS_ARCH_MIPS32R2
|
||||
tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
|
||||
@@ -478,8 +482,8 @@ static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
-static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
|
||||
- int arg1, tcg_target_long arg2)
|
||||
+static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
|
||||
+ TCGReg arg1, TCGArg arg2)
|
||||
{
|
||||
if (arg2 == (int16_t) arg2) {
|
||||
tcg_out_opc_imm(s, opc, arg, arg1, arg2);
|
||||
@@ -502,7 +506,7 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
|
||||
tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
|
||||
}
|
||||
|
||||
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
|
||||
+static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
|
||||
{
|
||||
if (val == (int16_t)val) {
|
||||
tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
|
||||
@@ -543,7 +547,7 @@ DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
|
||||
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
|
||||
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
|
||||
tcg_out_movi(s, TCG_TYPE_I32, A, arg);
|
||||
-DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg)
|
||||
+DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
|
||||
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
|
||||
|
||||
/* We don't use the macro for this one to avoid an unnecessary reg-reg
|
||||
@@ -573,8 +577,8 @@ static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
|
||||
#endif
|
||||
}
|
||||
|
||||
-static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
|
||||
- int arg2, int label_index)
|
||||
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
|
||||
+ TCGArg arg2, int label_index)
|
||||
{
|
||||
TCGLabel *l = &s->labels[label_index];
|
||||
|
||||
@@ -631,8 +635,9 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
|
||||
|
||||
/* XXX: we implement it at the target level to avoid having to
|
||||
handle cross basic blocks temporaries */
|
||||
-static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
|
||||
- int arg2, int arg3, int arg4, int label_index)
|
||||
+static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
|
||||
+ TCGArg arg2, TCGArg arg3, TCGArg arg4,
|
||||
+ int label_index)
|
||||
{
|
||||
void *label_ptr;
|
||||
|
||||
@@ -694,8 +699,8 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
|
||||
reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
|
||||
}
|
||||
|
||||
-static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
|
||||
- int arg1, int arg2)
|
||||
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
+ TCGArg arg1, TCGArg arg2)
|
||||
{
|
||||
switch (cond) {
|
||||
case TCG_COND_EQ:
|
||||
@@ -754,8 +759,8 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
|
||||
|
||||
/* XXX: we implement it at the target level to avoid having to
|
||||
handle cross basic blocks temporaries */
|
||||
-static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
|
||||
- int arg1, int arg2, int arg3, int arg4)
|
||||
+static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
+ TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
|
||||
{
|
||||
switch (cond) {
|
||||
case TCG_COND_EQ:
|
||||
@@ -842,7 +847,7 @@ static const void * const qemu_st_helpers[4] = {
|
||||
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
int opc)
|
||||
{
|
||||
- int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
|
||||
+ TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
void *label1_ptr, *label2_ptr;
|
||||
int arg_num;
|
||||
@@ -850,7 +855,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
int addr_meml;
|
||||
# if TARGET_LONG_BITS == 64
|
||||
uint8_t *label3_ptr;
|
||||
- int addr_regh, addr_memh;
|
||||
+ TCGReg addr_regh;
|
||||
+ int addr_memh;
|
||||
# endif
|
||||
#endif
|
||||
data_regl = *args++;
|
||||
@@ -1026,7 +1032,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||
int opc)
|
||||
{
|
||||
- int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
|
||||
+ TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
uint8_t *label1_ptr, *label2_ptr;
|
||||
int arg_num;
|
||||
@@ -1036,7 +1042,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||
#if TARGET_LONG_BITS == 64
|
||||
# if defined(CONFIG_SOFTMMU)
|
||||
uint8_t *label3_ptr;
|
||||
- int addr_regh, addr_memh;
|
||||
+ TCGReg addr_regh;
|
||||
+ int addr_memh;
|
||||
# endif
|
||||
#endif
|
||||
data_regl = *args++;
|
||||
--
|
||||
1.7.12.1
|
||||
|
37
0061-tcg-mips-don-t-use-global-pointer.patch
Normal file
37
0061-tcg-mips-don-t-use-global-pointer.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 9a4f545e4526f946613548a427fcab4c2a089ac0 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: don't use global pointer
|
||||
|
||||
Don't use the global pointer in TCG, in case helpers try access global
|
||||
variables.
|
||||
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 8b38f98..0ea6a76 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -1529,7 +1529,6 @@ static int tcg_target_callee_save_regs[] = {
|
||||
TCG_REG_S5,
|
||||
TCG_REG_S6,
|
||||
TCG_REG_S7,
|
||||
- TCG_REG_GP,
|
||||
TCG_REG_FP,
|
||||
TCG_REG_RA, /* should be last for ABI compliance */
|
||||
};
|
||||
@@ -1595,6 +1594,7 @@ static void tcg_target_init(TCGContext *s)
|
||||
tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0); /* internal use */
|
||||
tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return address */
|
||||
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
|
||||
|
||||
tcg_add_target_add_op_defs(mips_op_defs);
|
||||
tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
|
||||
--
|
||||
1.7.12.1
|
||||
|
47
0062-tcg-mips-use-stack-for-TCG-temps.patch
Normal file
47
0062-tcg-mips-use-stack-for-TCG-temps.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From c914ae50df4dc2f2ab589c87c0cd2ce2f14d9639 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: use stack for TCG temps
|
||||
|
||||
Use stack instead of temp_buf array in CPUState for TCG
|
||||
temps.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 0ea6a76..c05169f 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
{
|
||||
int i, frame_size;
|
||||
|
||||
- /* reserve some stack space */
|
||||
+ /* reserve some stack space, also for TCG temps. */
|
||||
frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
|
||||
- + TCG_STATIC_CALL_ARGS_SIZE;
|
||||
+ + TCG_STATIC_CALL_ARGS_SIZE
|
||||
+ + CPU_TEMP_BUF_NLONGS * sizeof(long);
|
||||
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
|
||||
~(TCG_TARGET_STACK_ALIGN - 1);
|
||||
+ tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
|
||||
+ + TCG_STATIC_CALL_ARGS_SIZE,
|
||||
+ CPU_TEMP_BUF_NLONGS * sizeof(long));
|
||||
|
||||
/* TB prologue */
|
||||
tcg_out_addi(s, TCG_REG_SP, -frame_size);
|
||||
@@ -1597,6 +1601,4 @@ static void tcg_target_init(TCGContext *s)
|
||||
tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP); /* global pointer */
|
||||
|
||||
tcg_add_target_add_op_defs(mips_op_defs);
|
||||
- tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
|
||||
- CPU_TEMP_BUF_NLONGS * sizeof(long));
|
||||
}
|
||||
--
|
||||
1.7.12.1
|
||||
|
99
0063-tcg-mips-optimize-brcond-arg-0.patch
Normal file
99
0063-tcg-mips-optimize-brcond-arg-0.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From e30cf829e9d8200364b53b9189c76d2155a32876 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: optimize brcond arg, 0
|
||||
|
||||
MIPS has some conditional branch instructions when comparing with zero.
|
||||
Use them.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 38 ++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 30 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index c05169f..6aa4527 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -278,6 +278,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
|
||||
enum {
|
||||
OPC_BEQ = 0x04 << 26,
|
||||
OPC_BNE = 0x05 << 26,
|
||||
+ OPC_BLEZ = 0x06 << 26,
|
||||
+ OPC_BGTZ = 0x07 << 26,
|
||||
OPC_ADDIU = 0x09 << 26,
|
||||
OPC_SLTI = 0x0A << 26,
|
||||
OPC_SLTIU = 0x0B << 26,
|
||||
@@ -319,6 +321,10 @@ enum {
|
||||
OPC_SLT = OPC_SPECIAL | 0x2A,
|
||||
OPC_SLTU = OPC_SPECIAL | 0x2B,
|
||||
|
||||
+ OPC_REGIMM = 0x01 << 26,
|
||||
+ OPC_BLTZ = OPC_REGIMM | (0x00 << 16),
|
||||
+ OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
|
||||
+
|
||||
OPC_SPECIAL3 = 0x1f << 26,
|
||||
OPC_SEB = OPC_SPECIAL3 | 0x420,
|
||||
OPC_SEH = OPC_SPECIAL3 | 0x620,
|
||||
@@ -590,32 +596,48 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
|
||||
tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
|
||||
break;
|
||||
case TCG_COND_LT:
|
||||
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
|
||||
- tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ if (arg2 == 0) {
|
||||
+ tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
|
||||
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ }
|
||||
break;
|
||||
case TCG_COND_LTU:
|
||||
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
|
||||
tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
|
||||
break;
|
||||
case TCG_COND_GE:
|
||||
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
|
||||
- tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ if (arg2 == 0) {
|
||||
+ tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
|
||||
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ }
|
||||
break;
|
||||
case TCG_COND_GEU:
|
||||
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
|
||||
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
|
||||
break;
|
||||
case TCG_COND_LE:
|
||||
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
|
||||
- tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ if (arg2 == 0) {
|
||||
+ tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
|
||||
+ tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ }
|
||||
break;
|
||||
case TCG_COND_LEU:
|
||||
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
|
||||
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
|
||||
break;
|
||||
case TCG_COND_GT:
|
||||
- tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
|
||||
- tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ if (arg2 == 0) {
|
||||
+ tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
|
||||
+ tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
|
||||
+ }
|
||||
break;
|
||||
case TCG_COND_GTU:
|
||||
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
|
||||
--
|
||||
1.7.12.1
|
||||
|
161
0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch
Normal file
161
0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From 879794c3d3974b1206bbc52011c8f2525709f396 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: optimize bswap{16,16s,32} on MIPS32R2
|
||||
|
||||
bswap operations can be optimized on MIPS32 Release 2 using the ROTR,
|
||||
WSBH and SEH instructions. We can't use the non-R2 code to implement the
|
||||
ops due to registers constraints, so don't define the corresponding
|
||||
TCG_TARGET_HAS_bswap* values.
|
||||
|
||||
Also bswap16* operations are supposed to be called with the 16 high bits
|
||||
zeroed. This is the case everywhere (including for TCG by definition)
|
||||
except when called from the store helper. Remove the AND instructions from
|
||||
bswap16* and move it there.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 34 +++++++++++++++++++++++++++++-----
|
||||
tcg/mips/tcg-target.h | 11 +++++++++--
|
||||
2 files changed, 38 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 6aa4527..8b2f9fc 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -326,6 +326,7 @@ enum {
|
||||
OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
|
||||
|
||||
OPC_SPECIAL3 = 0x1f << 26,
|
||||
+ OPC_WSBH = OPC_SPECIAL3 | 0x0a0,
|
||||
OPC_SEB = OPC_SPECIAL3 | 0x420,
|
||||
OPC_SEH = OPC_SPECIAL3 | 0x620,
|
||||
};
|
||||
@@ -419,36 +420,45 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
|
||||
|
||||
static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
+#ifdef _MIPS_ARCH_MIPS32R2
|
||||
+ tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
|
||||
+#else
|
||||
/* ret and arg can't be register at */
|
||||
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
|
||||
tcg_abort();
|
||||
}
|
||||
|
||||
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
|
||||
- tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
|
||||
-
|
||||
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
|
||||
tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
+#ifdef _MIPS_ARCH_MIPS32R2
|
||||
+ tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
|
||||
+ tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
|
||||
+#else
|
||||
/* ret and arg can't be register at */
|
||||
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
|
||||
tcg_abort();
|
||||
}
|
||||
|
||||
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
|
||||
- tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
|
||||
-
|
||||
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
|
||||
tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
+#ifdef _MIPS_ARCH_MIPS32R2
|
||||
+ tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
|
||||
+ tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
|
||||
+#else
|
||||
/* ret and arg must be different and can't be register at */
|
||||
if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
|
||||
tcg_abort();
|
||||
@@ -466,6 +476,7 @@ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
|
||||
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
|
||||
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
|
||||
@@ -1188,7 +1199,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||
break;
|
||||
case 1:
|
||||
if (TCG_NEED_BSWAP) {
|
||||
- tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
|
||||
+ tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_T0, data_reg1, 0xffff);
|
||||
+ tcg_out_bswap16(s, TCG_REG_T0, TCG_REG_T0);
|
||||
tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
|
||||
} else {
|
||||
tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
|
||||
@@ -1409,6 +1421,15 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
}
|
||||
break;
|
||||
|
||||
+ /* The bswap routines do not work on non-R2 CPU. In that case
|
||||
+ we let TCG generating the corresponding code. */
|
||||
+ case INDEX_op_bswap16_i32:
|
||||
+ tcg_out_bswap16(s, args[0], args[1]);
|
||||
+ break;
|
||||
+ case INDEX_op_bswap32_i32:
|
||||
+ tcg_out_bswap32(s, args[0], args[1]);
|
||||
+ break;
|
||||
+
|
||||
case INDEX_op_ext8s_i32:
|
||||
tcg_out_ext8s(s, args[0], args[1]);
|
||||
break;
|
||||
@@ -1503,6 +1524,9 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_shr_i32, { "r", "rZ", "ri" } },
|
||||
{ INDEX_op_sar_i32, { "r", "rZ", "ri" } },
|
||||
|
||||
+ { INDEX_op_bswap16_i32, { "r", "r" } },
|
||||
+ { INDEX_op_bswap32_i32, { "r", "r" } },
|
||||
+
|
||||
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
|
||||
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
|
||||
index 9c68a32..c5c13f7 100644
|
||||
--- a/tcg/mips/tcg-target.h
|
||||
+++ b/tcg/mips/tcg-target.h
|
||||
@@ -83,8 +83,6 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_rot_i32 0
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
-#define TCG_TARGET_HAS_bswap32_i32 0
|
||||
-#define TCG_TARGET_HAS_bswap16_i32 0
|
||||
#define TCG_TARGET_HAS_andc_i32 0
|
||||
#define TCG_TARGET_HAS_orc_i32 0
|
||||
#define TCG_TARGET_HAS_eqv_i32 0
|
||||
@@ -92,6 +90,15 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_deposit_i32 0
|
||||
#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
+/* optional instructions only implemented on MIPS32R2 */
|
||||
+#ifdef _MIPS_ARCH_MIPS32R2
|
||||
+#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
+#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
+#else
|
||||
+#define TCG_TARGET_HAS_bswap16_i32 0
|
||||
+#define TCG_TARGET_HAS_bswap32_i32 0
|
||||
+#endif
|
||||
+
|
||||
/* optional instructions automatically implemented */
|
||||
#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */
|
||||
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
|
||||
--
|
||||
1.7.12.1
|
||||
|
92
0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch
Normal file
92
0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From d19858a5515cd15dabf88b8f180754c1c3f3eb76 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: implement rotl/rotr ops on MIPS32R2
|
||||
|
||||
rotr operations can be optimized on MIPS32 Release 2 using the ROTR and
|
||||
ROTRV instructions. Also implemented rotl operations by subtracting the
|
||||
shift from 32.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 20 ++++++++++++++++++++
|
||||
tcg/mips/tcg-target.h | 3 ++-
|
||||
2 files changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 8b2f9fc..592e42a 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -300,9 +300,11 @@ enum {
|
||||
OPC_SPECIAL = 0x00 << 26,
|
||||
OPC_SLL = OPC_SPECIAL | 0x00,
|
||||
OPC_SRL = OPC_SPECIAL | 0x02,
|
||||
+ OPC_ROTR = OPC_SPECIAL | (0x01 << 21) | 0x02,
|
||||
OPC_SRA = OPC_SPECIAL | 0x03,
|
||||
OPC_SLLV = OPC_SPECIAL | 0x04,
|
||||
OPC_SRLV = OPC_SPECIAL | 0x06,
|
||||
+ OPC_ROTRV = OPC_SPECIAL | (0x01 << 6) | 0x06,
|
||||
OPC_SRAV = OPC_SPECIAL | 0x07,
|
||||
OPC_JR = OPC_SPECIAL | 0x08,
|
||||
OPC_JALR = OPC_SPECIAL | 0x09,
|
||||
@@ -1420,6 +1422,22 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
|
||||
}
|
||||
break;
|
||||
+ case INDEX_op_rotl_i32:
|
||||
+ if (const_args[2]) {
|
||||
+ tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
|
||||
+ } else {
|
||||
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
|
||||
+ tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
|
||||
+ tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
|
||||
+ }
|
||||
+ break;
|
||||
+ case INDEX_op_rotr_i32:
|
||||
+ if (const_args[2]) {
|
||||
+ tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
|
||||
+ }
|
||||
+ break;
|
||||
|
||||
/* The bswap routines do not work on non-R2 CPU. In that case
|
||||
we let TCG generating the corresponding code. */
|
||||
@@ -1523,6 +1541,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_shl_i32, { "r", "rZ", "ri" } },
|
||||
{ INDEX_op_shr_i32, { "r", "rZ", "ri" } },
|
||||
{ INDEX_op_sar_i32, { "r", "rZ", "ri" } },
|
||||
+ { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
|
||||
+ { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
|
||||
|
||||
{ INDEX_op_bswap16_i32, { "r", "r" } },
|
||||
{ INDEX_op_bswap32_i32, { "r", "r" } },
|
||||
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
|
||||
index c5c13f7..470314c 100644
|
||||
--- a/tcg/mips/tcg-target.h
|
||||
+++ b/tcg/mips/tcg-target.h
|
||||
@@ -80,7 +80,6 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_div_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
#define TCG_TARGET_HAS_nor_i32 1
|
||||
-#define TCG_TARGET_HAS_rot_i32 0
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_andc_i32 0
|
||||
@@ -94,9 +93,11 @@ typedef enum {
|
||||
#ifdef _MIPS_ARCH_MIPS32R2
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
+#define TCG_TARGET_HAS_rot_i32 1
|
||||
#else
|
||||
#define TCG_TARGET_HAS_bswap16_i32 0
|
||||
#define TCG_TARGET_HAS_bswap32_i32 0
|
||||
+#define TCG_TARGET_HAS_rot_i32 0
|
||||
#endif
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
--
|
||||
1.7.12.1
|
||||
|
77
0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch
Normal file
77
0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 7c3e573b364a65d4abce5266c376f4e77624b039 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: implement deposit op on MIPS32R2
|
||||
|
||||
deposit operations can be optimized on MIPS32 Release 2 using the INS
|
||||
instruction.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 8 ++++++++
|
||||
tcg/mips/tcg-target.h | 3 ++-
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index 592e42a..b2e1056 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -328,6 +328,7 @@ enum {
|
||||
OPC_BGEZ = OPC_REGIMM | (0x01 << 16),
|
||||
|
||||
OPC_SPECIAL3 = 0x1f << 26,
|
||||
+ OPC_INS = OPC_SPECIAL3 | 0x004,
|
||||
OPC_WSBH = OPC_SPECIAL3 | 0x0a0,
|
||||
OPC_SEB = OPC_SPECIAL3 | 0x420,
|
||||
OPC_SEH = OPC_SPECIAL3 | 0x620,
|
||||
@@ -1455,6 +1456,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
tcg_out_ext16s(s, args[0], args[1]);
|
||||
break;
|
||||
|
||||
+ case INDEX_op_deposit_i32:
|
||||
+ tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
|
||||
+ ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
|
||||
+ break;
|
||||
+
|
||||
case INDEX_op_brcond_i32:
|
||||
tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
|
||||
break;
|
||||
@@ -1550,6 +1556,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
|
||||
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
|
||||
|
||||
+ { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
|
||||
+
|
||||
{ INDEX_op_brcond_i32, { "rZ", "rZ" } },
|
||||
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
|
||||
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
|
||||
index 470314c..897a737 100644
|
||||
--- a/tcg/mips/tcg-target.h
|
||||
+++ b/tcg/mips/tcg-target.h
|
||||
@@ -86,7 +86,6 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_orc_i32 0
|
||||
#define TCG_TARGET_HAS_eqv_i32 0
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
-#define TCG_TARGET_HAS_deposit_i32 0
|
||||
#define TCG_TARGET_HAS_movcond_i32 0
|
||||
|
||||
/* optional instructions only implemented on MIPS32R2 */
|
||||
@@ -94,10 +93,12 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_rot_i32 1
|
||||
+#define TCG_TARGET_HAS_deposit_i32 1
|
||||
#else
|
||||
#define TCG_TARGET_HAS_bswap16_i32 0
|
||||
#define TCG_TARGET_HAS_bswap32_i32 0
|
||||
#define TCG_TARGET_HAS_rot_i32 0
|
||||
+#define TCG_TARGET_HAS_deposit_i32 0
|
||||
#endif
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
--
|
||||
1.7.12.1
|
||||
|
140
0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch
Normal file
140
0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From 552720cea4c1ca99dd1919cb8a80b6b8f3b13cda Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 18:20:26 +0200
|
||||
Subject: [PATCH] tcg/mips: implement movcond op on MIPS32R2
|
||||
|
||||
movcond operation can be implemented on MIPS32 Release 2 using the MOVN,
|
||||
MOVZ, SLT and SLTU instructions.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/mips/tcg-target.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
tcg/mips/tcg-target.h | 8 ++++++
|
||||
2 files changed, 77 insertions(+)
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
|
||||
index b2e1056..c272b38 100644
|
||||
--- a/tcg/mips/tcg-target.c
|
||||
+++ b/tcg/mips/tcg-target.c
|
||||
@@ -308,6 +308,8 @@ enum {
|
||||
OPC_SRAV = OPC_SPECIAL | 0x07,
|
||||
OPC_JR = OPC_SPECIAL | 0x08,
|
||||
OPC_JALR = OPC_SPECIAL | 0x09,
|
||||
+ OPC_MOVZ = OPC_SPECIAL | 0x0A,
|
||||
+ OPC_MOVN = OPC_SPECIAL | 0x0B,
|
||||
OPC_MFHI = OPC_SPECIAL | 0x10,
|
||||
OPC_MFLO = OPC_SPECIAL | 0x12,
|
||||
OPC_MULT = OPC_SPECIAL | 0x18,
|
||||
@@ -735,6 +737,68 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
|
||||
reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
|
||||
}
|
||||
|
||||
+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
+ TCGArg c1, TCGArg c2, TCGArg v)
|
||||
+{
|
||||
+ switch (cond) {
|
||||
+ case TCG_COND_EQ:
|
||||
+ if (c1 == 0) {
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c2);
|
||||
+ } else if (c2 == 0) {
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c1);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
|
||||
+ }
|
||||
+ break;
|
||||
+ case TCG_COND_NE:
|
||||
+ if (c1 == 0) {
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, c2);
|
||||
+ } else if (c2 == 0) {
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, c1);
|
||||
+ } else {
|
||||
+ tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
|
||||
+ }
|
||||
+ break;
|
||||
+ case TCG_COND_LT:
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_LTU:
|
||||
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_GE:
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_GEU:
|
||||
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_LE:
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_LEU:
|
||||
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_GT:
|
||||
+ tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ case TCG_COND_GTU:
|
||||
+ tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
|
||||
+ tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
|
||||
+ break;
|
||||
+ default:
|
||||
+ tcg_abort();
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
|
||||
TCGArg arg1, TCGArg arg2)
|
||||
{
|
||||
@@ -1468,6 +1532,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
|
||||
break;
|
||||
|
||||
+ case INDEX_op_movcond_i32:
|
||||
+ tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
|
||||
+ break;
|
||||
+
|
||||
case INDEX_op_setcond_i32:
|
||||
tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
|
||||
break;
|
||||
@@ -1559,6 +1627,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
|
||||
{ INDEX_op_deposit_i32, { "r", "0", "rZ" } },
|
||||
|
||||
{ INDEX_op_brcond_i32, { "rZ", "rZ" } },
|
||||
+ { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
|
||||
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
|
||||
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
|
||||
|
||||
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
|
||||
index 897a737..d147e70 100644
|
||||
--- a/tcg/mips/tcg-target.h
|
||||
+++ b/tcg/mips/tcg-target.h
|
||||
@@ -86,7 +86,15 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_orc_i32 0
|
||||
#define TCG_TARGET_HAS_eqv_i32 0
|
||||
#define TCG_TARGET_HAS_nand_i32 0
|
||||
+
|
||||
+/* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
|
||||
+#if defined(_MIPS_ARCH_MIPS4) || defined(_MIPS_ARCH_MIPS32) || \
|
||||
+ defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_LOONGSON2E) || \
|
||||
+ defined(_MIPS_ARCH_LOONGSON2F)
|
||||
+#define TCG_TARGET_HAS_movcond_i32 1
|
||||
+#else
|
||||
#define TCG_TARGET_HAS_movcond_i32 0
|
||||
+#endif
|
||||
|
||||
/* optional instructions only implemented on MIPS32R2 */
|
||||
#ifdef _MIPS_ARCH_MIPS32R2
|
||||
--
|
||||
1.7.12.1
|
||||
|
62
0068-tcg-optimize-remove-TCG_TEMP_ANY.patch
Normal file
62
0068-tcg-optimize-remove-TCG_TEMP_ANY.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 848750a4acf9ea5c473be596d41720e702d770f0 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Mon, 10 Sep 2012 23:51:42 +0200
|
||||
Subject: [PATCH] tcg/optimize: remove TCG_TEMP_ANY
|
||||
|
||||
TCG_TEMP_ANY has no different meaning than TCG_TEMP_UNDEF, so use
|
||||
the later instead.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 11 +++++------
|
||||
1 file changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 1be7631..308b7f9 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -39,8 +39,7 @@ typedef enum {
|
||||
TCG_TEMP_UNDEF = 0,
|
||||
TCG_TEMP_CONST,
|
||||
TCG_TEMP_COPY,
|
||||
- TCG_TEMP_HAS_COPY,
|
||||
- TCG_TEMP_ANY
|
||||
+ TCG_TEMP_HAS_COPY
|
||||
} tcg_temp_state;
|
||||
|
||||
struct tcg_temp_info {
|
||||
@@ -52,7 +51,7 @@ struct tcg_temp_info {
|
||||
|
||||
static struct tcg_temp_info temps[TCG_MAX_TEMPS];
|
||||
|
||||
-/* Reset TEMP's state to TCG_TEMP_ANY. If TEMP was a representative of some
|
||||
+/* Reset TEMP's state to TCG_TEMP_UNDEF. If TEMP was a representative of some
|
||||
class of equivalent temp's, a new representative should be chosen in this
|
||||
class. */
|
||||
static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
|
||||
@@ -69,7 +68,7 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
|
||||
}
|
||||
for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
|
||||
if (new_base == (TCGArg)-1) {
|
||||
- temps[i].state = TCG_TEMP_ANY;
|
||||
+ temps[i].state = TCG_TEMP_UNDEF;
|
||||
} else {
|
||||
temps[i].val = new_base;
|
||||
}
|
||||
@@ -81,9 +80,9 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
|
||||
temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
|
||||
new_base = temps[temp].val;
|
||||
}
|
||||
- temps[temp].state = TCG_TEMP_ANY;
|
||||
+ temps[temp].state = TCG_TEMP_UNDEF;
|
||||
if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) {
|
||||
- temps[new_base].state = TCG_TEMP_ANY;
|
||||
+ temps[new_base].state = TCG_TEMP_UNDEF;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
78
0069-tcg-optimize-check-types-in-copy-propagation.patch
Normal file
78
0069-tcg-optimize-check-types-in-copy-propagation.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From 71f0bcf065ddd00d5659e846ddfdffb9a06ee896 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 11 Sep 2012 12:26:23 +0200
|
||||
Subject: [PATCH] tcg/optimize: check types in copy propagation
|
||||
|
||||
The copy propagation doesn't check the types of the temps during copy
|
||||
propagation. However TCG is using the mov_i32 for the i64 to i32
|
||||
conversion and thus the two are not equivalent.
|
||||
|
||||
With this patch tcg_opt_gen_mov() doesn't consider two temps of
|
||||
different type as copies anymore.
|
||||
|
||||
So far it seems the optimization was not aggressive enough to trigger
|
||||
this bug, but it will be triggered later in this series once the copy
|
||||
propagation is improved.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 18 ++++++++----------
|
||||
1 file changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 308b7f9..da8dffe 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -106,12 +106,13 @@ static TCGOpcode op_to_movi(TCGOpcode op)
|
||||
}
|
||||
}
|
||||
|
||||
-static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
|
||||
- int nb_temps, int nb_globals)
|
||||
+static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
|
||||
+ TCGArg dst, TCGArg src)
|
||||
{
|
||||
- reset_temp(dst, nb_temps, nb_globals);
|
||||
+ reset_temp(dst, s->nb_temps, s->nb_globals);
|
||||
assert(temps[src].state != TCG_TEMP_COPY);
|
||||
- if (src >= nb_globals) {
|
||||
+ /* Only consider temps with the same type (width) as copies. */
|
||||
+ if (src >= s->nb_globals && s->temps[dst].type == s->temps[src].type) {
|
||||
assert(temps[src].state != TCG_TEMP_CONST);
|
||||
if (temps[src].state != TCG_TEMP_HAS_COPY) {
|
||||
temps[src].state = TCG_TEMP_HAS_COPY;
|
||||
@@ -461,8 +462,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
- tcg_opt_gen_mov(gen_args, args[0], args[1],
|
||||
- nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
|
||||
gen_args += 2;
|
||||
}
|
||||
args += 3;
|
||||
@@ -499,8 +499,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
- tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
|
||||
- nb_globals);
|
||||
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
|
||||
gen_args += 2;
|
||||
}
|
||||
args += 3;
|
||||
@@ -524,8 +523,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
break;
|
||||
}
|
||||
if (temps[args[1]].state != TCG_TEMP_CONST) {
|
||||
- tcg_opt_gen_mov(gen_args, args[0], args[1],
|
||||
- nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
|
||||
gen_args += 2;
|
||||
args += 2;
|
||||
break;
|
||||
--
|
||||
1.7.12.1
|
||||
|
377
0070-tcg-optimize-rework-copy-progagation.patch
Normal file
377
0070-tcg-optimize-rework-copy-progagation.patch
Normal file
@ -0,0 +1,377 @@
|
||||
From bf408071104de13f79a0c3c8cac892f440462e7c Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 11 Sep 2012 12:31:21 +0200
|
||||
Subject: [PATCH] tcg/optimize: rework copy progagation
|
||||
|
||||
The copy propagation pass tries to keep track what is a copy of what
|
||||
and what has copy of what, and in addition it keep a circular list of
|
||||
of all the copies. Unfortunately this doesn't fully work: a mov from
|
||||
a temp which has a state "COPY" changed it into a state "HAS_COPY".
|
||||
Later when this temp is used again, it is considered has not having
|
||||
copy and thus no propagation is done.
|
||||
|
||||
This patch fixes that by removing the hiearchy between copies, and thus
|
||||
only keeping a "COPY" state both meaning "is a copy" and "has a copy".
|
||||
The decision of which copy to use is deferred to the actual temp
|
||||
replacement. At this stage there is not one best choice to do, but only
|
||||
better choices than others. For doing the best choice the operation
|
||||
would have to be parsed in reversed to know if a temp is going to be
|
||||
used later or not. That what is done by the liveness analysis. At this
|
||||
stage it is known that globals will be always live, that local temps
|
||||
will be dead at the end of the translation block, and that the temps
|
||||
will be dead at the end of the basic block. This means that this stage
|
||||
should try to replace temps by local temps or globals and local temps
|
||||
by globals.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 167 +++++++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 92 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index da8dffe..1904b39 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -39,7 +39,6 @@ typedef enum {
|
||||
TCG_TEMP_UNDEF = 0,
|
||||
TCG_TEMP_CONST,
|
||||
TCG_TEMP_COPY,
|
||||
- TCG_TEMP_HAS_COPY
|
||||
} tcg_temp_state;
|
||||
|
||||
struct tcg_temp_info {
|
||||
@@ -51,39 +50,19 @@ struct tcg_temp_info {
|
||||
|
||||
static struct tcg_temp_info temps[TCG_MAX_TEMPS];
|
||||
|
||||
-/* Reset TEMP's state to TCG_TEMP_UNDEF. If TEMP was a representative of some
|
||||
- class of equivalent temp's, a new representative should be chosen in this
|
||||
- class. */
|
||||
-static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
|
||||
+/* Reset TEMP's state to TCG_TEMP_UNDEF. If TEMP only had one copy, remove
|
||||
+ the copy flag from the left temp. */
|
||||
+static void reset_temp(TCGArg temp)
|
||||
{
|
||||
- int i;
|
||||
- TCGArg new_base = (TCGArg)-1;
|
||||
- if (temps[temp].state == TCG_TEMP_HAS_COPY) {
|
||||
- for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
|
||||
- if (i >= nb_globals) {
|
||||
- temps[i].state = TCG_TEMP_HAS_COPY;
|
||||
- new_base = i;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
|
||||
- if (new_base == (TCGArg)-1) {
|
||||
- temps[i].state = TCG_TEMP_UNDEF;
|
||||
- } else {
|
||||
- temps[i].val = new_base;
|
||||
- }
|
||||
+ if (temps[temp].state == TCG_TEMP_COPY) {
|
||||
+ if (temps[temp].prev_copy == temps[temp].next_copy) {
|
||||
+ temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF;
|
||||
+ } else {
|
||||
+ temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
|
||||
+ temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
|
||||
}
|
||||
- temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
|
||||
- temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
|
||||
- } else if (temps[temp].state == TCG_TEMP_COPY) {
|
||||
- temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
|
||||
- temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
|
||||
- new_base = temps[temp].val;
|
||||
}
|
||||
temps[temp].state = TCG_TEMP_UNDEF;
|
||||
- if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) {
|
||||
- temps[new_base].state = TCG_TEMP_UNDEF;
|
||||
- }
|
||||
}
|
||||
|
||||
static int op_bits(TCGOpcode op)
|
||||
@@ -106,34 +85,83 @@ static TCGOpcode op_to_movi(TCGOpcode op)
|
||||
}
|
||||
}
|
||||
|
||||
+static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
|
||||
+{
|
||||
+ TCGArg i;
|
||||
+
|
||||
+ /* If this is already a global, we can't do better. */
|
||||
+ if (temp < s->nb_globals) {
|
||||
+ return temp;
|
||||
+ }
|
||||
+
|
||||
+ /* Search for a global first. */
|
||||
+ for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
|
||||
+ if (i < s->nb_globals) {
|
||||
+ return i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* If it is a temp, search for a temp local. */
|
||||
+ if (!s->temps[temp].temp_local) {
|
||||
+ for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
|
||||
+ if (s->temps[i].temp_local) {
|
||||
+ return i;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Failure to find a better representation, return the same temp. */
|
||||
+ return temp;
|
||||
+}
|
||||
+
|
||||
+static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
|
||||
+{
|
||||
+ TCGArg i;
|
||||
+
|
||||
+ if (arg1 == arg2) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (temps[arg1].state != TCG_TEMP_COPY
|
||||
+ || temps[arg2].state != TCG_TEMP_COPY) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ for (i = temps[arg1].next_copy ; i != arg1 ; i = temps[i].next_copy) {
|
||||
+ if (i == arg2) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
|
||||
TCGArg dst, TCGArg src)
|
||||
{
|
||||
- reset_temp(dst, s->nb_temps, s->nb_globals);
|
||||
- assert(temps[src].state != TCG_TEMP_COPY);
|
||||
- /* Only consider temps with the same type (width) as copies. */
|
||||
- if (src >= s->nb_globals && s->temps[dst].type == s->temps[src].type) {
|
||||
- assert(temps[src].state != TCG_TEMP_CONST);
|
||||
- if (temps[src].state != TCG_TEMP_HAS_COPY) {
|
||||
- temps[src].state = TCG_TEMP_HAS_COPY;
|
||||
+ reset_temp(dst);
|
||||
+ assert(temps[src].state != TCG_TEMP_CONST);
|
||||
+
|
||||
+ if (s->temps[src].type == s->temps[dst].type) {
|
||||
+ if (temps[src].state != TCG_TEMP_COPY) {
|
||||
+ temps[src].state = TCG_TEMP_COPY;
|
||||
temps[src].next_copy = src;
|
||||
temps[src].prev_copy = src;
|
||||
}
|
||||
temps[dst].state = TCG_TEMP_COPY;
|
||||
- temps[dst].val = src;
|
||||
temps[dst].next_copy = temps[src].next_copy;
|
||||
temps[dst].prev_copy = src;
|
||||
temps[temps[dst].next_copy].prev_copy = dst;
|
||||
temps[src].next_copy = dst;
|
||||
}
|
||||
+
|
||||
gen_args[0] = dst;
|
||||
gen_args[1] = src;
|
||||
}
|
||||
|
||||
-static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val,
|
||||
- int nb_temps, int nb_globals)
|
||||
+static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
|
||||
{
|
||||
- reset_temp(dst, nb_temps, nb_globals);
|
||||
+ reset_temp(dst);
|
||||
temps[dst].state = TCG_TEMP_CONST;
|
||||
temps[dst].val = val;
|
||||
gen_args[0] = dst;
|
||||
@@ -324,7 +352,6 @@ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
|
||||
tcg_abort();
|
||||
}
|
||||
|
||||
-
|
||||
/* Propagate constants and copies, fold constant expressions. */
|
||||
static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
TCGArg *args, TCGOpDef *tcg_op_defs)
|
||||
@@ -338,10 +365,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
|
||||
/* Array VALS has an element for each temp.
|
||||
If this temp holds a constant then its value is kept in VALS' element.
|
||||
- If this temp is a copy of other ones then this equivalence class'
|
||||
- representative is kept in VALS' element.
|
||||
- If this temp is neither copy nor constant then corresponding VALS'
|
||||
- element is unused. */
|
||||
+ If this temp is a copy of other ones then the other copies are
|
||||
+ available through the doubly linked circular list. */
|
||||
|
||||
nb_temps = s->nb_temps;
|
||||
nb_globals = s->nb_globals;
|
||||
@@ -357,7 +382,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
assert(op != INDEX_op_call);
|
||||
for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
|
||||
if (temps[args[i]].state == TCG_TEMP_COPY) {
|
||||
- args[i] = temps[args[i]].val;
|
||||
+ args[i] = find_better_copy(s, args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,7 +454,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
&& temps[args[1]].val == 0) {
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
- tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], 0);
|
||||
args += 3;
|
||||
gen_args += 2;
|
||||
continue;
|
||||
@@ -456,9 +481,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
}
|
||||
if (temps[args[2]].state == TCG_TEMP_CONST
|
||||
&& temps[args[2]].val == 0) {
|
||||
- if ((temps[args[0]].state == TCG_TEMP_COPY
|
||||
- && temps[args[0]].val == args[1])
|
||||
- || args[0] == args[1]) {
|
||||
+ if (temps_are_copies(args[0], args[1])) {
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
@@ -480,7 +503,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
if ((temps[args[2]].state == TCG_TEMP_CONST
|
||||
&& temps[args[2]].val == 0)) {
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
- tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], 0);
|
||||
args += 3;
|
||||
gen_args += 2;
|
||||
continue;
|
||||
@@ -495,7 +518,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
CASE_OP_32_64(or):
|
||||
CASE_OP_32_64(and):
|
||||
if (args[1] == args[2]) {
|
||||
- if (args[1] == args[0]) {
|
||||
+ if (temps_are_copies(args[0], args[1])) {
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
@@ -515,9 +538,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
allocator where needed and possible. Also detect copies. */
|
||||
switch (op) {
|
||||
CASE_OP_32_64(mov):
|
||||
- if ((temps[args[1]].state == TCG_TEMP_COPY
|
||||
- && temps[args[1]].val == args[0])
|
||||
- || args[0] == args[1]) {
|
||||
+ if (temps_are_copies(args[0], args[1])) {
|
||||
args += 2;
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
break;
|
||||
@@ -535,7 +556,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args[1] = temps[args[1]].val;
|
||||
/* fallthrough */
|
||||
CASE_OP_32_64(movi):
|
||||
- tcg_opt_gen_movi(gen_args, args[0], args[1], nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], args[1]);
|
||||
gen_args += 2;
|
||||
args += 2;
|
||||
break;
|
||||
@@ -550,9 +571,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
if (temps[args[1]].state == TCG_TEMP_CONST) {
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
tmp = do_constant_folding(op, temps[args[1]].val, 0);
|
||||
- tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], tmp);
|
||||
} else {
|
||||
- reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ reset_temp(args[0]);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
}
|
||||
@@ -580,10 +601,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
tmp = do_constant_folding(op, temps[args[1]].val,
|
||||
temps[args[2]].val);
|
||||
- tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], tmp);
|
||||
gen_args += 2;
|
||||
} else {
|
||||
- reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ reset_temp(args[0]);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
gen_args[2] = args[2];
|
||||
@@ -597,10 +618,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
tmp = do_constant_folding_cond(op, temps[args[1]].val,
|
||||
temps[args[2]].val, args[3]);
|
||||
- tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], tmp);
|
||||
gen_args += 2;
|
||||
} else {
|
||||
- reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ reset_temp(args[0]);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
gen_args[2] = args[2];
|
||||
@@ -623,7 +644,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
}
|
||||
} else {
|
||||
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
- reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ reset_temp(args[0]);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
gen_args[2] = args[2];
|
||||
@@ -637,23 +658,19 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
&& temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
tmp = do_constant_folding_cond(op, temps[args[1]].val,
|
||||
temps[args[2]].val, args[5]);
|
||||
- if (args[0] == args[4-tmp]
|
||||
- || (temps[args[4-tmp]].state == TCG_TEMP_COPY
|
||||
- && temps[args[4-tmp]].val == args[0])) {
|
||||
+ if (temps_are_copies(args[0], args[4-tmp])) {
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
- tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val,
|
||||
- nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
|
||||
gen_args += 2;
|
||||
} else {
|
||||
gen_opc_buf[op_index] = op_to_mov(op);
|
||||
- tcg_opt_gen_mov(gen_args, args[0], args[4-tmp],
|
||||
- nb_temps, nb_globals);
|
||||
+ tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
|
||||
gen_args += 2;
|
||||
}
|
||||
} else {
|
||||
- reset_temp(args[0], nb_temps, nb_globals);
|
||||
+ reset_temp(args[0]);
|
||||
gen_args[0] = args[0];
|
||||
gen_args[1] = args[1];
|
||||
gen_args[2] = args[2];
|
||||
@@ -668,11 +685,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
|
||||
if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
|
||||
for (i = 0; i < nb_globals; i++) {
|
||||
- reset_temp(i, nb_temps, nb_globals);
|
||||
+ reset_temp(i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < (args[0] >> 16); i++) {
|
||||
- reset_temp(args[i + 1], nb_temps, nb_globals);
|
||||
+ reset_temp(args[i + 1]);
|
||||
}
|
||||
i = nb_call_args + 3;
|
||||
while (i) {
|
||||
@@ -691,7 +708,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
} else {
|
||||
for (i = 0; i < def->nb_oargs; i++) {
|
||||
- reset_temp(args[i], nb_temps, nb_globals);
|
||||
+ reset_temp(args[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < def->nb_args; i++) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 7c1a67bb734f364ea0643b549e030f04d4eed798 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 11 Sep 2012 16:18:49 +0200
|
||||
Subject: [PATCH] tcg/optimize: do copy propagation for all operations
|
||||
|
||||
It is possible to due copy propagation for all operations, even the one
|
||||
that have side effects or clobber arguments (it only concerns input
|
||||
arguments). That said, the call operation should be handled differently
|
||||
due to the variable number of arguments.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index 1904b39..aeb2225 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -378,8 +378,15 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
op = gen_opc_buf[op_index];
|
||||
def = &tcg_op_defs[op];
|
||||
/* Do copy propagation */
|
||||
- if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) {
|
||||
- assert(op != INDEX_op_call);
|
||||
+ if (op == INDEX_op_call) {
|
||||
+ int nb_oargs = args[0] >> 16;
|
||||
+ int nb_iargs = args[0] & 0xffff;
|
||||
+ for (i = nb_oargs + 1; i < nb_oargs + nb_iargs + 1; i++) {
|
||||
+ if (temps[args[i]].state == TCG_TEMP_COPY) {
|
||||
+ args[i] = find_better_copy(s, args[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
|
||||
if (temps[args[i]].state == TCG_TEMP_COPY) {
|
||||
args[i] = find_better_copy(s, args[i]);
|
||||
--
|
||||
1.7.12.1
|
||||
|
31
0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch
Normal file
31
0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From e38329760e40a354e37d11c7f5d8c86cdb90736c Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 18 Sep 2012 19:11:32 +0200
|
||||
Subject: [PATCH] tcg/optimize: optimize "op r, a, a => mov r, a"
|
||||
|
||||
Now that we can easily detect all copies, we can optimize the
|
||||
"op r, a, a => mov r, a" case a bit more.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index aeb2225..b9a7da9 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -524,7 +524,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
switch (op) {
|
||||
CASE_OP_32_64(or):
|
||||
CASE_OP_32_64(and):
|
||||
- if (args[1] == args[2]) {
|
||||
+ if (temps_are_copies(args[1], args[2])) {
|
||||
if (temps_are_copies(args[0], args[1])) {
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else {
|
||||
--
|
||||
1.7.12.1
|
||||
|
46
0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch
Normal file
46
0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 363479b4d4f729959eafb1209d48ad75e928c00a Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 18 Sep 2012 19:12:36 +0200
|
||||
Subject: [PATCH] tcg/optimize: optimize "op r, a, a => movi r, 0"
|
||||
|
||||
Now that it's possible to detect copies, we can optimize the case
|
||||
the "op r, a, a => movi r, 0". This helps in the computation of
|
||||
overflow flags when one of the two args is 0.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index b9a7da9..ceea644 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -540,6 +540,22 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* Simplify expression for "op r, a, a => movi r, 0" cases */
|
||||
+ switch (op) {
|
||||
+ CASE_OP_32_64(sub):
|
||||
+ CASE_OP_32_64(xor):
|
||||
+ if (temps_are_copies(args[1], args[2])) {
|
||||
+ gen_opc_buf[op_index] = op_to_movi(op);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], 0);
|
||||
+ gen_args += 2;
|
||||
+ args += 3;
|
||||
+ continue;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Propagate constants through copy operations and do constant
|
||||
folding. Constants will be substituted to arguments by register
|
||||
allocator where needed and possible. Also detect copies. */
|
||||
--
|
||||
1.7.12.1
|
||||
|
192
0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch
Normal file
192
0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch
Normal file
@ -0,0 +1,192 @@
|
||||
From 8d5f3ca9ccace2374fd73d46fad56decc02e0a44 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Tue, 18 Sep 2012 19:37:00 +0200
|
||||
Subject: [PATCH] tcg/optimize: further optimize brcond/movcond/setcond
|
||||
|
||||
When both argument of brcond/movcond/setcond are the same or when one
|
||||
of the two values is a constant equal to zero, it's possible to do
|
||||
further optimizations.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 127 ++++++++++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 76 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index ceea644..abe016a 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -292,58 +292,88 @@ static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
|
||||
return res;
|
||||
}
|
||||
|
||||
+/* Return 2 if the condition can't be simplified, and the result
|
||||
+ of the condition (0 or 1) if it can */
|
||||
static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
|
||||
TCGArg y, TCGCond c)
|
||||
{
|
||||
- switch (op_bits(op)) {
|
||||
- case 32:
|
||||
+ if (temps[x].state == TCG_TEMP_CONST && temps[y].state == TCG_TEMP_CONST) {
|
||||
+ switch (op_bits(op)) {
|
||||
+ case 32:
|
||||
+ switch (c) {
|
||||
+ case TCG_COND_EQ:
|
||||
+ return (uint32_t)temps[x].val == (uint32_t)temps[y].val;
|
||||
+ case TCG_COND_NE:
|
||||
+ return (uint32_t)temps[x].val != (uint32_t)temps[y].val;
|
||||
+ case TCG_COND_LT:
|
||||
+ return (int32_t)temps[x].val < (int32_t)temps[y].val;
|
||||
+ case TCG_COND_GE:
|
||||
+ return (int32_t)temps[x].val >= (int32_t)temps[y].val;
|
||||
+ case TCG_COND_LE:
|
||||
+ return (int32_t)temps[x].val <= (int32_t)temps[y].val;
|
||||
+ case TCG_COND_GT:
|
||||
+ return (int32_t)temps[x].val > (int32_t)temps[y].val;
|
||||
+ case TCG_COND_LTU:
|
||||
+ return (uint32_t)temps[x].val < (uint32_t)temps[y].val;
|
||||
+ case TCG_COND_GEU:
|
||||
+ return (uint32_t)temps[x].val >= (uint32_t)temps[y].val;
|
||||
+ case TCG_COND_LEU:
|
||||
+ return (uint32_t)temps[x].val <= (uint32_t)temps[y].val;
|
||||
+ case TCG_COND_GTU:
|
||||
+ return (uint32_t)temps[x].val > (uint32_t)temps[y].val;
|
||||
+ }
|
||||
+ break;
|
||||
+ case 64:
|
||||
+ switch (c) {
|
||||
+ case TCG_COND_EQ:
|
||||
+ return (uint64_t)temps[x].val == (uint64_t)temps[y].val;
|
||||
+ case TCG_COND_NE:
|
||||
+ return (uint64_t)temps[x].val != (uint64_t)temps[y].val;
|
||||
+ case TCG_COND_LT:
|
||||
+ return (int64_t)temps[x].val < (int64_t)temps[y].val;
|
||||
+ case TCG_COND_GE:
|
||||
+ return (int64_t)temps[x].val >= (int64_t)temps[y].val;
|
||||
+ case TCG_COND_LE:
|
||||
+ return (int64_t)temps[x].val <= (int64_t)temps[y].val;
|
||||
+ case TCG_COND_GT:
|
||||
+ return (int64_t)temps[x].val > (int64_t)temps[y].val;
|
||||
+ case TCG_COND_LTU:
|
||||
+ return (uint64_t)temps[x].val < (uint64_t)temps[y].val;
|
||||
+ case TCG_COND_GEU:
|
||||
+ return (uint64_t)temps[x].val >= (uint64_t)temps[y].val;
|
||||
+ case TCG_COND_LEU:
|
||||
+ return (uint64_t)temps[x].val <= (uint64_t)temps[y].val;
|
||||
+ case TCG_COND_GTU:
|
||||
+ return (uint64_t)temps[x].val > (uint64_t)temps[y].val;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (temps_are_copies(x, y)) {
|
||||
switch (c) {
|
||||
- case TCG_COND_EQ:
|
||||
- return (uint32_t)x == (uint32_t)y;
|
||||
- case TCG_COND_NE:
|
||||
- return (uint32_t)x != (uint32_t)y;
|
||||
- case TCG_COND_LT:
|
||||
- return (int32_t)x < (int32_t)y;
|
||||
- case TCG_COND_GE:
|
||||
- return (int32_t)x >= (int32_t)y;
|
||||
- case TCG_COND_LE:
|
||||
- return (int32_t)x <= (int32_t)y;
|
||||
case TCG_COND_GT:
|
||||
- return (int32_t)x > (int32_t)y;
|
||||
case TCG_COND_LTU:
|
||||
- return (uint32_t)x < (uint32_t)y;
|
||||
- case TCG_COND_GEU:
|
||||
- return (uint32_t)x >= (uint32_t)y;
|
||||
- case TCG_COND_LEU:
|
||||
- return (uint32_t)x <= (uint32_t)y;
|
||||
+ case TCG_COND_LT:
|
||||
case TCG_COND_GTU:
|
||||
- return (uint32_t)x > (uint32_t)y;
|
||||
- }
|
||||
- break;
|
||||
- case 64:
|
||||
- switch (c) {
|
||||
- case TCG_COND_EQ:
|
||||
- return (uint64_t)x == (uint64_t)y;
|
||||
case TCG_COND_NE:
|
||||
- return (uint64_t)x != (uint64_t)y;
|
||||
- case TCG_COND_LT:
|
||||
- return (int64_t)x < (int64_t)y;
|
||||
+ return 0;
|
||||
case TCG_COND_GE:
|
||||
- return (int64_t)x >= (int64_t)y;
|
||||
+ case TCG_COND_GEU:
|
||||
case TCG_COND_LE:
|
||||
- return (int64_t)x <= (int64_t)y;
|
||||
- case TCG_COND_GT:
|
||||
- return (int64_t)x > (int64_t)y;
|
||||
+ case TCG_COND_LEU:
|
||||
+ case TCG_COND_EQ:
|
||||
+ return 1;
|
||||
+ }
|
||||
+ } else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) {
|
||||
+ switch (c) {
|
||||
case TCG_COND_LTU:
|
||||
- return (uint64_t)x < (uint64_t)y;
|
||||
+ return 0;
|
||||
case TCG_COND_GEU:
|
||||
- return (uint64_t)x >= (uint64_t)y;
|
||||
- case TCG_COND_LEU:
|
||||
- return (uint64_t)x <= (uint64_t)y;
|
||||
- case TCG_COND_GTU:
|
||||
- return (uint64_t)x > (uint64_t)y;
|
||||
+ return 1;
|
||||
+ default:
|
||||
+ return 2;
|
||||
}
|
||||
- break;
|
||||
+ } else {
|
||||
+ return 2;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
@@ -636,11 +666,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args += 3;
|
||||
break;
|
||||
CASE_OP_32_64(setcond):
|
||||
- if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
- && temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
+ tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
|
||||
+ if (tmp != 2) {
|
||||
gen_opc_buf[op_index] = op_to_movi(op);
|
||||
- tmp = do_constant_folding_cond(op, temps[args[1]].val,
|
||||
- temps[args[2]].val, args[3]);
|
||||
tcg_opt_gen_movi(gen_args, args[0], tmp);
|
||||
gen_args += 2;
|
||||
} else {
|
||||
@@ -654,10 +682,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args += 4;
|
||||
break;
|
||||
CASE_OP_32_64(brcond):
|
||||
- if (temps[args[0]].state == TCG_TEMP_CONST
|
||||
- && temps[args[1]].state == TCG_TEMP_CONST) {
|
||||
- if (do_constant_folding_cond(op, temps[args[0]].val,
|
||||
- temps[args[1]].val, args[2])) {
|
||||
+ tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
|
||||
+ if (tmp != 2) {
|
||||
+ if (tmp) {
|
||||
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
|
||||
gen_opc_buf[op_index] = INDEX_op_br;
|
||||
gen_args[0] = args[3];
|
||||
@@ -677,10 +704,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
args += 4;
|
||||
break;
|
||||
CASE_OP_32_64(movcond):
|
||||
- if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
- && temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
- tmp = do_constant_folding_cond(op, temps[args[1]].val,
|
||||
- temps[args[2]].val, args[5]);
|
||||
+ tmp = do_constant_folding_cond(op, args[1], args[2], args[5]);
|
||||
+ if (tmp != 2) {
|
||||
if (temps_are_copies(args[0], args[4-tmp])) {
|
||||
gen_opc_buf[op_index] = INDEX_op_nop;
|
||||
} else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -0,0 +1,38 @@
|
||||
From a0b71ad6a3f8aeb8b5ea6d112a7afeadc7c004a4 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Wed, 19 Sep 2012 22:00:22 +0200
|
||||
Subject: [PATCH] tcg/optimize: prefer the "op a, a, b" form for commutative
|
||||
ops
|
||||
|
||||
The "op a, a, b" form is better handled on non-RISC host than the "op
|
||||
a, b, a" form, so swap the arguments to this form when possible, and
|
||||
when b is not a constant.
|
||||
|
||||
This reduces the number of generated instructions by a tiny bit.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index abe016a..c8ae50b 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -434,7 +434,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
CASE_OP_32_64(eqv):
|
||||
CASE_OP_32_64(nand):
|
||||
CASE_OP_32_64(nor):
|
||||
- if (temps[args[1]].state == TCG_TEMP_CONST) {
|
||||
+ /* Prefer the constant in second argument, and then the form
|
||||
+ op a, a, b, which is better handled on non-RISC hosts. */
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST || (args[0] == args[2]
|
||||
+ && temps[args[2]].state != TCG_TEMP_CONST)) {
|
||||
tmp = args[1];
|
||||
args[1] = args[2];
|
||||
args[2] = tmp;
|
||||
--
|
||||
1.7.12.1
|
||||
|
68
0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch
Normal file
68
0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From 3942910a66f682b98ac53ac2d2fba65b9c75eefd Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 10:02:45 +0200
|
||||
Subject: [PATCH] tcg: remove #ifdef #endif around TCGOpcode tests
|
||||
|
||||
Commit 25c4d9cc changed all TCGOpcode enums to be available, so we don't
|
||||
need to #ifdef #endif the one that are available only on some targets.
|
||||
This makes the code easier to read.
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/tcg.c | 13 +------------
|
||||
1 file changed, 1 insertion(+), 12 deletions(-)
|
||||
|
||||
diff --git a/tcg/tcg.c b/tcg/tcg.c
|
||||
index 24ce830..93421cd 100644
|
||||
--- a/tcg/tcg.c
|
||||
+++ b/tcg/tcg.c
|
||||
@@ -937,11 +937,7 @@ void tcg_dump_ops(TCGContext *s)
|
||||
args[nb_oargs + i]));
|
||||
}
|
||||
}
|
||||
- } else if (c == INDEX_op_movi_i32
|
||||
-#if TCG_TARGET_REG_BITS == 64
|
||||
- || c == INDEX_op_movi_i64
|
||||
-#endif
|
||||
- ) {
|
||||
+ } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
|
||||
tcg_target_ulong val;
|
||||
TCGHelperInfo *th;
|
||||
|
||||
@@ -993,14 +989,11 @@ void tcg_dump_ops(TCGContext *s)
|
||||
case INDEX_op_brcond_i32:
|
||||
case INDEX_op_setcond_i32:
|
||||
case INDEX_op_movcond_i32:
|
||||
-#if TCG_TARGET_REG_BITS == 32
|
||||
case INDEX_op_brcond2_i32:
|
||||
case INDEX_op_setcond2_i32:
|
||||
-#else
|
||||
case INDEX_op_brcond_i64:
|
||||
case INDEX_op_setcond_i64:
|
||||
case INDEX_op_movcond_i64:
|
||||
-#endif
|
||||
if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
|
||||
qemu_log(",%s", cond_name[args[k++]]);
|
||||
} else {
|
||||
@@ -2095,16 +2088,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
|
||||
#endif
|
||||
switch(opc) {
|
||||
case INDEX_op_mov_i32:
|
||||
-#if TCG_TARGET_REG_BITS == 64
|
||||
case INDEX_op_mov_i64:
|
||||
-#endif
|
||||
dead_args = s->op_dead_args[op_index];
|
||||
tcg_reg_alloc_mov(s, def, args, dead_args);
|
||||
break;
|
||||
case INDEX_op_movi_i32:
|
||||
-#if TCG_TARGET_REG_BITS == 64
|
||||
case INDEX_op_movi_i64:
|
||||
-#endif
|
||||
tcg_reg_alloc_movi(s, args);
|
||||
break;
|
||||
case INDEX_op_debug_insn_start:
|
||||
--
|
||||
1.7.12.1
|
||||
|
46
0077-tcg-optimize-add-constant-folding-for-deposit.patch
Normal file
46
0077-tcg-optimize-add-constant-folding-for-deposit.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 04edfbcf025b5588e0f3b86c74356a4339745f35 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri, 21 Sep 2012 11:07:29 +0200
|
||||
Subject: [PATCH] tcg/optimize: add constant folding for deposit
|
||||
|
||||
Reviewed-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/optimize.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/tcg/optimize.c b/tcg/optimize.c
|
||||
index c8ae50b..35532a1 100644
|
||||
--- a/tcg/optimize.c
|
||||
+++ b/tcg/optimize.c
|
||||
@@ -668,6 +668,26 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
|
||||
}
|
||||
args += 3;
|
||||
break;
|
||||
+ CASE_OP_32_64(deposit):
|
||||
+ if (temps[args[1]].state == TCG_TEMP_CONST
|
||||
+ && temps[args[2]].state == TCG_TEMP_CONST) {
|
||||
+ gen_opc_buf[op_index] = op_to_movi(op);
|
||||
+ tmp = ((1ull << args[4]) - 1);
|
||||
+ tmp = (temps[args[1]].val & ~(tmp << args[3]))
|
||||
+ | ((temps[args[2]].val & tmp) << args[3]);
|
||||
+ tcg_opt_gen_movi(gen_args, args[0], tmp);
|
||||
+ gen_args += 2;
|
||||
+ } else {
|
||||
+ reset_temp(args[0]);
|
||||
+ gen_args[0] = args[0];
|
||||
+ gen_args[1] = args[1];
|
||||
+ gen_args[2] = args[2];
|
||||
+ gen_args[3] = args[3];
|
||||
+ gen_args[4] = args[4];
|
||||
+ gen_args += 5;
|
||||
+ }
|
||||
+ args += 5;
|
||||
+ break;
|
||||
CASE_OP_32_64(setcond):
|
||||
tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
|
||||
if (tmp != 2) {
|
||||
--
|
||||
1.7.12.1
|
||||
|
33
0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch
Normal file
33
0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 08de143bdd34e906c3e89443cb6b24665f7c088d Mon Sep 17 00:00:00 2001
|
||||
From: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Date: Fri, 21 Sep 2012 04:18:07 +0400
|
||||
Subject: [PATCH] tcg/README: document tcg_gen_goto_tb restrictions
|
||||
|
||||
See
|
||||
http://lists.nongnu.org/archive/html/qemu-devel/2012-09/msg03196.html
|
||||
for the whole story.
|
||||
|
||||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/README | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/README b/tcg/README
|
||||
index d03ae05..33783ee 100644
|
||||
--- a/tcg/README
|
||||
+++ b/tcg/README
|
||||
@@ -392,7 +392,8 @@ Exit the current TB and return the value t0 (word type).
|
||||
|
||||
Exit the current TB and jump to the TB index 'index' (constant) if the
|
||||
current TB was linked to this TB. Otherwise execute the next
|
||||
-instructions.
|
||||
+instructions. Only indices 0 and 1 are valid and tcg_gen_goto_tb may be issued
|
||||
+at most once with each slot index per TB.
|
||||
|
||||
* qemu_ld8u t0, t1, flags
|
||||
qemu_ld8s t0, t1, flags
|
||||
--
|
||||
1.7.12.1
|
||||
|
57
0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch
Normal file
57
0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From e35e8b9bb446ff2693962151b8c80c5c88294959 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Weil <sw@weilnetz.de>
|
||||
Date: Thu, 13 Sep 2012 19:37:43 +0200
|
||||
Subject: [PATCH] w64: Fix TCG helper functions with 5 arguments
|
||||
|
||||
TCG uses 6 registers for function arguments on 64 bit Linux hosts,
|
||||
but only 4 registers on W64 hosts.
|
||||
|
||||
Commit 2999a0b20074a7e4a58f56572bb1436749368f59 increased the number
|
||||
of arguments for some important helper functions from 4 to 5
|
||||
which triggered a bug for W64 hosts: QEMU aborts when executing
|
||||
helper_lcall_real in the guest's BIOS because function
|
||||
tcg_target_get_call_iarg_regs_count always returned 6.
|
||||
|
||||
As W64 has only 4 registers for arguments, the 5th argument must be
|
||||
passed on the stack using a correct stack offset.
|
||||
|
||||
Signed-off-by: Stefan Weil <sw@weilnetz.de>
|
||||
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/i386/tcg-target.c | 2 +-
|
||||
tcg/i386/tcg-target.h | 4 ++++
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
|
||||
index aa1fa9f..85c6b81 100644
|
||||
--- a/tcg/i386/tcg-target.c
|
||||
+++ b/tcg/i386/tcg-target.c
|
||||
@@ -118,7 +118,7 @@ static void patch_reloc(uint8_t *code_ptr, int type,
|
||||
static inline int tcg_target_get_call_iarg_regs_count(int flags)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 64) {
|
||||
- return 6;
|
||||
+ return ARRAY_SIZE(tcg_target_call_iarg_regs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
|
||||
index b356d76..ace63ba 100644
|
||||
--- a/tcg/i386/tcg-target.h
|
||||
+++ b/tcg/i386/tcg-target.h
|
||||
@@ -67,7 +67,11 @@ typedef enum {
|
||||
/* used for function call generation */
|
||||
#define TCG_REG_CALL_STACK TCG_REG_ESP
|
||||
#define TCG_TARGET_STACK_ALIGN 16
|
||||
+#if defined(_WIN64)
|
||||
+#define TCG_TARGET_CALL_STACK_OFFSET 32
|
||||
+#else
|
||||
#define TCG_TARGET_CALL_STACK_OFFSET 0
|
||||
+#endif
|
||||
|
||||
/* optional instructions */
|
||||
#define TCG_TARGET_HAS_div2_i32 1
|
||||
--
|
||||
1.7.12.1
|
||||
|
137
0080-tcg-ppc32-Implement-movcond32.patch
Normal file
137
0080-tcg-ppc32-Implement-movcond32.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From d65d20819ac52207befffa9a7aa858cc7de9cbaf Mon Sep 17 00:00:00 2001
|
||||
From: malc <av1474@comtv.ru>
|
||||
Date: Sat, 22 Sep 2012 19:14:33 +0400
|
||||
Subject: [PATCH] tcg/ppc32: Implement movcond32
|
||||
|
||||
Thanks to Richard Henderson
|
||||
|
||||
Signed-off-by: malc <av1474@comtv.ru>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/ppc/tcg-target.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
tcg/ppc/tcg-target.h | 2 +-
|
||||
2 files changed, 76 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
|
||||
index 26c4b33..8f8b193 100644
|
||||
--- a/tcg/ppc/tcg-target.c
|
||||
+++ b/tcg/ppc/tcg-target.c
|
||||
@@ -390,6 +390,7 @@ static int tcg_target_const_match(tcg_target_long val,
|
||||
#define ORC XO31(412)
|
||||
#define EQV XO31(284)
|
||||
#define NAND XO31(476)
|
||||
+#define ISEL XO31( 15)
|
||||
|
||||
#define LBZX XO31( 87)
|
||||
#define LHZX XO31(279)
|
||||
@@ -1269,6 +1270,72 @@ static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
|
||||
);
|
||||
}
|
||||
|
||||
+static void tcg_out_movcond (TCGContext *s, TCGCond cond,
|
||||
+ TCGArg dest,
|
||||
+ TCGArg c1, TCGArg c2,
|
||||
+ TCGArg v1, TCGArg v2,
|
||||
+ int const_c2)
|
||||
+{
|
||||
+ tcg_out_cmp (s, cond, c1, c2, const_c2, 7);
|
||||
+
|
||||
+ if (1) {
|
||||
+ /* At least here on 7747A bit twiddling hacks are outperformed
|
||||
+ by jumpy code (the testing was not scientific) */
|
||||
+ if (dest == v2) {
|
||||
+ cond = tcg_invert_cond (cond);
|
||||
+ v2 = v1;
|
||||
+ }
|
||||
+ else {
|
||||
+ if (dest != v1) {
|
||||
+ tcg_out_mov (s, TCG_TYPE_I32, dest, v1);
|
||||
+ }
|
||||
+ }
|
||||
+ /* Branch forward over one insn */
|
||||
+ tcg_out32 (s, tcg_to_bc[cond] | 8);
|
||||
+ tcg_out_mov (s, TCG_TYPE_I32, dest, v2);
|
||||
+ }
|
||||
+ else {
|
||||
+ /* isel version, "if (1)" above should be replaced once a way
|
||||
+ to figure out availability of isel on the underlying
|
||||
+ hardware is found */
|
||||
+ int tab, bc;
|
||||
+
|
||||
+ switch (cond) {
|
||||
+ case TCG_COND_EQ:
|
||||
+ tab = TAB (dest, v1, v2);
|
||||
+ bc = CR_EQ;
|
||||
+ break;
|
||||
+ case TCG_COND_NE:
|
||||
+ tab = TAB (dest, v2, v1);
|
||||
+ bc = CR_EQ;
|
||||
+ break;
|
||||
+ case TCG_COND_LTU:
|
||||
+ case TCG_COND_LT:
|
||||
+ tab = TAB (dest, v1, v2);
|
||||
+ bc = CR_LT;
|
||||
+ break;
|
||||
+ case TCG_COND_GEU:
|
||||
+ case TCG_COND_GE:
|
||||
+ tab = TAB (dest, v2, v1);
|
||||
+ bc = CR_LT;
|
||||
+ break;
|
||||
+ case TCG_COND_LEU:
|
||||
+ case TCG_COND_LE:
|
||||
+ tab = TAB (dest, v2, v1);
|
||||
+ bc = CR_GT;
|
||||
+ break;
|
||||
+ case TCG_COND_GTU:
|
||||
+ case TCG_COND_GT:
|
||||
+ tab = TAB (dest, v1, v2);
|
||||
+ bc = CR_GT;
|
||||
+ break;
|
||||
+ default:
|
||||
+ tcg_abort ();
|
||||
+ }
|
||||
+ tcg_out32 (s, ISEL | tab | ((bc + 28) << 6));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void tcg_out_brcond (TCGContext *s, TCGCond cond,
|
||||
TCGArg arg1, TCGArg arg2, int const_arg2,
|
||||
int label_index)
|
||||
@@ -1826,6 +1893,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
);
|
||||
break;
|
||||
|
||||
+ case INDEX_op_movcond_i32:
|
||||
+ tcg_out_movcond (s, args[5], args[0],
|
||||
+ args[1], args[2],
|
||||
+ args[3], args[4],
|
||||
+ const_args[2]);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
tcg_dump_ops (s);
|
||||
tcg_abort ();
|
||||
@@ -1922,6 +1996,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
|
||||
{ INDEX_op_ext16u_i32, { "r", "r" } },
|
||||
|
||||
{ INDEX_op_deposit_i32, { "r", "0", "r" } },
|
||||
+ { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "r" } },
|
||||
|
||||
{ -1 },
|
||||
};
|
||||
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
|
||||
index 177eea1..3259d89 100644
|
||||
--- a/tcg/ppc/tcg-target.h
|
||||
+++ b/tcg/ppc/tcg-target.h
|
||||
@@ -92,7 +92,7 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_nand_i32 1
|
||||
#define TCG_TARGET_HAS_nor_i32 1
|
||||
#define TCG_TARGET_HAS_deposit_i32 1
|
||||
-#define TCG_TARGET_HAS_movcond_i32 0
|
||||
+#define TCG_TARGET_HAS_movcond_i32 1
|
||||
|
||||
#define TCG_AREG0 TCG_REG_R27
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
30
0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch
Normal file
30
0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From da65fa6c51ef1c999ffc75a162e95285d4cb915b Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sat, 24 Mar 2012 21:30:20 +0100
|
||||
Subject: [PATCH] tcg-sparc: Hack in qemu_ld/st64 for 32-bit.
|
||||
|
||||
Not actually implemented, but at least we avoid the tcg assert at startup.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index baed3b4..608fc46 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -1556,6 +1556,9 @@ static const TCGTargetOpDef sparc_op_defs[] = {
|
||||
|
||||
{ INDEX_op_brcond_i64, { "r", "rJ" } },
|
||||
{ INDEX_op_setcond_i64, { "r", "r", "rJ" } },
|
||||
+#else
|
||||
+ { INDEX_op_qemu_ld64, { "L", "L", "L" } },
|
||||
+ { INDEX_op_qemu_st64, { "L", "L", "L" } },
|
||||
#endif
|
||||
{ -1 },
|
||||
};
|
||||
--
|
||||
1.7.12.1
|
||||
|
27
0082-tcg-sparc-Fix-ADDX-opcode.patch
Normal file
27
0082-tcg-sparc-Fix-ADDX-opcode.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From b92aceeb9604c74e4a66db8ea5dd399d892e94bc Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 23 Mar 2012 23:57:12 +0100
|
||||
Subject: [PATCH] tcg-sparc: Fix ADDX opcode.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index 608fc46..0a19313 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -236,7 +236,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
|
||||
#define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03))
|
||||
#define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04))
|
||||
#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
|
||||
-#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
|
||||
+#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x08))
|
||||
#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
|
||||
#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
|
||||
#define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
|
||||
--
|
||||
1.7.12.1
|
||||
|
45
0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch
Normal file
45
0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 59aadb4f5b15eff968ed00ad29816ac19bef507d Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:40:48 -0700
|
||||
Subject: [PATCH] tcg-sparc: Don't MAP_FIXED on top of the program
|
||||
|
||||
The address we pick in sparc64.ld is also 0x60000000, so doing a fixed map
|
||||
on top of that is guaranteed to blow up. Choosing 0x40000000 is exactly
|
||||
right for the max of code_gen_buffer_size set below.
|
||||
|
||||
No need to ever use MAP_FIXED. While getting our desired address helps
|
||||
optimize the generated code, we won't fail if we don't get it.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
exec.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/exec.c b/exec.c
|
||||
index 5834766..871a68a 100644
|
||||
--- a/exec.c
|
||||
+++ b/exec.c
|
||||
@@ -543,8 +543,7 @@ static void code_gen_alloc(unsigned long tb_size)
|
||||
code_gen_buffer_size = (800 * 1024 * 1024);
|
||||
#elif defined(__sparc_v9__)
|
||||
// Map the buffer below 2G, so we can use direct calls and branches
|
||||
- flags |= MAP_FIXED;
|
||||
- start = (void *) 0x60000000UL;
|
||||
+ start = (void *) 0x40000000UL;
|
||||
if (code_gen_buffer_size > (512 * 1024 * 1024))
|
||||
code_gen_buffer_size = (512 * 1024 * 1024);
|
||||
#elif defined(__arm__)
|
||||
@@ -584,8 +583,7 @@ static void code_gen_alloc(unsigned long tb_size)
|
||||
code_gen_buffer_size = (800 * 1024 * 1024);
|
||||
#elif defined(__sparc_v9__)
|
||||
// Map the buffer below 2G, so we can use direct calls and branches
|
||||
- flags |= MAP_FIXED;
|
||||
- addr = (void *) 0x60000000UL;
|
||||
+ addr = (void *) 0x40000000UL;
|
||||
if (code_gen_buffer_size > (512 * 1024 * 1024)) {
|
||||
code_gen_buffer_size = (512 * 1024 * 1024);
|
||||
}
|
||||
--
|
||||
1.7.12.1
|
||||
|
286
0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch
Normal file
286
0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch
Normal file
@ -0,0 +1,286 @@
|
||||
From cf873edf4227be439a9ffa5abb3da61ff1fd6527 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:34:21 -0700
|
||||
Subject: [PATCH] tcg-sparc: Assume v9 cpu always, i.e. force v8plus in 32-bit
|
||||
mode.
|
||||
|
||||
Current code doesn't actually work in 32-bit mode at all. Since
|
||||
no one really noticed, drop the complication of v7 and v8 cpus.
|
||||
Eliminate the --sparc_cpu configure option and standardize macro
|
||||
testing on TCG_TARGET_REG_BITS / HOST_LONG_BITS
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 40 ++++------------------------------------
|
||||
disas.c | 2 --
|
||||
exec.c | 6 +++---
|
||||
qemu-timer.h | 8 +++++---
|
||||
tcg/sparc/tcg-target.c | 20 +++++---------------
|
||||
tcg/sparc/tcg-target.h | 7 ++++---
|
||||
tcg/tcg.c | 3 ++-
|
||||
7 files changed, 23 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 816f0f9..0590f16 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -111,7 +111,6 @@ source_path=`dirname "$0"`
|
||||
cpu=""
|
||||
interp_prefix="/usr/gnemul/qemu-%M"
|
||||
static="no"
|
||||
-sparc_cpu=""
|
||||
cross_prefix=""
|
||||
audio_drv_list=""
|
||||
audio_card_list="ac97 es1370 sb16 hda"
|
||||
@@ -249,21 +248,6 @@ for opt do
|
||||
;;
|
||||
--disable-debug-info) debug_info="no"
|
||||
;;
|
||||
- --sparc_cpu=*)
|
||||
- sparc_cpu="$optarg"
|
||||
- case $sparc_cpu in
|
||||
- v7|v8|v8plus|v8plusa)
|
||||
- cpu="sparc"
|
||||
- ;;
|
||||
- v9)
|
||||
- cpu="sparc64"
|
||||
- ;;
|
||||
- *)
|
||||
- echo "undefined SPARC architecture. Exiting";
|
||||
- exit 1
|
||||
- ;;
|
||||
- esac
|
||||
- ;;
|
||||
esac
|
||||
done
|
||||
# OS specific
|
||||
@@ -351,8 +335,6 @@ elif check_define __i386__ ; then
|
||||
elif check_define __x86_64__ ; then
|
||||
cpu="x86_64"
|
||||
elif check_define __sparc__ ; then
|
||||
- # We can't check for 64 bit (when gcc is biarch) or V8PLUSA
|
||||
- # They must be specified using --sparc_cpu
|
||||
if check_define __arch64__ ; then
|
||||
cpu="sparc64"
|
||||
else
|
||||
@@ -798,8 +780,6 @@ for opt do
|
||||
;;
|
||||
--enable-uname-release=*) uname_release="$optarg"
|
||||
;;
|
||||
- --sparc_cpu=*)
|
||||
- ;;
|
||||
--enable-werror) werror="yes"
|
||||
;;
|
||||
--disable-werror) werror="no"
|
||||
@@ -883,31 +863,19 @@ for opt do
|
||||
esac
|
||||
done
|
||||
|
||||
-#
|
||||
-# If cpu ~= sparc and sparc_cpu hasn't been defined, plug in the right
|
||||
-# QEMU_CFLAGS/LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
|
||||
-#
|
||||
host_guest_base="no"
|
||||
case "$cpu" in
|
||||
- sparc) case $sparc_cpu in
|
||||
- v7|v8)
|
||||
- QEMU_CFLAGS="-mcpu=${sparc_cpu} -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
|
||||
- ;;
|
||||
- v8plus|v8plusa)
|
||||
- QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
|
||||
- ;;
|
||||
- *) # sparc_cpu not defined in the command line
|
||||
- QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_v8plus__ $QEMU_CFLAGS"
|
||||
- esac
|
||||
+ sparc)
|
||||
LDFLAGS="-m32 $LDFLAGS"
|
||||
- QEMU_CFLAGS="-m32 -ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
|
||||
+ QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
|
||||
+ QEMU_CFLAGS="-ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
|
||||
if test "$solaris" = "no" ; then
|
||||
QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
|
||||
fi
|
||||
;;
|
||||
sparc64)
|
||||
- QEMU_CFLAGS="-m64 -mcpu=ultrasparc -D__sparc_v9__ $QEMU_CFLAGS"
|
||||
LDFLAGS="-m64 $LDFLAGS"
|
||||
+ QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
|
||||
QEMU_CFLAGS="-ffixed-g5 -ffixed-g6 -ffixed-g7 $QEMU_CFLAGS"
|
||||
if test "$solaris" != "no" ; then
|
||||
QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
|
||||
diff --git a/disas.c b/disas.c
|
||||
index 7b2acc9..b801c8f 100644
|
||||
--- a/disas.c
|
||||
+++ b/disas.c
|
||||
@@ -316,9 +316,7 @@ void disas(FILE *out, void *code, unsigned long size)
|
||||
print_insn = print_insn_alpha;
|
||||
#elif defined(__sparc__)
|
||||
print_insn = print_insn_sparc;
|
||||
-#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
|
||||
disasm_info.mach = bfd_mach_sparc_v9b;
|
||||
-#endif
|
||||
#elif defined(__arm__)
|
||||
print_insn = print_insn_arm;
|
||||
#elif defined(__MIPSEB__)
|
||||
diff --git a/exec.c b/exec.c
|
||||
index 871a68a..ad175db 100644
|
||||
--- a/exec.c
|
||||
+++ b/exec.c
|
||||
@@ -86,7 +86,7 @@ static int nb_tbs;
|
||||
/* any access to the tbs or the page table must use this lock */
|
||||
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
-#if defined(__arm__) || defined(__sparc_v9__)
|
||||
+#if defined(__arm__) || defined(__sparc__)
|
||||
/* The prologue must be reachable with a direct jump. ARM and Sparc64
|
||||
have limited branch ranges (possibly also PPC) so place it in a
|
||||
section close to code segment. */
|
||||
@@ -541,7 +541,7 @@ static void code_gen_alloc(unsigned long tb_size)
|
||||
/* Cannot map more than that */
|
||||
if (code_gen_buffer_size > (800 * 1024 * 1024))
|
||||
code_gen_buffer_size = (800 * 1024 * 1024);
|
||||
-#elif defined(__sparc_v9__)
|
||||
+#elif defined(__sparc__) && HOST_LONG_BITS == 64
|
||||
// Map the buffer below 2G, so we can use direct calls and branches
|
||||
start = (void *) 0x40000000UL;
|
||||
if (code_gen_buffer_size > (512 * 1024 * 1024))
|
||||
@@ -581,7 +581,7 @@ static void code_gen_alloc(unsigned long tb_size)
|
||||
/* Cannot map more than that */
|
||||
if (code_gen_buffer_size > (800 * 1024 * 1024))
|
||||
code_gen_buffer_size = (800 * 1024 * 1024);
|
||||
-#elif defined(__sparc_v9__)
|
||||
+#elif defined(__sparc__) && HOST_LONG_BITS == 64
|
||||
// Map the buffer below 2G, so we can use direct calls and branches
|
||||
addr = (void *) 0x40000000UL;
|
||||
if (code_gen_buffer_size > (512 * 1024 * 1024)) {
|
||||
diff --git a/qemu-timer.h b/qemu-timer.h
|
||||
index f8af595..da7e97c 100644
|
||||
--- a/qemu-timer.h
|
||||
+++ b/qemu-timer.h
|
||||
@@ -218,7 +218,7 @@ static inline int64_t cpu_get_real_ticks(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
-#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
|
||||
+#elif defined(__sparc__)
|
||||
|
||||
static inline int64_t cpu_get_real_ticks (void)
|
||||
{
|
||||
@@ -227,6 +227,8 @@ static inline int64_t cpu_get_real_ticks (void)
|
||||
asm volatile("rd %%tick,%0" : "=r"(rval));
|
||||
return rval;
|
||||
#else
|
||||
+ /* We need an %o or %g register for this. For recent enough gcc
|
||||
+ there is an "h" constraint for that. Don't bother with that. */
|
||||
union {
|
||||
uint64_t i64;
|
||||
struct {
|
||||
@@ -234,8 +236,8 @@ static inline int64_t cpu_get_real_ticks (void)
|
||||
uint32_t low;
|
||||
} i32;
|
||||
} rval;
|
||||
- asm volatile("rd %%tick,%1; srlx %1,32,%0"
|
||||
- : "=r"(rval.i32.high), "=r"(rval.i32.low));
|
||||
+ asm volatile("rd %%tick,%%g1; srlx %%g1,32,%0; mov %%g1,%1"
|
||||
+ : "=r"(rval.i32.high), "=r"(rval.i32.low) : : "g1");
|
||||
return rval.i64;
|
||||
#endif
|
||||
}
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index 0a19313..23c2fda 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -621,18 +621,10 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
|
||||
|
||||
default:
|
||||
tcg_out_cmp(s, c1, c2, c2const);
|
||||
-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
|
||||
tcg_out_movi_imm13(s, ret, 0);
|
||||
- tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
|
||||
- | INSN_RS1(tcg_cond_to_bcond[cond])
|
||||
- | MOVCC_ICC | INSN_IMM11(1));
|
||||
-#else
|
||||
- t = gen_new_label();
|
||||
- tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), t);
|
||||
- tcg_out_movi_imm13(s, ret, 1);
|
||||
- tcg_out_movi_imm13(s, ret, 0);
|
||||
- tcg_out_label(s, t, s->code_ptr);
|
||||
-#endif
|
||||
+ tcg_out32(s, ARITH_MOVCC | INSN_RD(ret)
|
||||
+ | INSN_RS1(tcg_cond_to_bcond[cond])
|
||||
+ | MOVCC_ICC | INSN_IMM11(1));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -742,7 +734,7 @@ static const void * const qemu_st_helpers[4] = {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
-#ifdef __arch64__
|
||||
+#if TCG_TARGET_REG_BITS == 64
|
||||
#define HOST_LD_OP LDX
|
||||
#define HOST_ST_OP STX
|
||||
#define HOST_SLL_OP SHIFT_SLLX
|
||||
@@ -1600,11 +1592,9 @@ static void tcg_target_init(TCGContext *s)
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
# define ELF_HOST_MACHINE EM_SPARCV9
|
||||
-#elif defined(__sparc_v8plus__)
|
||||
+#else
|
||||
# define ELF_HOST_MACHINE EM_SPARC32PLUS
|
||||
# define ELF_HOST_FLAGS EF_SPARC_32PLUS
|
||||
-#else
|
||||
-# define ELF_HOST_MACHINE EM_SPARC
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
|
||||
index d762574..adca1d2 100644
|
||||
--- a/tcg/sparc/tcg-target.h
|
||||
+++ b/tcg/sparc/tcg-target.h
|
||||
@@ -67,7 +67,8 @@ typedef enum {
|
||||
|
||||
/* used for function call generation */
|
||||
#define TCG_REG_CALL_STACK TCG_REG_I6
|
||||
-#ifdef __arch64__
|
||||
+
|
||||
+#if TCG_TARGET_REG_BITS == 64
|
||||
// Reserve space for AREG0
|
||||
#define TCG_TARGET_STACK_MINFRAME (176 + 4 * (int)sizeof(long) + \
|
||||
TCG_STATIC_CALL_ARGS_SIZE)
|
||||
@@ -81,7 +82,7 @@ typedef enum {
|
||||
#define TCG_TARGET_STACK_ALIGN 8
|
||||
#endif
|
||||
|
||||
-#ifdef __arch64__
|
||||
+#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_EXTEND_ARGS 1
|
||||
#endif
|
||||
|
||||
@@ -129,7 +130,7 @@ typedef enum {
|
||||
|
||||
#ifdef CONFIG_SOLARIS
|
||||
#define TCG_AREG0 TCG_REG_G2
|
||||
-#elif defined(__sparc_v9__)
|
||||
+#elif HOST_LONG_BITS == 64
|
||||
#define TCG_AREG0 TCG_REG_G5
|
||||
#else
|
||||
#define TCG_AREG0 TCG_REG_G6
|
||||
diff --git a/tcg/tcg.c b/tcg/tcg.c
|
||||
index 93421cd..16c4e1d 100644
|
||||
--- a/tcg/tcg.c
|
||||
+++ b/tcg/tcg.c
|
||||
@@ -1450,7 +1450,8 @@ static void temp_allocate_frame(TCGContext *s, int temp)
|
||||
{
|
||||
TCGTemp *ts;
|
||||
ts = &s->temps[temp];
|
||||
-#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
|
||||
+#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
|
||||
+ /* Sparc64 stack is accessed with offset of 2047 */
|
||||
s->current_frame_offset = (s->current_frame_offset +
|
||||
(tcg_target_long)sizeof(tcg_target_long) - 1) &
|
||||
~(sizeof(tcg_target_long) - 1);
|
||||
--
|
||||
1.7.12.1
|
||||
|
967
0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch
Normal file
967
0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch
Normal file
@ -0,0 +1,967 @@
|
||||
From 138dfa905538bf918af390ff365a27de49364578 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 23 Mar 2012 23:27:39 +0100
|
||||
Subject: [PATCH] tcg-sparc: Fix qemu_ld/st to handle 32-bit host.
|
||||
|
||||
At the same time, split out the tlb load logic to a new function.
|
||||
Fixes the cases of two data registers and two address registers.
|
||||
Fixes the signature of, and adds missing, qemu_ld/st opcodes.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 777 ++++++++++++++++++++++---------------------------
|
||||
1 file changed, 348 insertions(+), 429 deletions(-)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index 23c2fda..d89c19b 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -59,8 +59,6 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
-#define ARG_OFFSET 1
|
||||
-
|
||||
static const int tcg_target_reg_alloc_order[] = {
|
||||
TCG_REG_L0,
|
||||
TCG_REG_L1,
|
||||
@@ -288,6 +286,16 @@ static inline int tcg_target_const_match(tcg_target_long val,
|
||||
#define ASI_PRIMARY_LITTLE 0x88
|
||||
#endif
|
||||
|
||||
+#define LDUH_LE (LDUHA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+#define LDSH_LE (LDSHA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+#define LDUW_LE (LDUWA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+#define LDSW_LE (LDSWA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+#define LDX_LE (LDXA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+
|
||||
+#define STH_LE (STHA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+#define STW_LE (STWA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+#define STX_LE (STXA | INSN_ASI(ASI_PRIMARY_LITTLE))
|
||||
+
|
||||
static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
|
||||
int op)
|
||||
{
|
||||
@@ -360,64 +368,43 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
|
||||
}
|
||||
}
|
||||
|
||||
-static inline void tcg_out_ld_raw(TCGContext *s, int ret,
|
||||
- tcg_target_long arg)
|
||||
-{
|
||||
- tcg_out_sethi(s, ret, arg);
|
||||
- tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
|
||||
- INSN_IMM13(arg & 0x3ff));
|
||||
-}
|
||||
-
|
||||
-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
|
||||
- tcg_target_long arg)
|
||||
+static inline void tcg_out_ldst_rr(TCGContext *s, int data, int a1,
|
||||
+ int a2, int op)
|
||||
{
|
||||
- if (!check_fit_tl(arg, 10))
|
||||
- tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
|
||||
- if (TCG_TARGET_REG_BITS == 64) {
|
||||
- tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
|
||||
- INSN_IMM13(arg & 0x3ff));
|
||||
- } else {
|
||||
- tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
|
||||
- INSN_IMM13(arg & 0x3ff));
|
||||
- }
|
||||
+ tcg_out32(s, op | INSN_RD(data) | INSN_RS1(a1) | INSN_RS2(a2));
|
||||
}
|
||||
|
||||
-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
|
||||
+static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
|
||||
+ int offset, int op)
|
||||
{
|
||||
- if (check_fit_tl(offset, 13))
|
||||
+ if (check_fit_tl(offset, 13)) {
|
||||
tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
|
||||
INSN_IMM13(offset));
|
||||
- else {
|
||||
+ } else {
|
||||
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
|
||||
- tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
|
||||
- INSN_RS2(addr));
|
||||
+ tcg_out_ldst_rr(s, ret, addr, TCG_REG_I5, op);
|
||||
}
|
||||
}
|
||||
|
||||
-static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
|
||||
- int offset, int op, int asi)
|
||||
-{
|
||||
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
|
||||
- tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
|
||||
- INSN_ASI(asi) | INSN_RS2(addr));
|
||||
-}
|
||||
-
|
||||
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
|
||||
TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
- if (type == TCG_TYPE_I32)
|
||||
- tcg_out_ldst(s, ret, arg1, arg2, LDUW);
|
||||
- else
|
||||
- tcg_out_ldst(s, ret, arg1, arg2, LDX);
|
||||
+ tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX));
|
||||
}
|
||||
|
||||
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
|
||||
TCGReg arg1, tcg_target_long arg2)
|
||||
{
|
||||
- if (type == TCG_TYPE_I32)
|
||||
- tcg_out_ldst(s, arg, arg1, arg2, STW);
|
||||
- else
|
||||
- tcg_out_ldst(s, arg, arg1, arg2, STX);
|
||||
+ tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
|
||||
+}
|
||||
+
|
||||
+static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
|
||||
+ tcg_target_long arg)
|
||||
+{
|
||||
+ if (!check_fit_tl(arg, 10)) {
|
||||
+ tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
|
||||
+ }
|
||||
+ tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
|
||||
}
|
||||
|
||||
static inline void tcg_out_sety(TCGContext *s, int rs)
|
||||
@@ -442,14 +429,15 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
|
||||
}
|
||||
}
|
||||
|
||||
-static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
|
||||
+static inline void tcg_out_andi(TCGContext *s, int rd, int rs,
|
||||
+ tcg_target_long val)
|
||||
{
|
||||
if (val != 0) {
|
||||
if (check_fit_tl(val, 13))
|
||||
- tcg_out_arithi(s, reg, reg, val, ARITH_AND);
|
||||
+ tcg_out_arithi(s, rd, rs, val, ARITH_AND);
|
||||
else {
|
||||
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
|
||||
- tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
|
||||
+ tcg_out_arith(s, rd, rs, TCG_REG_I5, ARITH_AND);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -718,418 +706,328 @@ static const void * const qemu_st_helpers[4] = {
|
||||
helper_stl_mmu,
|
||||
helper_stq_mmu,
|
||||
};
|
||||
-#endif
|
||||
|
||||
-#if TARGET_LONG_BITS == 32
|
||||
-#define TARGET_LD_OP LDUW
|
||||
-#else
|
||||
-#define TARGET_LD_OP LDX
|
||||
-#endif
|
||||
+/* Perform the TLB load and compare.
|
||||
|
||||
-#if defined(CONFIG_SOFTMMU)
|
||||
-#if HOST_LONG_BITS == 32
|
||||
-#define TARGET_ADDEND_LD_OP LDUW
|
||||
+ Inputs:
|
||||
+ ADDRLO_IDX contains the index into ARGS of the low part of the
|
||||
+ address; the high part of the address is at ADDR_LOW_IDX+1.
|
||||
+
|
||||
+ MEM_INDEX and S_BITS are the memory context and log2 size of the load.
|
||||
+
|
||||
+ WHICH is the offset into the CPUTLBEntry structure of the slot to read.
|
||||
+ This should be offsetof addr_read or addr_write.
|
||||
+
|
||||
+ The result of the TLB comparison is in %[ix]cc. The sanitized address
|
||||
+ is in the returned register, maybe %o0. The TLB addend is in %o1. */
|
||||
+
|
||||
+static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
|
||||
+ int s_bits, const TCGArg *args, int which)
|
||||
+{
|
||||
+ const int addrlo = args[addrlo_idx];
|
||||
+ const int r0 = TCG_REG_O0;
|
||||
+ const int r1 = TCG_REG_O1;
|
||||
+ const int r2 = TCG_REG_O2;
|
||||
+ int addr = addrlo;
|
||||
+ int tlb_ofs;
|
||||
+
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
|
||||
+ /* Assemble the 64-bit address in R0. */
|
||||
+ tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
|
||||
+ tcg_out_arithi(s, r1, args[addrlo_idx + 1], 32, SHIFT_SLLX);
|
||||
+ tcg_out_arith(s, r0, r0, r1, ARITH_OR);
|
||||
+ }
|
||||
+
|
||||
+ /* Shift the page number down to tlb-entry. */
|
||||
+ tcg_out_arithi(s, r1, addrlo,
|
||||
+ TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS, SHIFT_SRL);
|
||||
+
|
||||
+ /* Mask out the page offset, except for the required alignment. */
|
||||
+ tcg_out_andi(s, r0, addr, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
|
||||
+
|
||||
+ /* Compute tlb index, modulo tlb size. */
|
||||
+ tcg_out_andi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
|
||||
+
|
||||
+ /* Relative to the current ENV. */
|
||||
+ tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
|
||||
+
|
||||
+ /* Find a base address that can load both tlb comparator and addend. */
|
||||
+ tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
|
||||
+ if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
|
||||
+ tcg_out_addi(s, r1, tlb_ofs);
|
||||
+ tlb_ofs = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Load the tlb comparator and the addend. */
|
||||
+ tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
|
||||
+ tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
|
||||
+
|
||||
+ /* subcc arg0, arg2, %g0 */
|
||||
+ tcg_out_cmp(s, r0, r2, 0);
|
||||
+
|
||||
+ /* If the guest address must be zero-extended, do so now. */
|
||||
+ if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
|
||||
+ tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
|
||||
+ return r0;
|
||||
+ }
|
||||
+ return addrlo;
|
||||
+}
|
||||
+#endif /* CONFIG_SOFTMMU */
|
||||
+
|
||||
+static const int qemu_ld_opc[8] = {
|
||||
+#ifdef TARGET_WORDS_BIGENDIAN
|
||||
+ LDUB, LDUH, LDUW, LDX, LDSB, LDSH, LDSW, LDX
|
||||
#else
|
||||
-#define TARGET_ADDEND_LD_OP LDX
|
||||
-#endif
|
||||
+ LDUB, LDUH_LE, LDUW_LE, LDX_LE, LDSB, LDSH_LE, LDSW_LE, LDX_LE
|
||||
#endif
|
||||
+};
|
||||
|
||||
-#if TCG_TARGET_REG_BITS == 64
|
||||
-#define HOST_LD_OP LDX
|
||||
-#define HOST_ST_OP STX
|
||||
-#define HOST_SLL_OP SHIFT_SLLX
|
||||
-#define HOST_SRA_OP SHIFT_SRAX
|
||||
+static const int qemu_st_opc[4] = {
|
||||
+#ifdef TARGET_WORDS_BIGENDIAN
|
||||
+ STB, STH, STW, STX
|
||||
#else
|
||||
-#define HOST_LD_OP LDUW
|
||||
-#define HOST_ST_OP STW
|
||||
-#define HOST_SLL_OP SHIFT_SLL
|
||||
-#define HOST_SRA_OP SHIFT_SRA
|
||||
+ STB, STH_LE, STW_LE, STX_LE
|
||||
#endif
|
||||
+};
|
||||
|
||||
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||
- int opc)
|
||||
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
{
|
||||
- int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
|
||||
+ int addrlo_idx = 1, datalo, datahi, addr_reg;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
- uint32_t *label1_ptr, *label2_ptr;
|
||||
+ int memi_idx, memi, s_bits, n;
|
||||
+ uint32_t *label_ptr[2];
|
||||
#endif
|
||||
|
||||
- data_reg = *args++;
|
||||
- addr_reg = *args++;
|
||||
- mem_index = *args;
|
||||
- s_bits = opc & 3;
|
||||
-
|
||||
- arg0 = TCG_REG_O0;
|
||||
- arg1 = TCG_REG_O1;
|
||||
- arg2 = TCG_REG_O2;
|
||||
+ datahi = datalo = args[0];
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ datahi = args[1];
|
||||
+ addrlo_idx = 2;
|
||||
+ }
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
- /* srl addr_reg, x, arg1 */
|
||||
- tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
|
||||
- SHIFT_SRL);
|
||||
- /* and addr_reg, x, arg0 */
|
||||
- tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
|
||||
- ARITH_AND);
|
||||
+ memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
|
||||
+ memi = args[memi_idx];
|
||||
+ s_bits = sizeop & 3;
|
||||
+
|
||||
+ addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, s_bits, args,
|
||||
+ offsetof(CPUTLBEntry, addr_read));
|
||||
+
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ int reg64;
|
||||
+
|
||||
+ /* bne,pn %[xi]cc, label0 */
|
||||
+ label_ptr[0] = (uint32_t *)s->code_ptr;
|
||||
+ tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_NE, 0) | INSN_OP2(0x1)
|
||||
+ | ((TARGET_LONG_BITS == 64) << 21)));
|
||||
+
|
||||
+ /* TLB Hit. */
|
||||
+ /* Load all 64-bits into an O/G register. */
|
||||
+ reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
|
||||
+ tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
|
||||
+
|
||||
+ /* Move the two 32-bit pieces into the destination registers. */
|
||||
+ tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
|
||||
+ if (reg64 != datalo) {
|
||||
+ tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
|
||||
+ }
|
||||
|
||||
- /* and arg1, x, arg1 */
|
||||
- tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
|
||||
+ /* b,a,pt label1 */
|
||||
+ label_ptr[1] = (uint32_t *)s->code_ptr;
|
||||
+ tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x1)
|
||||
+ | (1 << 29) | (1 << 19)));
|
||||
+ } else {
|
||||
+ /* The fast path is exactly one insn. Thus we can perform the
|
||||
+ entire TLB Hit in the (annulled) delay slot of the branch
|
||||
+ over the TLB Miss case. */
|
||||
+
|
||||
+ /* beq,a,pt %[xi]cc, label0 */
|
||||
+ label_ptr[0] = NULL;
|
||||
+ label_ptr[1] = (uint32_t *)s->code_ptr;
|
||||
+ tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1)
|
||||
+ | ((TARGET_LONG_BITS == 64) << 21)
|
||||
+ | (1 << 29) | (1 << 19)));
|
||||
+ /* delay slot */
|
||||
+ tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
|
||||
+ }
|
||||
|
||||
- /* add arg1, x, arg1 */
|
||||
- tcg_out_addi(s, arg1, offsetof(CPUArchState,
|
||||
- tlb_table[mem_index][0].addr_read));
|
||||
+ /* TLB Miss. */
|
||||
|
||||
- /* add env, arg1, arg1 */
|
||||
- tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
|
||||
+ if (label_ptr[0]) {
|
||||
+ *label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
|
||||
+ (unsigned long)label_ptr[0]);
|
||||
+ }
|
||||
+ n = 0;
|
||||
+ tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
|
||||
+ if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
|
||||
+ args[addrlo_idx + 1]);
|
||||
+ }
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
|
||||
+ args[addrlo_idx]);
|
||||
|
||||
- /* ld [arg1], arg2 */
|
||||
- tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
|
||||
- INSN_RS2(TCG_REG_G0));
|
||||
+ /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
+ global registers */
|
||||
+ tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
+ sizeof(long));
|
||||
|
||||
- /* subcc arg0, arg2, %g0 */
|
||||
- tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
|
||||
-
|
||||
- /* will become:
|
||||
- be label1
|
||||
- or
|
||||
- be,pt %xcc label1 */
|
||||
- label1_ptr = (uint32_t *)s->code_ptr;
|
||||
- tcg_out32(s, 0);
|
||||
-
|
||||
- /* mov (delay slot) */
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
|
||||
-
|
||||
- /* mov */
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
|
||||
- /* XXX/FIXME: suboptimal */
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
|
||||
- tcg_target_call_iarg_regs[2]);
|
||||
- tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
|
||||
- tcg_target_call_iarg_regs[1]);
|
||||
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
|
||||
- tcg_target_call_iarg_regs[0]);
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
|
||||
- TCG_AREG0);
|
||||
-
|
||||
- /* XXX: move that code at the end of the TB */
|
||||
/* qemu_ld_helper[s_bits](arg0, arg1) */
|
||||
tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
|
||||
- (tcg_target_ulong)s->code_ptr) >> 2)
|
||||
& 0x3fffffff));
|
||||
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
- global registers */
|
||||
- // delay slot
|
||||
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long), HOST_ST_OP);
|
||||
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long), HOST_LD_OP);
|
||||
-
|
||||
- /* data_reg = sign_extend(arg0) */
|
||||
- switch(opc) {
|
||||
+ /* delay slot */
|
||||
+ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
|
||||
+
|
||||
+ /* Reload AREG0. */
|
||||
+ tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
+ sizeof(long));
|
||||
+
|
||||
+ n = tcg_target_call_oarg_regs[0];
|
||||
+ /* datalo = sign_extend(arg0) */
|
||||
+ switch (sizeop) {
|
||||
case 0 | 4:
|
||||
- /* sll arg0, 24/56, data_reg */
|
||||
- tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
|
||||
- HOST_SLL_OP);
|
||||
- /* sra data_reg, 24/56, data_reg */
|
||||
- tcg_out_arithi(s, data_reg, data_reg,
|
||||
- (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
|
||||
+ /* Recall that SRA sign extends from bit 31 through bit 63. */
|
||||
+ tcg_out_arithi(s, datalo, n, 24, SHIFT_SLL);
|
||||
+ tcg_out_arithi(s, datalo, datalo, 24, SHIFT_SRA);
|
||||
break;
|
||||
case 1 | 4:
|
||||
- /* sll arg0, 16/48, data_reg */
|
||||
- tcg_out_arithi(s, data_reg, arg0,
|
||||
- (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
|
||||
- /* sra data_reg, 16/48, data_reg */
|
||||
- tcg_out_arithi(s, data_reg, data_reg,
|
||||
- (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
|
||||
+ tcg_out_arithi(s, datalo, n, 16, SHIFT_SLL);
|
||||
+ tcg_out_arithi(s, datalo, datalo, 16, SHIFT_SRA);
|
||||
break;
|
||||
case 2 | 4:
|
||||
- /* sll arg0, 32, data_reg */
|
||||
- tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
|
||||
- /* sra data_reg, 32, data_reg */
|
||||
- tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
|
||||
+ tcg_out_arithi(s, datalo, n, 0, SHIFT_SRA);
|
||||
break;
|
||||
+ case 3:
|
||||
+ if (TCG_TARGET_REG_BITS == 32) {
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, datahi, n);
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, datalo, n + 1);
|
||||
+ break;
|
||||
+ }
|
||||
+ /* FALLTHRU */
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
- case 3:
|
||||
default:
|
||||
/* mov */
|
||||
- tcg_out_mov(s, TCG_TYPE_REG, data_reg, arg0);
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, datalo, n);
|
||||
break;
|
||||
}
|
||||
|
||||
- /* will become:
|
||||
- ba label2 */
|
||||
- label2_ptr = (uint32_t *)s->code_ptr;
|
||||
- tcg_out32(s, 0);
|
||||
-
|
||||
- /* nop (delay slot */
|
||||
- tcg_out_nop(s);
|
||||
-
|
||||
- /* label1: */
|
||||
-#if TARGET_LONG_BITS == 32
|
||||
- /* be label1 */
|
||||
- *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
|
||||
- INSN_OFF22((unsigned long)s->code_ptr -
|
||||
- (unsigned long)label1_ptr));
|
||||
-#else
|
||||
- /* be,pt %xcc label1 */
|
||||
- *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
|
||||
- (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
|
||||
- (unsigned long)label1_ptr));
|
||||
-#endif
|
||||
-
|
||||
- /* ld [arg1 + x], arg1 */
|
||||
- tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
|
||||
- offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
|
||||
-
|
||||
-#if TARGET_LONG_BITS == 32
|
||||
- /* and addr_reg, x, arg0 */
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
|
||||
- tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
|
||||
- /* add arg0, arg1, arg0 */
|
||||
- tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
|
||||
+ *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
|
||||
+ (unsigned long)label_ptr[1]);
|
||||
#else
|
||||
- /* add addr_reg, arg1, arg0 */
|
||||
- tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
|
||||
-#endif
|
||||
+ addr_reg = args[addrlo_idx];
|
||||
+ if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
|
||||
+ tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
|
||||
+ addr_reg = TCG_REG_I5;
|
||||
+ }
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
|
||||
|
||||
-#else
|
||||
- arg0 = addr_reg;
|
||||
-#endif
|
||||
+ tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
|
||||
|
||||
- switch(opc) {
|
||||
- case 0:
|
||||
- /* ldub [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
|
||||
- break;
|
||||
- case 0 | 4:
|
||||
- /* ldsb [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
|
||||
- break;
|
||||
- case 1:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* lduh [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
|
||||
-#else
|
||||
- /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- case 1 | 4:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* ldsh [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
|
||||
-#else
|
||||
- /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- case 2:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* lduw [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
|
||||
-#else
|
||||
- /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- case 2 | 4:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* ldsw [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
|
||||
-#else
|
||||
- /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- case 3:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* ldx [arg0], data_reg */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, LDX);
|
||||
-#else
|
||||
- /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- default:
|
||||
- tcg_abort();
|
||||
+ tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
|
||||
+ if (reg64 != datalo) {
|
||||
+ tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
|
||||
+ }
|
||||
+ } else {
|
||||
+ tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
|
||||
}
|
||||
-
|
||||
-#if defined(CONFIG_SOFTMMU)
|
||||
- /* label2: */
|
||||
- *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
|
||||
- INSN_OFF22((unsigned long)s->code_ptr -
|
||||
- (unsigned long)label2_ptr));
|
||||
-#endif
|
||||
+#endif /* CONFIG_SOFTMMU */
|
||||
}
|
||||
|
||||
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||
- int opc)
|
||||
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
{
|
||||
- int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
|
||||
+ int addrlo_idx = 1, datalo, datahi, addr_reg;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
- uint32_t *label1_ptr, *label2_ptr;
|
||||
+ int memi_idx, memi, n;
|
||||
+ uint32_t *label_ptr;
|
||||
#endif
|
||||
|
||||
- data_reg = *args++;
|
||||
- addr_reg = *args++;
|
||||
- mem_index = *args;
|
||||
-
|
||||
- s_bits = opc;
|
||||
-
|
||||
- arg0 = TCG_REG_O0;
|
||||
- arg1 = TCG_REG_O1;
|
||||
- arg2 = TCG_REG_O2;
|
||||
+ datahi = datalo = args[0];
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ datahi = args[1];
|
||||
+ addrlo_idx = 2;
|
||||
+ }
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
- /* srl addr_reg, x, arg1 */
|
||||
- tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
|
||||
- SHIFT_SRL);
|
||||
-
|
||||
- /* and addr_reg, x, arg0 */
|
||||
- tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
|
||||
- ARITH_AND);
|
||||
-
|
||||
- /* and arg1, x, arg1 */
|
||||
- tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
|
||||
-
|
||||
- /* add arg1, x, arg1 */
|
||||
- tcg_out_addi(s, arg1, offsetof(CPUArchState,
|
||||
- tlb_table[mem_index][0].addr_write));
|
||||
+ memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
|
||||
+ memi = args[memi_idx];
|
||||
+
|
||||
+ addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, sizeop, args,
|
||||
+ offsetof(CPUTLBEntry, addr_write));
|
||||
+
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ /* Reconstruct the full 64-bit value in %g1, using %o2 as temp. */
|
||||
+ /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
|
||||
+ tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
|
||||
+ tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
|
||||
+ tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
|
||||
+ datalo = TCG_REG_G1;
|
||||
+ }
|
||||
|
||||
- /* add env, arg1, arg1 */
|
||||
- tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
|
||||
+ /* The fast path is exactly one insn. Thus we can perform the entire
|
||||
+ TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
|
||||
+ /* beq,a,pt %[xi]cc, label0 */
|
||||
+ label_ptr = (uint32_t *)s->code_ptr;
|
||||
+ tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1)
|
||||
+ | ((TARGET_LONG_BITS == 64) << 21)
|
||||
+ | (1 << 29) | (1 << 19)));
|
||||
+ /* delay slot */
|
||||
+ tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
|
||||
+
|
||||
+ /* TLB Miss. */
|
||||
+
|
||||
+ n = 0;
|
||||
+ tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
|
||||
+ if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
|
||||
+ args[addrlo_idx + 1]);
|
||||
+ }
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
|
||||
+ args[addrlo_idx]);
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datahi);
|
||||
+ }
|
||||
+ tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datalo);
|
||||
|
||||
- /* ld [arg1], arg2 */
|
||||
- tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
|
||||
- INSN_RS2(TCG_REG_G0));
|
||||
+ /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
+ global registers */
|
||||
+ tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
+ sizeof(long));
|
||||
|
||||
- /* subcc arg0, arg2, %g0 */
|
||||
- tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
|
||||
-
|
||||
- /* will become:
|
||||
- be label1
|
||||
- or
|
||||
- be,pt %xcc label1 */
|
||||
- label1_ptr = (uint32_t *)s->code_ptr;
|
||||
- tcg_out32(s, 0);
|
||||
-
|
||||
- /* mov (delay slot) */
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
|
||||
-
|
||||
- /* mov */
|
||||
- tcg_out_mov(s, TCG_TYPE_REG, arg1, data_reg);
|
||||
-
|
||||
- /* mov */
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
|
||||
-
|
||||
- /* XXX/FIXME: suboptimal */
|
||||
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
|
||||
- tcg_target_call_iarg_regs[2]);
|
||||
- tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
|
||||
- tcg_target_call_iarg_regs[1]);
|
||||
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
|
||||
- tcg_target_call_iarg_regs[0]);
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
|
||||
- TCG_AREG0);
|
||||
- /* XXX: move that code at the end of the TB */
|
||||
/* qemu_st_helper[s_bits](arg0, arg1, arg2) */
|
||||
- tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
|
||||
+ tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[sizeop]
|
||||
- (tcg_target_ulong)s->code_ptr) >> 2)
|
||||
& 0x3fffffff));
|
||||
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
- global registers */
|
||||
- // delay slot
|
||||
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long), HOST_ST_OP);
|
||||
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long), HOST_LD_OP);
|
||||
-
|
||||
- /* will become:
|
||||
- ba label2 */
|
||||
- label2_ptr = (uint32_t *)s->code_ptr;
|
||||
- tcg_out32(s, 0);
|
||||
-
|
||||
- /* nop (delay slot) */
|
||||
- tcg_out_nop(s);
|
||||
+ /* delay slot */
|
||||
+ tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
|
||||
|
||||
-#if TARGET_LONG_BITS == 32
|
||||
- /* be label1 */
|
||||
- *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
|
||||
- INSN_OFF22((unsigned long)s->code_ptr -
|
||||
- (unsigned long)label1_ptr));
|
||||
-#else
|
||||
- /* be,pt %xcc label1 */
|
||||
- *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
|
||||
- (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
|
||||
- (unsigned long)label1_ptr));
|
||||
-#endif
|
||||
-
|
||||
- /* ld [arg1 + x], arg1 */
|
||||
- tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
|
||||
- offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
|
||||
+ /* Reload AREG0. */
|
||||
+ tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
+ sizeof(long));
|
||||
|
||||
-#if TARGET_LONG_BITS == 32
|
||||
- /* and addr_reg, x, arg0 */
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
|
||||
- tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
|
||||
- /* add arg0, arg1, arg0 */
|
||||
- tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
|
||||
+ *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
|
||||
+ (unsigned long)label_ptr);
|
||||
#else
|
||||
- /* add addr_reg, arg1, arg0 */
|
||||
- tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
|
||||
-#endif
|
||||
-
|
||||
-#else
|
||||
- arg0 = addr_reg;
|
||||
-#endif
|
||||
-
|
||||
- switch(opc) {
|
||||
- case 0:
|
||||
- /* stb data_reg, [arg0] */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, STB);
|
||||
- break;
|
||||
- case 1:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* sth data_reg, [arg0] */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, STH);
|
||||
-#else
|
||||
- /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- case 2:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* stw data_reg, [arg0] */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, STW);
|
||||
-#else
|
||||
- /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- case 3:
|
||||
-#ifdef TARGET_WORDS_BIGENDIAN
|
||||
- /* stx data_reg, [arg0] */
|
||||
- tcg_out_ldst(s, data_reg, arg0, 0, STX);
|
||||
-#else
|
||||
- /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
|
||||
- tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
|
||||
-#endif
|
||||
- break;
|
||||
- default:
|
||||
- tcg_abort();
|
||||
+ addr_reg = args[addrlo_idx];
|
||||
+ if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
|
||||
+ tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
|
||||
+ addr_reg = TCG_REG_I5;
|
||||
}
|
||||
-
|
||||
-#if defined(CONFIG_SOFTMMU)
|
||||
- /* label2: */
|
||||
- *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
|
||||
- INSN_OFF22((unsigned long)s->code_ptr -
|
||||
- (unsigned long)label2_ptr));
|
||||
-#endif
|
||||
+ if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
+ /* Reconstruct the full 64-bit value in %g1, using %o2 as temp. */
|
||||
+ /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
|
||||
+ tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
|
||||
+ tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
|
||||
+ tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
|
||||
+ datalo = TCG_REG_G1;
|
||||
+ }
|
||||
+ tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_st_opc[sizeop]);
|
||||
+#endif /* CONFIG_SOFTMMU */
|
||||
}
|
||||
|
||||
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
@@ -1175,12 +1073,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
/* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
global registers */
|
||||
// delay slot
|
||||
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long), HOST_ST_OP);
|
||||
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long), HOST_LD_OP);
|
||||
+ tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
+ sizeof(long));
|
||||
+ tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
+ TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
+ sizeof(long));
|
||||
break;
|
||||
case INDEX_op_jmp:
|
||||
case INDEX_op_br:
|
||||
@@ -1348,6 +1246,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
tcg_out_qemu_ld(s, args, 2 | 4);
|
||||
break;
|
||||
#endif
|
||||
+ case INDEX_op_qemu_ld64:
|
||||
+ tcg_out_qemu_ld(s, args, 3);
|
||||
+ break;
|
||||
case INDEX_op_qemu_st8:
|
||||
tcg_out_qemu_st(s, args, 0);
|
||||
break;
|
||||
@@ -1357,6 +1258,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_qemu_st32:
|
||||
tcg_out_qemu_st(s, args, 2);
|
||||
break;
|
||||
+ case INDEX_op_qemu_st64:
|
||||
+ tcg_out_qemu_st(s, args, 3);
|
||||
+ break;
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
case INDEX_op_movi_i64:
|
||||
@@ -1421,13 +1325,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
args[2], const_args[2]);
|
||||
break;
|
||||
|
||||
- case INDEX_op_qemu_ld64:
|
||||
- tcg_out_qemu_ld(s, args, 3);
|
||||
- break;
|
||||
- case INDEX_op_qemu_st64:
|
||||
- tcg_out_qemu_st(s, args, 3);
|
||||
- break;
|
||||
-
|
||||
#endif
|
||||
gen_arith:
|
||||
tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
|
||||
@@ -1492,20 +1389,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
|
||||
{ INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
|
||||
#endif
|
||||
|
||||
- { INDEX_op_qemu_ld8u, { "r", "L" } },
|
||||
- { INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
- { INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
- { INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
- { INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
-#if TCG_TARGET_REG_BITS == 64
|
||||
- { INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
- { INDEX_op_qemu_ld32s, { "r", "L" } },
|
||||
-#endif
|
||||
-
|
||||
- { INDEX_op_qemu_st8, { "L", "L" } },
|
||||
- { INDEX_op_qemu_st16, { "L", "L" } },
|
||||
- { INDEX_op_qemu_st32, { "L", "L" } },
|
||||
-
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
{ INDEX_op_mov_i64, { "r", "r" } },
|
||||
{ INDEX_op_movi_i64, { "r" } },
|
||||
@@ -1520,8 +1403,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
|
||||
{ INDEX_op_st16_i64, { "r", "r" } },
|
||||
{ INDEX_op_st32_i64, { "r", "r" } },
|
||||
{ INDEX_op_st_i64, { "r", "r" } },
|
||||
- { INDEX_op_qemu_ld64, { "L", "L" } },
|
||||
- { INDEX_op_qemu_st64, { "L", "L" } },
|
||||
|
||||
{ INDEX_op_add_i64, { "r", "r", "rJ" } },
|
||||
{ INDEX_op_mul_i64, { "r", "r", "rJ" } },
|
||||
@@ -1548,10 +1429,48 @@ static const TCGTargetOpDef sparc_op_defs[] = {
|
||||
|
||||
{ INDEX_op_brcond_i64, { "r", "rJ" } },
|
||||
{ INDEX_op_setcond_i64, { "r", "r", "rJ" } },
|
||||
-#else
|
||||
- { INDEX_op_qemu_ld64, { "L", "L", "L" } },
|
||||
+#endif
|
||||
+
|
||||
+#if TCG_TARGET_REG_BITS == 64
|
||||
+ { INDEX_op_qemu_ld8u, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld32u, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld32s, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld64, { "r", "L" } },
|
||||
+
|
||||
+ { INDEX_op_qemu_st8, { "L", "L" } },
|
||||
+ { INDEX_op_qemu_st16, { "L", "L" } },
|
||||
+ { INDEX_op_qemu_st32, { "L", "L" } },
|
||||
+ { INDEX_op_qemu_st64, { "L", "L" } },
|
||||
+#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
|
||||
+ { INDEX_op_qemu_ld8u, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld8s, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld16u, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld16s, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld32, { "r", "L" } },
|
||||
+ { INDEX_op_qemu_ld64, { "r", "r", "L" } },
|
||||
+
|
||||
+ { INDEX_op_qemu_st8, { "L", "L" } },
|
||||
+ { INDEX_op_qemu_st16, { "L", "L" } },
|
||||
+ { INDEX_op_qemu_st32, { "L", "L" } },
|
||||
{ INDEX_op_qemu_st64, { "L", "L", "L" } },
|
||||
+#else
|
||||
+ { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
|
||||
+ { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
|
||||
+ { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
|
||||
+ { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
|
||||
+ { INDEX_op_qemu_ld32, { "r", "L", "L" } },
|
||||
+ { INDEX_op_qemu_ld64, { "L", "L", "L", "L" } },
|
||||
+
|
||||
+ { INDEX_op_qemu_st8, { "L", "L", "L" } },
|
||||
+ { INDEX_op_qemu_st16, { "L", "L", "L" } },
|
||||
+ { INDEX_op_qemu_st32, { "L", "L", "L" } },
|
||||
+ { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
|
||||
#endif
|
||||
+
|
||||
{ -1 },
|
||||
};
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
113
0086-tcg-sparc-Support-GUEST_BASE.patch
Normal file
113
0086-tcg-sparc-Support-GUEST_BASE.patch
Normal file
@ -0,0 +1,113 @@
|
||||
From fecc7bd255206876152baab622c61902133066bd Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sat, 24 Mar 2012 22:11:25 +0100
|
||||
Subject: [PATCH] tcg-sparc: Support GUEST_BASE.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 2 ++
|
||||
tcg/sparc/tcg-target.c | 26 +++++++++++++++++++++++---
|
||||
tcg/sparc/tcg-target.h | 2 ++
|
||||
3 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 0590f16..9139b5c 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -872,6 +872,7 @@ case "$cpu" in
|
||||
if test "$solaris" = "no" ; then
|
||||
QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
|
||||
fi
|
||||
+ host_guest_base="yes"
|
||||
;;
|
||||
sparc64)
|
||||
LDFLAGS="-m64 $LDFLAGS"
|
||||
@@ -880,6 +881,7 @@ case "$cpu" in
|
||||
if test "$solaris" != "no" ; then
|
||||
QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
|
||||
fi
|
||||
+ host_guest_base="yes"
|
||||
;;
|
||||
s390)
|
||||
QEMU_CFLAGS="-m31 -march=z990 $QEMU_CFLAGS"
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index d89c19b..5acfeba 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -59,6 +59,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_USE_GUEST_BASE
|
||||
+# define TCG_GUEST_BASE_REG TCG_REG_I3
|
||||
+#else
|
||||
+# define TCG_GUEST_BASE_REG TCG_REG_G0
|
||||
+#endif
|
||||
+
|
||||
static const int tcg_target_reg_alloc_order[] = {
|
||||
TCG_REG_L0,
|
||||
TCG_REG_L1,
|
||||
@@ -680,6 +686,14 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
|
||||
INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
|
||||
CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
|
||||
+
|
||||
+#ifdef CONFIG_USE_GUEST_BASE
|
||||
+ if (GUEST_BASE != 0) {
|
||||
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
|
||||
INSN_RS2(TCG_REG_G0));
|
||||
tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
|
||||
@@ -925,14 +939,18 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
|
||||
|
||||
- tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
|
||||
+ tcg_out_ldst_rr(s, reg64, addr_reg,
|
||||
+ (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
|
||||
+ qemu_ld_opc[sizeop]);
|
||||
|
||||
tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
|
||||
if (reg64 != datalo) {
|
||||
tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
|
||||
}
|
||||
} else {
|
||||
- tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
|
||||
+ tcg_out_ldst_rr(s, datalo, addr_reg,
|
||||
+ (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
|
||||
+ qemu_ld_opc[sizeop]);
|
||||
}
|
||||
#endif /* CONFIG_SOFTMMU */
|
||||
}
|
||||
@@ -1026,7 +1044,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
|
||||
datalo = TCG_REG_G1;
|
||||
}
|
||||
- tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_st_opc[sizeop]);
|
||||
+ tcg_out_ldst_rr(s, datalo, addr_reg,
|
||||
+ (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
|
||||
+ qemu_st_opc[sizeop]);
|
||||
#endif /* CONFIG_SOFTMMU */
|
||||
}
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
|
||||
index adca1d2..99e9f57 100644
|
||||
--- a/tcg/sparc/tcg-target.h
|
||||
+++ b/tcg/sparc/tcg-target.h
|
||||
@@ -128,6 +128,8 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_movcond_i64 0
|
||||
#endif
|
||||
|
||||
+#define TCG_TARGET_HAS_GUEST_BASE
|
||||
+
|
||||
#ifdef CONFIG_SOLARIS
|
||||
#define TCG_AREG0 TCG_REG_G2
|
||||
#elif HOST_LONG_BITS == 64
|
||||
--
|
||||
1.7.12.1
|
||||
|
51
0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch
Normal file
51
0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From d526285d4339f02e3be64a7287d1e009dd5bff3d Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sun, 25 Mar 2012 19:52:11 +0200
|
||||
Subject: [PATCH] tcg-sparc: Change AREG0 in generated code to %i0.
|
||||
|
||||
We can now move the TCG variable from %g[56] to a call-preserved
|
||||
windowed register.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 3 ++-
|
||||
tcg/sparc/tcg-target.h | 8 +-------
|
||||
2 files changed, 3 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index 5acfeba..9ab5746 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -696,7 +696,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
|
||||
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
|
||||
INSN_RS2(TCG_REG_G0));
|
||||
- tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
|
||||
+ /* delay slot */
|
||||
+ tcg_out_nop(s);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
|
||||
index 99e9f57..ee154d0 100644
|
||||
--- a/tcg/sparc/tcg-target.h
|
||||
+++ b/tcg/sparc/tcg-target.h
|
||||
@@ -130,13 +130,7 @@ typedef enum {
|
||||
|
||||
#define TCG_TARGET_HAS_GUEST_BASE
|
||||
|
||||
-#ifdef CONFIG_SOLARIS
|
||||
-#define TCG_AREG0 TCG_REG_G2
|
||||
-#elif HOST_LONG_BITS == 64
|
||||
-#define TCG_AREG0 TCG_REG_G5
|
||||
-#else
|
||||
-#define TCG_AREG0 TCG_REG_G6
|
||||
-#endif
|
||||
+#define TCG_AREG0 TCG_REG_I0
|
||||
|
||||
static inline void flush_icache_range(tcg_target_ulong start,
|
||||
tcg_target_ulong stop)
|
||||
--
|
||||
1.7.12.1
|
||||
|
203
0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch
Normal file
203
0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch
Normal file
@ -0,0 +1,203 @@
|
||||
From 5767c23140f2c92b899d9caeaa8e08711cb63868 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sun, 25 Mar 2012 21:21:46 +0200
|
||||
Subject: [PATCH] tcg-sparc: Clean up cruft stemming from attempts to use
|
||||
global registers.
|
||||
|
||||
Don't use -ffixed-gN. Don't link statically. Don't save/restore
|
||||
AREG0 around calls. Don't allocate space on the stack for AREG0 save.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
configure | 12 -----------
|
||||
tcg/sparc/tcg-target.c | 55 +++++++++++++++++---------------------------------
|
||||
tcg/sparc/tcg-target.h | 18 +++++++----------
|
||||
3 files changed, 26 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 9139b5c..8ffddf4 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -868,19 +868,11 @@ case "$cpu" in
|
||||
sparc)
|
||||
LDFLAGS="-m32 $LDFLAGS"
|
||||
QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
|
||||
- QEMU_CFLAGS="-ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
|
||||
- if test "$solaris" = "no" ; then
|
||||
- QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
|
||||
- fi
|
||||
host_guest_base="yes"
|
||||
;;
|
||||
sparc64)
|
||||
LDFLAGS="-m64 $LDFLAGS"
|
||||
QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
|
||||
- QEMU_CFLAGS="-ffixed-g5 -ffixed-g6 -ffixed-g7 $QEMU_CFLAGS"
|
||||
- if test "$solaris" != "no" ; then
|
||||
- QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
|
||||
- fi
|
||||
host_guest_base="yes"
|
||||
;;
|
||||
s390)
|
||||
@@ -4055,10 +4047,6 @@ fi
|
||||
|
||||
if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
|
||||
case "$ARCH" in
|
||||
- sparc)
|
||||
- # -static is used to avoid g1/g3 usage by the dynamic linker
|
||||
- ldflags="$linker_script -static $ldflags"
|
||||
- ;;
|
||||
alpha | s390x)
|
||||
# The default placement of the application is fine.
|
||||
;;
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index 9ab5746..e625aa3 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -161,7 +161,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
|
||||
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
|
||||
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
|
||||
tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
|
||||
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O3);
|
||||
break;
|
||||
case 'I':
|
||||
ct->ct |= TCG_CT_CONST_S11;
|
||||
@@ -681,11 +680,22 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
|
||||
/* Generate global QEMU prologue and epilogue code */
|
||||
static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
{
|
||||
- tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
|
||||
- CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
|
||||
+ int tmp_buf_size, frame_size;
|
||||
+
|
||||
+ /* The TCG temp buffer is at the top of the frame, immediately
|
||||
+ below the frame pointer. */
|
||||
+ tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
|
||||
+ tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
|
||||
+ tmp_buf_size);
|
||||
+
|
||||
+ /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
|
||||
+ otherwise the minimal frame usable by callees. */
|
||||
+ frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
|
||||
+ frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
|
||||
+ frame_size += TCG_TARGET_STACK_ALIGN - 1;
|
||||
+ frame_size &= -TCG_TARGET_STACK_ALIGN;
|
||||
tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
|
||||
- INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
|
||||
- CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
|
||||
+ INSN_IMM13(-frame_size));
|
||||
|
||||
#ifdef CONFIG_USE_GUEST_BASE
|
||||
if (GUEST_BASE != 0) {
|
||||
@@ -698,6 +708,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
|
||||
INSN_RS2(TCG_REG_G0));
|
||||
/* delay slot */
|
||||
tcg_out_nop(s);
|
||||
+
|
||||
+ /* No epilogue required. We issue ret + restore directly in the TB. */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
@@ -880,12 +892,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
|
||||
args[addrlo_idx]);
|
||||
|
||||
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
- global registers */
|
||||
- tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long));
|
||||
-
|
||||
/* qemu_ld_helper[s_bits](arg0, arg1) */
|
||||
tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
|
||||
- (tcg_target_ulong)s->code_ptr) >> 2)
|
||||
@@ -893,11 +899,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
/* delay slot */
|
||||
tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
|
||||
|
||||
- /* Reload AREG0. */
|
||||
- tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long));
|
||||
-
|
||||
n = tcg_target_call_oarg_regs[0];
|
||||
/* datalo = sign_extend(arg0) */
|
||||
switch (sizeop) {
|
||||
@@ -1011,12 +1012,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
}
|
||||
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datalo);
|
||||
|
||||
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
- global registers */
|
||||
- tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long));
|
||||
-
|
||||
/* qemu_st_helper[s_bits](arg0, arg1, arg2) */
|
||||
tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[sizeop]
|
||||
- (tcg_target_ulong)s->code_ptr) >> 2)
|
||||
@@ -1024,11 +1019,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
/* delay slot */
|
||||
tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
|
||||
|
||||
- /* Reload AREG0. */
|
||||
- tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long));
|
||||
-
|
||||
*label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
|
||||
(unsigned long)label_ptr);
|
||||
#else
|
||||
@@ -1091,15 +1081,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
|
||||
INSN_RS2(TCG_REG_G0));
|
||||
}
|
||||
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
|
||||
- global registers */
|
||||
- // delay slot
|
||||
- tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long));
|
||||
- tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
|
||||
- TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
|
||||
- sizeof(long));
|
||||
+ /* delay slot */
|
||||
+ tcg_out_nop(s);
|
||||
break;
|
||||
case INDEX_op_jmp:
|
||||
case INDEX_op_br:
|
||||
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
|
||||
index ee154d0..6314ffb 100644
|
||||
--- a/tcg/sparc/tcg-target.h
|
||||
+++ b/tcg/sparc/tcg-target.h
|
||||
@@ -66,20 +66,16 @@ typedef enum {
|
||||
#define TCG_CT_CONST_S13 0x200
|
||||
|
||||
/* used for function call generation */
|
||||
-#define TCG_REG_CALL_STACK TCG_REG_I6
|
||||
+#define TCG_REG_CALL_STACK TCG_REG_O6
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
-// Reserve space for AREG0
|
||||
-#define TCG_TARGET_STACK_MINFRAME (176 + 4 * (int)sizeof(long) + \
|
||||
- TCG_STATIC_CALL_ARGS_SIZE)
|
||||
-#define TCG_TARGET_CALL_STACK_OFFSET (2047 - 16)
|
||||
-#define TCG_TARGET_STACK_ALIGN 16
|
||||
+#define TCG_TARGET_STACK_BIAS 2047
|
||||
+#define TCG_TARGET_STACK_ALIGN 16
|
||||
+#define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS)
|
||||
#else
|
||||
-// AREG0 + one word for alignment
|
||||
-#define TCG_TARGET_STACK_MINFRAME (92 + (2 + 1) * (int)sizeof(long) + \
|
||||
- TCG_STATIC_CALL_ARGS_SIZE)
|
||||
-#define TCG_TARGET_CALL_STACK_OFFSET TCG_TARGET_STACK_MINFRAME
|
||||
-#define TCG_TARGET_STACK_ALIGN 8
|
||||
+#define TCG_TARGET_STACK_BIAS 0
|
||||
+#define TCG_TARGET_STACK_ALIGN 8
|
||||
+#define TCG_TARGET_CALL_STACK_OFFSET (64 + 4 + 6*4)
|
||||
#endif
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
--
|
||||
1.7.12.1
|
||||
|
@ -0,0 +1,62 @@
|
||||
From 12e60f780a097837840ab1e7bb7d54b8c15112e8 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sun, 25 Mar 2012 21:36:28 +0200
|
||||
Subject: [PATCH] tcg-sparc: Mask shift immediates to avoid illegal insns.
|
||||
|
||||
The xtensa-test image generates a sra_i32 with count 0x40.
|
||||
Whether this is accident of tcg constant propagation or
|
||||
originating directly from the instruction stream is immaterial.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index e625aa3..be5c170 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -1154,13 +1154,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
goto gen_arith;
|
||||
case INDEX_op_shl_i32:
|
||||
c = SHIFT_SLL;
|
||||
- goto gen_arith;
|
||||
+ do_shift32:
|
||||
+ /* Limit immediate shift count lest we create an illegal insn. */
|
||||
+ tcg_out_arithc(s, args[0], args[1], args[2] & 31, const_args[2], c);
|
||||
+ break;
|
||||
case INDEX_op_shr_i32:
|
||||
c = SHIFT_SRL;
|
||||
- goto gen_arith;
|
||||
+ goto do_shift32;
|
||||
case INDEX_op_sar_i32:
|
||||
c = SHIFT_SRA;
|
||||
- goto gen_arith;
|
||||
+ goto do_shift32;
|
||||
case INDEX_op_mul_i32:
|
||||
c = ARITH_UMUL;
|
||||
goto gen_arith;
|
||||
@@ -1281,13 +1284,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
break;
|
||||
case INDEX_op_shl_i64:
|
||||
c = SHIFT_SLLX;
|
||||
- goto gen_arith;
|
||||
+ do_shift64:
|
||||
+ /* Limit immediate shift count lest we create an illegal insn. */
|
||||
+ tcg_out_arithc(s, args[0], args[1], args[2] & 63, const_args[2], c);
|
||||
+ break;
|
||||
case INDEX_op_shr_i64:
|
||||
c = SHIFT_SRLX;
|
||||
- goto gen_arith;
|
||||
+ goto do_shift64;
|
||||
case INDEX_op_sar_i64:
|
||||
c = SHIFT_SRAX;
|
||||
- goto gen_arith;
|
||||
+ goto do_shift64;
|
||||
case INDEX_op_mul_i64:
|
||||
c = ARITH_MULX;
|
||||
goto gen_arith;
|
||||
--
|
||||
1.7.12.1
|
||||
|
275
0090-tcg-sparc-Use-defines-for-temporaries.patch
Normal file
275
0090-tcg-sparc-Use-defines-for-temporaries.patch
Normal file
@ -0,0 +1,275 @@
|
||||
From fc9726f880dea515a2cf98456c5f03a1388e4e14 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sun, 25 Mar 2012 22:04:59 +0200
|
||||
Subject: [PATCH] tcg-sparc: Use defines for temporaries.
|
||||
|
||||
And change from %i4/%i5 to %g1/%o7 to remove a v8plus fixme.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 115 +++++++++++++++++++++++++------------------------
|
||||
1 file changed, 59 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index be5c170..d401f8e 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -59,8 +59,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
+/* Define some temporary registers. T2 is used for constant generation. */
|
||||
+#define TCG_REG_T1 TCG_REG_G1
|
||||
+#define TCG_REG_T2 TCG_REG_O7
|
||||
+
|
||||
#ifdef CONFIG_USE_GUEST_BASE
|
||||
-# define TCG_GUEST_BASE_REG TCG_REG_I3
|
||||
+# define TCG_GUEST_BASE_REG TCG_REG_I5
|
||||
#else
|
||||
# define TCG_GUEST_BASE_REG TCG_REG_G0
|
||||
#endif
|
||||
@@ -79,6 +83,7 @@ static const int tcg_target_reg_alloc_order[] = {
|
||||
TCG_REG_I2,
|
||||
TCG_REG_I3,
|
||||
TCG_REG_I4,
|
||||
+ TCG_REG_I5,
|
||||
};
|
||||
|
||||
static const int tcg_target_call_iarg_regs[6] = {
|
||||
@@ -366,10 +371,10 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
|
||||
tcg_out_sethi(s, ret, ~arg);
|
||||
tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
|
||||
} else {
|
||||
- tcg_out_movi_imm32(s, TCG_REG_I4, arg >> (TCG_TARGET_REG_BITS / 2));
|
||||
- tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
|
||||
- tcg_out_movi_imm32(s, ret, arg);
|
||||
- tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
|
||||
+ tcg_out_movi_imm32(s, ret, arg >> (TCG_TARGET_REG_BITS / 2));
|
||||
+ tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
|
||||
+ tcg_out_movi_imm32(s, TCG_REG_T2, arg);
|
||||
+ tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,8 +391,8 @@ static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
|
||||
tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
|
||||
INSN_IMM13(offset));
|
||||
} else {
|
||||
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
|
||||
- tcg_out_ldst_rr(s, ret, addr, TCG_REG_I5, op);
|
||||
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, offset);
|
||||
+ tcg_out_ldst_rr(s, ret, addr, TCG_REG_T1, op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,8 +433,8 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
|
||||
if (check_fit_tl(val, 13))
|
||||
tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
|
||||
else {
|
||||
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
|
||||
- tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
|
||||
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, val);
|
||||
+ tcg_out_arith(s, reg, reg, TCG_REG_T1, ARITH_ADD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,8 +446,8 @@ static inline void tcg_out_andi(TCGContext *s, int rd, int rs,
|
||||
if (check_fit_tl(val, 13))
|
||||
tcg_out_arithi(s, rd, rs, val, ARITH_AND);
|
||||
else {
|
||||
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
|
||||
- tcg_out_arith(s, rd, rs, TCG_REG_I5, ARITH_AND);
|
||||
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T1, val);
|
||||
+ tcg_out_arith(s, rd, rs, TCG_REG_T1, ARITH_AND);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,8 +459,8 @@ static void tcg_out_div32(TCGContext *s, int rd, int rs1,
|
||||
if (uns) {
|
||||
tcg_out_sety(s, TCG_REG_G0);
|
||||
} else {
|
||||
- tcg_out_arithi(s, TCG_REG_I5, rs1, 31, SHIFT_SRA);
|
||||
- tcg_out_sety(s, TCG_REG_I5);
|
||||
+ tcg_out_arithi(s, TCG_REG_T1, rs1, 31, SHIFT_SRA);
|
||||
+ tcg_out_sety(s, TCG_REG_T1);
|
||||
}
|
||||
|
||||
tcg_out_arithc(s, rd, rs1, val2, val2const,
|
||||
@@ -601,8 +606,8 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
|
||||
case TCG_COND_GTU:
|
||||
case TCG_COND_GEU:
|
||||
if (c2const && c2 != 0) {
|
||||
- tcg_out_movi_imm13(s, TCG_REG_I5, c2);
|
||||
- c2 = TCG_REG_I5;
|
||||
+ tcg_out_movi_imm13(s, TCG_REG_T1, c2);
|
||||
+ c2 = TCG_REG_T1;
|
||||
}
|
||||
t = c1, c1 = c2, c2 = t, c2const = 0;
|
||||
cond = tcg_swap_cond(cond);
|
||||
@@ -649,15 +654,15 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
|
||||
|
||||
switch (cond) {
|
||||
case TCG_COND_EQ:
|
||||
- tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_I5, al, bl, blconst);
|
||||
+ tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_T1, al, bl, blconst);
|
||||
tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst);
|
||||
- tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_AND);
|
||||
+ tcg_out_arith(s, ret, ret, TCG_REG_T1, ARITH_AND);
|
||||
break;
|
||||
|
||||
case TCG_COND_NE:
|
||||
- tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_I5, al, al, blconst);
|
||||
+ tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_T1, al, al, blconst);
|
||||
tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst);
|
||||
- tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR);
|
||||
+ tcg_out_arith(s, ret, ret, TCG_REG_T1, ARITH_OR);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -935,8 +940,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
#else
|
||||
addr_reg = args[addrlo_idx];
|
||||
if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
|
||||
- tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
|
||||
- addr_reg = TCG_REG_I5;
|
||||
+ tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
|
||||
+ addr_reg = TCG_REG_T1;
|
||||
}
|
||||
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
|
||||
@@ -979,12 +984,11 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
offsetof(CPUTLBEntry, addr_write));
|
||||
|
||||
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
- /* Reconstruct the full 64-bit value in %g1, using %o2 as temp. */
|
||||
- /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
|
||||
- tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
|
||||
+ /* Reconstruct the full 64-bit value. */
|
||||
+ tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
|
||||
tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
|
||||
- tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
|
||||
- datalo = TCG_REG_G1;
|
||||
+ tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
|
||||
+ datalo = TCG_REG_O2;
|
||||
}
|
||||
|
||||
/* The fast path is exactly one insn. Thus we can perform the entire
|
||||
@@ -1024,16 +1028,14 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
|
||||
#else
|
||||
addr_reg = args[addrlo_idx];
|
||||
if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
|
||||
- tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
|
||||
- addr_reg = TCG_REG_I5;
|
||||
+ tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
|
||||
+ addr_reg = TCG_REG_T1;
|
||||
}
|
||||
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
|
||||
- /* Reconstruct the full 64-bit value in %g1, using %o2 as temp. */
|
||||
- /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
|
||||
- tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
|
||||
+ tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
|
||||
tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
|
||||
- tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
|
||||
- datalo = TCG_REG_G1;
|
||||
+ tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
|
||||
+ datalo = TCG_REG_O2;
|
||||
}
|
||||
tcg_out_ldst_rr(s, datalo, addr_reg,
|
||||
(GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
|
||||
@@ -1057,28 +1059,29 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_goto_tb:
|
||||
if (s->tb_jmp_offset) {
|
||||
/* direct jump method */
|
||||
- tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
|
||||
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
|
||||
+ tcg_out_sethi(s, TCG_REG_T1, args[0] & 0xffffe000);
|
||||
+ tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
|
||||
INSN_IMM13((args[0] & 0x1fff)));
|
||||
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
|
||||
} else {
|
||||
/* indirect jump method */
|
||||
- tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
|
||||
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
|
||||
+ tcg_out_ld_ptr(s, TCG_REG_T1,
|
||||
+ (tcg_target_long)(s->tb_next + args[0]));
|
||||
+ tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
|
||||
INSN_RS2(TCG_REG_G0));
|
||||
}
|
||||
tcg_out_nop(s);
|
||||
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
|
||||
break;
|
||||
case INDEX_op_call:
|
||||
- if (const_args[0])
|
||||
+ if (const_args[0]) {
|
||||
tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
|
||||
- (tcg_target_ulong)s->code_ptr) >> 2)
|
||||
& 0x3fffffff));
|
||||
- else {
|
||||
- tcg_out_ld_ptr(s, TCG_REG_I5,
|
||||
+ } else {
|
||||
+ tcg_out_ld_ptr(s, TCG_REG_T1,
|
||||
(tcg_target_long)(s->tb_next + args[0]));
|
||||
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
|
||||
+ tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_T1) |
|
||||
INSN_RS2(TCG_REG_G0));
|
||||
}
|
||||
/* delay slot */
|
||||
@@ -1184,11 +1187,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
|
||||
case INDEX_op_rem_i32:
|
||||
case INDEX_op_remu_i32:
|
||||
- tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
|
||||
+ tcg_out_div32(s, TCG_REG_T1, args[1], args[2], const_args[2],
|
||||
opc == INDEX_op_remu_i32);
|
||||
- tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
|
||||
+ tcg_out_arithc(s, TCG_REG_T1, TCG_REG_T1, args[2], const_args[2],
|
||||
ARITH_UMUL);
|
||||
- tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
|
||||
+ tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
|
||||
break;
|
||||
|
||||
case INDEX_op_brcond_i32:
|
||||
@@ -1305,11 +1308,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
goto gen_arith;
|
||||
case INDEX_op_rem_i64:
|
||||
case INDEX_op_remu_i64:
|
||||
- tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
|
||||
+ tcg_out_arithc(s, TCG_REG_T1, args[1], args[2], const_args[2],
|
||||
opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
|
||||
- tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
|
||||
+ tcg_out_arithc(s, TCG_REG_T1, TCG_REG_T1, args[2], const_args[2],
|
||||
ARITH_MULX);
|
||||
- tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
|
||||
+ tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
|
||||
break;
|
||||
case INDEX_op_ext32s_i64:
|
||||
if (const_args[1]) {
|
||||
@@ -1507,15 +1510,15 @@ static void tcg_target_init(TCGContext *s)
|
||||
(1 << TCG_REG_O7));
|
||||
|
||||
tcg_regset_clear(s->reserved_regs);
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
|
||||
-#if TCG_TARGET_REG_BITS == 64
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
|
||||
-#endif
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
|
||||
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
|
||||
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
|
||||
+
|
||||
tcg_add_target_add_op_defs(sparc_op_defs);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.12.1
|
||||
|
44
0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch
Normal file
44
0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From ca72cdf648b56d851c4bc9145a1abfcbeeec0579 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Sun, 25 Mar 2012 22:43:17 +0200
|
||||
Subject: [PATCH] tcg-sparc: Add %g/%o registers to alloc_order
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
tcg/sparc/tcg-target.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index d401f8e..03c385a 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -78,12 +78,25 @@ static const int tcg_target_reg_alloc_order[] = {
|
||||
TCG_REG_L5,
|
||||
TCG_REG_L6,
|
||||
TCG_REG_L7,
|
||||
+
|
||||
TCG_REG_I0,
|
||||
TCG_REG_I1,
|
||||
TCG_REG_I2,
|
||||
TCG_REG_I3,
|
||||
TCG_REG_I4,
|
||||
TCG_REG_I5,
|
||||
+
|
||||
+ TCG_REG_G2,
|
||||
+ TCG_REG_G3,
|
||||
+ TCG_REG_G4,
|
||||
+ TCG_REG_G5,
|
||||
+
|
||||
+ TCG_REG_O0,
|
||||
+ TCG_REG_O1,
|
||||
+ TCG_REG_O2,
|
||||
+ TCG_REG_O3,
|
||||
+ TCG_REG_O4,
|
||||
+ TCG_REG_O5,
|
||||
};
|
||||
|
||||
static const int tcg_target_call_iarg_regs[6] = {
|
||||
--
|
||||
1.7.12.1
|
||||
|
79
0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch
Normal file
79
0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch
Normal file
@ -0,0 +1,79 @@
|
||||
From 1338a6f18ff9b651c12ee1f7edd1d2b7684bd6aa Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <rth@twiddle.net>
|
||||
Date: Fri, 21 Sep 2012 10:48:51 -0700
|
||||
Subject: [PATCH] tcg-sparc: Fix and enable direct TB chaining.
|
||||
|
||||
Signed-off-by: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
exec-all.h | 9 ++++++---
|
||||
tcg/sparc/tcg-target.c | 21 ++++++++++++++++++---
|
||||
2 files changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/exec-all.h b/exec-all.h
|
||||
index c5d3a13..1f81da7 100644
|
||||
--- a/exec-all.h
|
||||
+++ b/exec-all.h
|
||||
@@ -132,9 +132,10 @@ static inline void tlb_flush(CPUArchState *env, int flush_global)
|
||||
#define CODE_GEN_AVG_BLOCK_SIZE 64
|
||||
#endif
|
||||
|
||||
-#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
|
||||
-#define USE_DIRECT_JUMP
|
||||
-#elif defined(CONFIG_TCG_INTERPRETER)
|
||||
+#if defined(__arm__) || defined(_ARCH_PPC) \
|
||||
+ || defined(__x86_64__) || defined(__i386__) \
|
||||
+ || defined(__sparc__) \
|
||||
+ || defined(CONFIG_TCG_INTERPRETER)
|
||||
#define USE_DIRECT_JUMP
|
||||
#endif
|
||||
|
||||
@@ -244,6 +245,8 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
|
||||
__asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
|
||||
#endif
|
||||
}
|
||||
+#elif defined(__sparc__)
|
||||
+void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
|
||||
#else
|
||||
#error tb_set_jmp_target1 is missing
|
||||
#endif
|
||||
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
|
||||
index 03c385a..1db0c9d 100644
|
||||
--- a/tcg/sparc/tcg-target.c
|
||||
+++ b/tcg/sparc/tcg-target.c
|
||||
@@ -1072,10 +1072,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
|
||||
case INDEX_op_goto_tb:
|
||||
if (s->tb_jmp_offset) {
|
||||
/* direct jump method */
|
||||
- tcg_out_sethi(s, TCG_REG_T1, args[0] & 0xffffe000);
|
||||
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
|
||||
- INSN_IMM13((args[0] & 0x1fff)));
|
||||
+ uint32_t old_insn = *(uint32_t *)s->code_ptr;
|
||||
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
|
||||
+ /* Make sure to preserve links during retranslation. */
|
||||
+ tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
|
||||
} else {
|
||||
/* indirect jump method */
|
||||
tcg_out_ld_ptr(s, TCG_REG_T1,
|
||||
@@ -1595,3 +1595,18 @@ void tcg_register_jit(void *buf, size_t buf_size)
|
||||
|
||||
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
|
||||
}
|
||||
+
|
||||
+void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
|
||||
+{
|
||||
+ uint32_t *ptr = (uint32_t *)jmp_addr;
|
||||
+ tcg_target_long disp = (tcg_target_long)(addr - jmp_addr) >> 2;
|
||||
+
|
||||
+ /* We can reach the entire address space for 32-bit. For 64-bit
|
||||
+ the code_gen_buffer can't be larger than 2GB. */
|
||||
+ if (TCG_TARGET_REG_BITS == 64 && !check_fit_tl(disp, 30)) {
|
||||
+ tcg_abort();
|
||||
+ }
|
||||
+
|
||||
+ *ptr = CALL | (disp & 0x3fffffff);
|
||||
+ flush_icache_range(jmp_addr, jmp_addr + 4);
|
||||
+}
|
||||
--
|
||||
1.7.12.1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user