Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20181226' int…
Browse files Browse the repository at this point in the history
…o staging

Host support for riscv64.
Dead code elimination pass.
Register allocation improvements.

# gpg: Signature made Tue 25 Dec 2018 20:52:34 GMT
# gpg:                using RSA key 64DF38E8AF7E215F
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>"
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-tcg-20181226: (42 commits)
  tcg: Improve call argument loading
  tcg: Record register preferences during liveness
  tcg: Add TCG_OPF_BB_EXIT
  tcg: Split out more subroutines from liveness_pass_1
  tcg: Rename and adjust liveness_pass_1 helpers
  tcg: Reindent parts of liveness_pass_1
  tcg: Dump register preference info with liveness
  tcg: Improve register allocation for matching constraints
  tcg: Add output_pref to TCGOp
  tcg: Add preferred_reg argument to tcg_reg_alloc_do_movi
  tcg: Add preferred_reg argument to temp_sync
  tcg: Add preferred_reg argument to temp_load
  tcg: Add preferred_reg argument to tcg_reg_alloc
  tcg: Add reachable_code_pass
  tcg: Reference count labels
  tcg: Add TCG_CALL_NO_RETURN
  tcg: Renumber TCG_CALL_* flags
  linux-user: Add safe_syscall for riscv64 host
  disas/microblaze: Remove unused REG_SP macro
  configure: Add support for building RISC-V host
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jan 3, 2019
2 parents 9b2e891 + 4250da1 commit 1b3e800
Show file tree
Hide file tree
Showing 19 changed files with 2,945 additions and 164 deletions.
12 changes: 11 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ S: Maintained
F: target/riscv/
F: hw/riscv/
F: include/hw/riscv/
F: disas/riscv.c
F: linux-user/host/riscv32/
F: linux-user/host/riscv64/

S390
M: Richard Henderson <rth@twiddle.net>
Expand Down Expand Up @@ -2172,6 +2173,15 @@ S: Odd Fixes
F: tcg/ppc/
F: disas/ppc.c

RISC-V
M: Michael Clark <mjc@sifive.com>
M: Palmer Dabbelt <palmer@sifive.com>
M: Alistair Francis <Alistair.Francis@wdc.com>
L: qemu-riscv@nongnu.org
S: Maintained
F: tcg/riscv/
F: disas/riscv.c

S390 target
M: Richard Henderson <rth@twiddle.net>
S: Maintained
Expand Down
75 changes: 75 additions & 0 deletions accel/tcg/user-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,81 @@ int cpu_signal_handler(int host_signum, void *pinfo,
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
}

#elif defined(__riscv)

int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
{
siginfo_t *info = pinfo;
ucontext_t *uc = puc;
greg_t pc = uc->uc_mcontext.__gregs[REG_PC];
uint32_t insn = *(uint32_t *)pc;
int is_write = 0;

/* Detect store by reading the instruction at the program
counter. Note: we currently only generate 32-bit
instructions so we thus only detect 32-bit stores */
switch (((insn >> 0) & 0b11)) {
case 3:
switch (((insn >> 2) & 0b11111)) {
case 8:
switch (((insn >> 12) & 0b111)) {
case 0: /* sb */
case 1: /* sh */
case 2: /* sw */
case 3: /* sd */
case 4: /* sq */
is_write = 1;
break;
default:
break;
}
break;
case 9:
switch (((insn >> 12) & 0b111)) {
case 2: /* fsw */
case 3: /* fsd */
case 4: /* fsq */
is_write = 1;
break;
default:
break;
}
break;
default:
break;
}
}

/* Check for compressed instructions */
switch (((insn >> 13) & 0b111)) {
case 7:
switch (insn & 0b11) {
case 0: /*c.sd */
case 2: /* c.sdsp */
is_write = 1;
break;
default:
break;
}
break;
case 6:
switch (insn & 0b11) {
case 0: /* c.sw */
case 3: /* c.swsp */
is_write = 1;
break;
default:
break;
}
break;
default:
break;
}

return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
}

#else

