diff options
-rw-r--r-- | accel/tcg/tcg-runtime.h | 11 | ||||
-rw-r--r-- | docs/devel/tracing.txt | 3 | ||||
-rw-r--r-- | include/exec/helper-proto.h | 4 | ||||
-rw-r--r-- | include/tcg/tcg-op.h | 2 | ||||
-rw-r--r-- | meson.build | 3 | ||||
-rwxr-xr-x | scripts/tracetool.py | 12 | ||||
-rw-r--r-- | scripts/tracetool/__init__.py | 53 | ||||
-rw-r--r-- | scripts/tracetool/backend/ftrace.py | 4 | ||||
-rw-r--r-- | scripts/tracetool/backend/log.py | 4 | ||||
-rw-r--r-- | scripts/tracetool/backend/syslog.py | 4 | ||||
-rw-r--r-- | tcg/riscv/tcg-target.c.inc | 12 | ||||
-rw-r--r-- | tcg/tcg-op-gvec.c | 32 | ||||
-rw-r--r-- | trace/control.c | 12 | ||||
-rw-r--r-- | trace/control.h | 3 | ||||
-rw-r--r-- | trace/meson.build | 21 |
15 files changed, 138 insertions, 42 deletions
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h index 4eda24e63a..2e36d6eb0c 100644 --- a/accel/tcg/tcg-runtime.h +++ b/accel/tcg/tcg-runtime.h @@ -28,6 +28,17 @@ DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env) DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env) +#ifndef IN_HELPER_PROTO +/* + * Pass calls to memset directly to libc, without a thunk in qemu. + * Do not re-declare memset, especially since we fudge the type here; + * we assume sizeof(void *) == sizeof(size_t), which is true for + * all supported hosts. + */ +#define helper_memset memset +DEF_HELPER_FLAGS_3(memset, TCG_CALL_NO_RWG, ptr, ptr, int, ptr) +#endif /* IN_HELPER_PROTO */ + #ifdef CONFIG_SOFTMMU DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG, diff --git a/docs/devel/tracing.txt b/docs/devel/tracing.txt index d2160655b4..dba43fc7a4 100644 --- a/docs/devel/tracing.txt +++ b/docs/devel/tracing.txt @@ -318,7 +318,8 @@ probes: --target-type system \ --target-name x86_64 \ --group=all \ - trace-events-all >qemu.stp + trace-events-all \ + qemu.stp To facilitate simple usage of systemtap where there merely needs to be printf logging of certain probes, a helper script "qemu-trace-stap" is provided. diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h index a0a8d9aa46..659f9298e8 100644 --- a/include/exec/helper-proto.h +++ b/include/exec/helper-proto.h @@ -35,11 +35,15 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \ dh_ctype(t7)); +#define IN_HELPER_PROTO + #include "helper.h" #include "trace/generated-helpers.h" #include "tcg-runtime.h" #include "plugin-helpers.h" +#undef IN_HELPER_PROTO + #undef DEF_HELPER_FLAGS_0 #undef DEF_HELPER_FLAGS_1 #undef DEF_HELPER_FLAGS_2 diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h index 5abf17fecc..5b3bdacc39 100644 --- a/include/tcg/tcg-op.h +++ b/include/tcg/tcg-op.h @@ -1085,6 +1085,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #define tcg_gen_bswap16_tl tcg_gen_bswap16_i64 #define tcg_gen_bswap32_tl tcg_gen_bswap32_i64 #define tcg_gen_bswap64_tl tcg_gen_bswap64_i64 +#define tcg_gen_bswap_tl tcg_gen_bswap64_i64 #define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64 #define tcg_gen_extr_i64_tl tcg_gen_extr32_i64 #define tcg_gen_andc_tl tcg_gen_andc_i64 @@ -1197,6 +1198,7 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t); #define tcg_gen_ext32s_tl tcg_gen_mov_i32 #define tcg_gen_bswap16_tl tcg_gen_bswap16_i32 #define tcg_gen_bswap32_tl tcg_gen_bswap32_i32 +#define tcg_gen_bswap_tl tcg_gen_bswap32_i32 #define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64 #define tcg_gen_extr_i64_tl tcg_gen_extr_i64_i32 #define tcg_gen_andc_tl tcg_gen_andc_i32 diff --git a/meson.build b/meson.build index 372576f82c..4a92213231 100644 --- a/meson.build +++ b/meson.build @@ -1901,7 +1901,6 @@ foreach target : target_dirs custom_target(exe['name'] + stp['ext'], input: trace_events_all, output: exe['name'] + stp['ext'], - capture: true, install: stp['install'], install_dir: get_option('datadir') / 'systemtap/tapset', command: [ @@ -1910,7 +1909,7 @@ foreach target : target_dirs '--target-name=' + target_name, '--target-type=' + target_type, '--probe-prefix=qemu.' + target_type + '.' + target_name, - '@INPUT@', + '@INPUT@', '@OUTPUT@' ]) endforeach endif diff --git a/scripts/tracetool.py b/scripts/tracetool.py index 31146242b7..ab7653a5ce 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -16,7 +16,7 @@ __email__ = "stefanha@redhat.com" import sys import getopt -from tracetool import error_write, out +from tracetool import error_write, out, out_open import tracetool.backend import tracetool.format @@ -32,7 +32,7 @@ def error_opt(msg = None): format_descr = "\n".join([ " %-15s %s" % (n, d) for n,d in tracetool.format.get_list() ]) error_write("""\ -Usage: %(script)s --format=<format> --backends=<backends> [<options>] +Usage: %(script)s --format=<format> --backends=<backends> [<options>] <trace-events> ... <output> Backends: %(backends)s @@ -135,13 +135,15 @@ def main(args): if probe_prefix is None: probe_prefix = ".".join(["qemu", target_type, target_name]) - if len(args) < 1: - error_opt("missing trace-events filepath") + if len(args) < 2: + error_opt("missing trace-events and output filepaths") events = [] - for arg in args: + for arg in args[:-1]: with open(arg, "r") as fh: events.extend(tracetool.read_events(fh, arg)) + out_open(args[-1]) + try: tracetool.generate(events, arg_group, arg_format, arg_backends, binary=binary, probe_prefix=probe_prefix) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 3ee54be223..96b1cd69a5 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -31,14 +31,36 @@ def error(*lines): sys.exit(1) +out_lineno = 1 +out_filename = '<none>' +out_fobj = sys.stdout + +def out_open(filename): + global out_filename, out_fobj + out_filename = filename + out_fobj = open(filename, 'wt') + def out(*lines, **kwargs): """Write a set of output lines. You can use kwargs as a shorthand for mapping variables when formatting all the strings in lines. + + The 'out_lineno' kwarg is automatically added to reflect the current output + file line number. The 'out_next_lineno' kwarg is also automatically added + with the next output line number. The 'out_filename' kwarg is automatically + added with the output filename. """ - lines = [ l % kwargs for l in lines ] - sys.stdout.writelines("\n".join(lines) + "\n") + global out_lineno + output = [] + for l in lines: + kwargs['out_lineno'] = out_lineno + kwargs['out_next_lineno'] = out_lineno + 1 + kwargs['out_filename'] = out_filename + output.append(l % kwargs) + out_lineno += 1 + + out_fobj.writelines("\n".join(output) + "\n") # We only want to allow standard C types or fixed sized # integer types. We don't want QEMU specific types @@ -196,6 +218,10 @@ class Event(object): Properties of the event. args : Arguments The event arguments. + lineno : int + The line number in the input file. + filename : str + The path to the input file. """ @@ -208,7 +234,7 @@ class Event(object): _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"]) - def __init__(self, name, props, fmt, args, orig=None, + def __init__(self, name, props, fmt, args, lineno, filename, orig=None, event_trans=None, event_exec=None): """ Parameters @@ -221,6 +247,10 @@ class Event(object): Event printing format string(s). args : Arguments Event arguments. + lineno : int + The line number in the input file. + filename : str + The path to the input file. orig : Event or None Original Event before transformation/generation. event_trans : Event or None @@ -233,6 +263,8 @@ class Event(object): self.properties = props self.fmt = fmt self.args = args + self.lineno = int(lineno) + self.filename = str(filename) self.event_trans = event_trans self.event_exec = event_exec @@ -254,16 +286,21 @@ class Event(object): def copy(self): """Create a new copy.""" return Event(self.name, list(self.properties), self.fmt, - self.args.copy(), self, self.event_trans, self.event_exec) + self.args.copy(), self.lineno, self.filename, + self, self.event_trans, self.event_exec) @staticmethod - def build(line_str): + def build(line_str, lineno, filename): """Build an Event instance from a string. Parameters ---------- line_str : str Line describing the event. + lineno : int + Line number in input file. + filename : str + Path to input file. """ m = Event._CRE.match(line_str) assert m is not None @@ -293,7 +330,7 @@ class Event(object): if "tcg" in props and isinstance(fmt, str): raise ValueError("Events with 'tcg' property must have two format strings") - event = Event(name, props, fmt, args) + event = Event(name, props, fmt, args, lineno, filename) # add implicit arguments when using the 'vcpu' property import tracetool.vcpu @@ -338,6 +375,8 @@ class Event(object): list(self.properties), self.fmt, self.args.transform(*trans), + self.lineno, + self.filename, self) @@ -364,7 +403,7 @@ def read_events(fobj, fname): continue try: - event = Event.build(line) + event = Event.build(line, lineno, fname) except ValueError as e: arg0 = 'Error at %s:%d: %s' % (fname, lineno, e.args[0]) e.args = (arg0,) + e.args[1:] diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py index e9844dd335..5fa30ccc08 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -33,8 +33,10 @@ def generate_h(event, group): ' int unused __attribute__ ((unused));', ' int trlen;', ' if (trace_event_get_state(%(event_id)s)) {', + '#line %(event_lineno)d "%(event_filename)s"', ' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,', ' "%(name)s " %(fmt)s "\\n" %(argnames)s);', + '#line %(out_next_lineno)d "%(out_filename)s"', ' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);', ' unused = write(trace_marker_fd, ftrace_buf, trlen);', ' }', @@ -42,6 +44,8 @@ def generate_h(event, group): name=event.name, args=event.args, event_id="TRACE_" + event.name.upper(), + event_lineno=event.lineno, + event_filename=event.filename, fmt=event.fmt.rstrip("\n"), argnames=argnames) diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index 877222bbe9..bc43dbb4f4 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -37,12 +37,16 @@ def generate_h(event, group): out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {', ' struct timeval _now;', ' gettimeofday(&_now, NULL);', + '#line %(event_lineno)d "%(event_filename)s"', ' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",', ' qemu_get_thread_id(),', ' (size_t)_now.tv_sec, (size_t)_now.tv_usec', ' %(argnames)s);', + '#line %(out_next_lineno)d "%(out_filename)s"', ' }', cond=cond, + event_lineno=event.lineno, + event_filename=event.filename, name=event.name, fmt=event.fmt.rstrip("\n"), argnames=argnames) diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py index 1373a90192..5a3a00fe31 100644 --- a/scripts/tracetool/backend/syslog.py +++ b/scripts/tracetool/backend/syslog.py @@ -35,9 +35,13 @@ def generate_h(event, group): cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper()) out(' if (%(cond)s) {', + '#line %(event_lineno)d "%(event_filename)s"', ' syslog(LOG_INFO, "%(name)s " %(fmt)s %(argnames)s);', + '#line %(out_next_lineno)d "%(out_filename)s"', ' }', cond=cond, + event_lineno=event.lineno, + event_filename=event.filename, name=event.name, fmt=event.fmt.rstrip("\n"), argnames=argnames) diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index d536f3ccc1..4089e29cd9 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -1462,14 +1462,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_shl_i32: if (c2) { - tcg_out_opc_imm(s, OPC_SLLIW, a0, a1, a2); + tcg_out_opc_imm(s, OPC_SLLIW, a0, a1, a2 & 0x1f); } else { tcg_out_opc_reg(s, OPC_SLLW, a0, a1, a2); } break; case INDEX_op_shl_i64: if (c2) { - tcg_out_opc_imm(s, OPC_SLLI, a0, a1, a2); + tcg_out_opc_imm(s, OPC_SLLI, a0, a1, a2 & 0x3f); } else { tcg_out_opc_reg(s, OPC_SLL, a0, a1, a2); } @@ -1477,14 +1477,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_shr_i32: if (c2) { - tcg_out_opc_imm(s, OPC_SRLIW, a0, a1, a2); + tcg_out_opc_imm(s, OPC_SRLIW, a0, a1, a2 & 0x1f); } else { tcg_out_opc_reg(s, OPC_SRLW, a0, a1, a2); } break; case INDEX_op_shr_i64: if (c2) { - tcg_out_opc_imm(s, OPC_SRLI, a0, a1, a2); + tcg_out_opc_imm(s, OPC_SRLI, a0, a1, a2 & 0x3f); } else { tcg_out_opc_reg(s, OPC_SRL, a0, a1, a2); } @@ -1492,14 +1492,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_sar_i32: if (c2) { - tcg_out_opc_imm(s, OPC_SRAIW, a0, a1, a2); + tcg_out_opc_imm(s, OPC_SRAIW, a0, a1, a2 & 0x1f); } else { tcg_out_opc_reg(s, OPC_SRAW, a0, a1, a2); } break; case INDEX_op_sar_i64: if (c2) { - tcg_out_opc_imm(s, OPC_SRAI, a0, a1, a2); + tcg_out_opc_imm(s, OPC_SRAI, a0, a1, a2 & 0x3f); } else { tcg_out_opc_reg(s, OPC_SRA, a0, a1, a2); } diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c index ddbe06b71a..1a41dfa908 100644 --- a/tcg/tcg-op-gvec.c +++ b/tcg/tcg-op-gvec.c @@ -547,6 +547,9 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz, in_c = dup_const(vece, in_c); if (in_c == 0) { oprsz = maxsz; + vece = MO_8; + } else if (in_c == dup_const(MO_8, in_c)) { + vece = MO_8; } } @@ -628,6 +631,35 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz, /* Otherwise implement out of line. */ t_ptr = tcg_temp_new_ptr(); tcg_gen_addi_ptr(t_ptr, cpu_env, dofs); + + /* + * This may be expand_clr for the tail of an operation, e.g. + * oprsz == 8 && maxsz == 64. The size of the clear is misaligned + * wrt simd_desc and will assert. Simply pass all replicated byte + * stores through to memset. + */ + if (oprsz == maxsz && vece == MO_8) { + TCGv_ptr t_size = tcg_const_ptr(oprsz); + TCGv_i32 t_val; + + if (in_32) { + t_val = in_32; + } else if (in_64) { + t_val = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(t_val, in_64); + } else { + t_val = tcg_const_i32(in_c); + } + gen_helper_memset(t_ptr, t_ptr, t_val, t_size); + + if (!in_32) { + tcg_temp_free_i32(t_val); + } + tcg_temp_free_ptr(t_size); + tcg_temp_free_ptr(t_ptr); + return; + } + t_desc = tcg_const_i32(simd_desc(oprsz, maxsz, 0)); if (vece == MO_64) { diff --git a/trace/control.c b/trace/control.c index b82fb87316..cd04dd4e0c 100644 --- a/trace/control.c +++ b/trace/control.c @@ -125,18 +125,18 @@ TraceEvent *trace_event_iter_next(TraceEventIter *iter) return NULL; } -void trace_list_events(void) +void trace_list_events(FILE *f) { TraceEventIter iter; TraceEvent *ev; trace_event_iter_init(&iter, NULL); while ((ev = trace_event_iter_next(&iter)) != NULL) { - fprintf(stderr, "%s\n", trace_event_get_name(ev)); + fprintf(f, "%s\n", trace_event_get_name(ev)); } #ifdef CONFIG_TRACE_DTRACE - fprintf(stderr, "This list of names of trace points may be incomplete " - "when using the DTrace/SystemTap backends.\n" - "Run 'qemu-trace-stap list %s' to print the full list.\n", + fprintf(f, "This list of names of trace points may be incomplete " + "when using the DTrace/SystemTap backends.\n" + "Run 'qemu-trace-stap list %s' to print the full list.\n", error_get_progname()); #endif } @@ -176,7 +176,7 @@ static void do_trace_enable_events(const char *line_buf) void trace_enable_events(const char *line_buf) { if (is_help_option(line_buf)) { - trace_list_events(); + trace_list_events(stdout); if (monitor_cur() == NULL) { exit(0); } diff --git a/trace/control.h b/trace/control.h index 05b95ea453..9522a7b318 100644 --- a/trace/control.h +++ b/trace/control.h @@ -201,10 +201,11 @@ void trace_fini_vcpu(CPUState *vcpu); /** * trace_list_events: + * @f: Where to send output. * * List all available events. */ -void trace_list_events(void); +void trace_list_events(FILE *f); /** * trace_enable_events: diff --git a/trace/meson.build b/trace/meson.build index 843ea14495..8569e8a0c4 100644 --- a/trace/meson.build +++ b/trace/meson.build @@ -11,20 +11,17 @@ foreach dir : [ '.' ] + trace_events_subdirs trace_h = custom_target(fmt.format('trace', 'h'), output: fmt.format('trace', 'h'), input: trace_events_file, - command: [ tracetool, group, '--format=h', '@INPUT@' ], - capture: true) + command: [ tracetool, group, '--format=h', '@INPUT@', '@OUTPUT@' ]) genh += trace_h trace_c = custom_target(fmt.format('trace', 'c'), output: fmt.format('trace', 'c'), input: trace_events_file, - command: [ tracetool, group, '--format=c', '@INPUT@' ], - capture: true) + command: [ tracetool, group, '--format=c', '@INPUT@', '@OUTPUT@' ]) if 'CONFIG_TRACE_UST' in config_host trace_ust_h = custom_target(fmt.format('trace-ust', 'h'), output: fmt.format('trace-ust', 'h'), input: trace_events_file, - command: [ tracetool, group, '--format=ust-events-h', '@INPUT@' ], - capture: true) + command: [ tracetool, group, '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ]) trace_ss.add(trace_ust_h, lttng, urcubp) genh += trace_ust_h endif @@ -33,8 +30,7 @@ foreach dir : [ '.' ] + trace_events_subdirs trace_dtrace = custom_target(fmt.format('trace-dtrace', 'dtrace'), output: fmt.format('trace-dtrace', 'dtrace'), input: trace_events_file, - command: [ tracetool, group, '--format=d', '@INPUT@' ], - capture: true) + command: [ tracetool, group, '--format=d', '@INPUT@', '@OUTPUT@' ]) trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'), output: fmt.format('trace-dtrace', 'h'), input: trace_dtrace, @@ -69,8 +65,7 @@ foreach d : [ gen = custom_target(d[0], output: d[0], input: meson.source_root() / 'trace-events', - command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@' ], - capture: true) + command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ]) specific_ss.add(gen) endforeach @@ -78,13 +73,11 @@ if 'CONFIG_TRACE_UST' in config_host trace_ust_all_h = custom_target('trace-ust-all.h', output: 'trace-ust-all.h', input: trace_events_files, - command: [ tracetool, '--group=all', '--format=ust-events-h', '@INPUT@' ], - capture: true) + command: [ tracetool, '--group=all', '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ]) trace_ust_all_c = custom_target('trace-ust-all.c', output: 'trace-ust-all.c', input: trace_events_files, - command: [ tracetool, '--group=all', '--format=ust-events-c', '@INPUT@' ], - capture: true) + command: [ tracetool, '--group=all', '--format=ust-events-c', '@INPUT@', '@OUTPUT@' ]) trace_ss.add(trace_ust_all_h, trace_ust_all_c) genh += trace_ust_all_h endif |