#error host CPU specific signal handler needed
Expand Down
12 changes: 10 additions & 2 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,12 @@ elif check_define __s390__ ; then
else
cpu="s390"
fi
elif check_define __riscv ; then
if check_define _LP64 ; then
cpu="riscv64"
else
cpu="riscv32"
fi
elif check_define __arm__ ; then
cpu="arm"
elif check_define __aarch64__ ; then
Expand All @@ -722,7 +728,7 @@ ARCH=
# Normalise host CPU name and set ARCH.
# Note that this case should only have supported host CPUs, not guests.
case "$cpu" in
ppc|ppc64|s390|s390x|sparc64|x32)
ppc|ppc64|s390|s390x|sparc64|x32|riscv32|riscv64)
cpu="$cpu"
supported_cpu="yes"
eval "cross_cc_${cpu}=\$host_cc"
Expand Down Expand Up @@ -6937,6 +6943,8 @@ elif test "$ARCH" = "x86_64" -o "$ARCH" = "x32" ; then
QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/i386 $QEMU_INCLUDES"
elif test "$ARCH" = "ppc64" ; then
QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/ppc $QEMU_INCLUDES"
elif test "$ARCH" = "riscv32" -o "$ARCH" = "riscv64" ; then
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/riscv $QEMU_INCLUDES"
else
QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/\$(ARCH) $QEMU_INCLUDES"
fi
Expand Down Expand Up @@ -7433,7 +7441,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
ppc*)
disas_config "PPC"
;;
riscv)
riscv*)
disas_config "RISCV"
;;
s390*)
Expand Down
10 changes: 8 additions & 2 deletions disas.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,14 @@ void disas(FILE *out, void *code, unsigned long size)
# ifdef _ARCH_PPC64
s.info.cap_mode = CS_MODE_64;
# endif
#elif defined(__riscv__)
print_insn = print_insn_riscv;
#elif defined(__riscv) && defined(CONFIG_RISCV_DIS)
#if defined(_ILP32) || (__riscv_xlen == 32)
print_insn = print_insn_riscv32;
#elif defined(_LP64)
print_insn = print_insn_riscv64;
#else
#error unsupported RISC-V ABI
#endif
#elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS)
print_insn = print_insn_arm_a64;
s.info.cap_arch = CS_ARCH_ARM64;
Expand Down
1 change: 0 additions & 1 deletion disas/microblaze.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ enum microblaze_instr_type {
#define REG_TLBSX 36869 /* MMU: TLB Search Index reg */

/* alternate names for gen purpose regs */
#define REG_SP 1 /* stack pointer */
#define REG_ROSDP 2 /* read-only small data pointer */
#define REG_RWSDP 13 /* read-write small data pointer */

Expand Down
55 changes: 55 additions & 0 deletions include/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,61 @@ typedef struct {
#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */

/* RISC-V relocations. */
#define R_RISCV_NONE 0
#define R_RISCV_32 1
#define R_RISCV_64 2
#define R_RISCV_RELATIVE 3
#define R_RISCV_COPY 4
#define R_RISCV_JUMP_SLOT 5
#define R_RISCV_TLS_DTPMOD32 6
#define R_RISCV_TLS_DTPMOD64 7
#define R_RISCV_TLS_DTPREL32 8
#define R_RISCV_TLS_DTPREL64 9
#define R_RISCV_TLS_TPREL32 10
#define R_RISCV_TLS_TPREL64 11
#define R_RISCV_BRANCH 16
#define R_RISCV_JAL 17
#define R_RISCV_CALL 18
#define R_RISCV_CALL_PLT 19
#define R_RISCV_GOT_HI20 20
#define R_RISCV_TLS_GOT_HI20 21
#define R_RISCV_TLS_GD_HI20 22
#define R_RISCV_PCREL_HI20 23
#define R_RISCV_PCREL_LO12_I 24
#define R_RISCV_PCREL_LO12_S 25
#define R_RISCV_HI20 26
#define R_RISCV_LO12_I 27
#define R_RISCV_LO12_S 28
#define R_RISCV_TPREL_HI20 29
#define R_RISCV_TPREL_LO12_I 30
#define R_RISCV_TPREL_LO12_S 31
#define R_RISCV_TPREL_ADD 32
#define R_RISCV_ADD8 33
#define R_RISCV_ADD16 34
#define R_RISCV_ADD32 35
#define R_RISCV_ADD64 36
#define R_RISCV_SUB8 37
#define R_RISCV_SUB16 38
#define R_RISCV_SUB32 39
#define R_RISCV_SUB64 40
#define R_RISCV_GNU_VTINHERIT 41
#define R_RISCV_GNU_VTENTRY 42
#define R_RISCV_ALIGN 43
#define R_RISCV_RVC_BRANCH 44
#define R_RISCV_RVC_JUMP 45
#define R_RISCV_RVC_LUI 46
#define R_RISCV_GPREL_I 47
#define R_RISCV_GPREL_S 48
#define R_RISCV_TPREL_I 49
#define R_RISCV_TPREL_S 50
#define R_RISCV_RELAX 51
#define R_RISCV_SUB6 52
#define R_RISCV_SET6 53
#define R_RISCV_SET8 54
#define R_RISCV_SET16 55
#define R_RISCV_SET32 56

typedef struct elf32_rel {
Elf32_Addr r_offset;
Elf32_Word r_info;
Expand Down
13 changes: 13 additions & 0 deletions include/exec/helper-head.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,19 @@
#define dh_is_signed_env dh_is_signed_ptr
#define dh_is_signed(t) dh_is_signed_##t

#define dh_callflag_i32 0
#define dh_callflag_s32 0
#define dh_callflag_int 0
#define dh_callflag_i64 0
#define dh_callflag_s64 0
#define dh_callflag_f16 0
#define dh_callflag_f32 0
#define dh_callflag_f64 0
#define dh_callflag_ptr 0
#define dh_callflag_void 0
#define dh_callflag_noreturn TCG_CALL_NO_RETURN
#define dh_callflag(t) glue(dh_callflag_, dh_alias(t))

#define dh_sizemask(t, n) \
((dh_is_64bit(t) << (n*2)) | (dh_is_signed(t) << (n*2+1)))

Expand Down
21 changes: 14 additions & 7 deletions include/exec/helper-tcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,43 @@
#define str(s) #s

#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) },

#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },

#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
| dh_sizemask(t2, 2) },

#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },

#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },

#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
| dh_sizemask(t5, 5) },

#define DEF_HELPER_FLAGS_6(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6) \
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
{ .func = HELPER(NAME), .name = str(NAME), \
.flags = FLAGS | dh_callflag(ret), \
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
| dh_sizemask(t5, 5) | dh_sizemask(t6, 6) },
Expand Down
1 change: 1 addition & 0 deletions include/exec/poison.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#pragma GCC poison CONFIG_MOXIE_DIS
#pragma GCC poison CONFIG_NIOS2_DIS
#pragma GCC poison CONFIG_PPC_DIS
#pragma GCC poison CONFIG_RISCV_DIS
#pragma GCC poison CONFIG_S390_DIS
#pragma GCC poison CONFIG_SH4_DIS
#pragma GCC poison CONFIG_SPARC_DIS
Expand Down
11 changes: 11 additions & 0 deletions linux-user/host/riscv32/hostdep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* hostdep.h : things which are dependent on the host architecture
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#ifndef RISCV32_HOSTDEP_H
#define RISCV32_HOSTDEP_H

#endif
34 changes: 34 additions & 0 deletions linux-user/host/riscv64/hostdep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* hostdep.h : things which are dependent on the host architecture
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#ifndef RISCV64_HOSTDEP_H
#define RISCV64_HOSTDEP_H

/* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL

#ifndef __ASSEMBLER__

/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];

/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
unsigned long *pcreg = &uc->uc_mcontext.__gregs[REG_PC];

if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}

#endif /* __ASSEMBLER__ */

#endif
Loading

0 comments on commit 1b3e800

Please sign in to comment.