diff --git a/tracetool b/tracetool
index f9098da..6f48215 100755
--- a/tracetool
+++ b/tracetool
@@ -38,13 +38,74 @@ get_api_name()
     echo "$event"
 }
 
+# Convenience function to pair elements of two lists (of comma-separated values) of equal size
+# $1: list
+# $2: list
+# $3: format (defaults to ", $1 $2")
+zip_lists()
+{
+    [ -n "$1" -a -n "$2" ] || return
+
+    local format
+    format=$3
+    [ -n "$format" ] || format=", %s %s"
+
+    local i elem accum
+    i=1
+    accum=""
+    for elem in $1; do
+        if [ "$elem" = "${elem%,}" ]; then
+            accum="$accum $elem"
+        else
+            accum="$accum ${elem%,}"
+            eval __elem_$i=\"$accum\"
+            i=$(($i + 1))
+            accum=""
+        fi
+    done
+    eval __elem_$i=\"$accum\"
+
+    local tmp res
+    accum=""
+    res=""
+    i=1
+    for elem in $2; do
+        if [ "$elem" = "${elem%,}" ]; then
+            accum="$accum $elem"
+        else
+            accum="$accum ${elem%,}"
+            eval tmp=\$__elem_$i
+            tmp=$(printf "$format" "$tmp" "$accum")
+            res="$res$tmp"
+            i=$(($i + 1))
+            accum=""
+        fi
+    done
+    eval tmp=\$__elem_$i
+    tmp=$(printf "$format" "$tmp" "$elem")
+    res="$res$tmp"
+
+    echo $res
+}
+
 # Get the argument list of a trace event, including types and names
+# If given, the second argument is a function name to map on each element of the
+# comma-separated list
 get_args()
 {
     local args
     args=${1#*\(}
     args=${args%\)*}
-    echo "$args"
+
+    if [ -z "$2" -o "$args" = "void" ]; then
+        echo "$args"
+    else
+        local argtypes argnames res
+        argtypes=$(get_argtypes "$1" $2)
+        argnames=$(get_argnames "$1")
+        res=$(zip_lists "$argtypes" "$argnames")
+        echo "${res#, }"
+    fi
 }
 
 # Get the argument name list of a trace event
@@ -72,6 +133,60 @@ get_argnames()
     fi
 }
 
+# Get the argument type list of a trace event
+# If given, the second argument is a function name to map on each element of the
+# comma-separated list
+get_argtypes()
+{
+    if [ -z "$2" ]; then
+        local res elem accum
+        res=""
+        accum=""
+        for elem in $(get_args "$1"); do
+            if [ "${elem}" = "${elem%,}" ]; then
+                accum="$accum $elem"
+            else
+                [ "$elem" = "${elem#\*}" ] || accum="$accum *"
+                res="$res, $accum"
+                accum=""
+            fi
+        done
+        accum=${accum% *}
+        [ "$elem" = "${elem#\*}" ] || accum="$accum *"
+        res="$res, $accum"
+        echo "${res#, }"
+    else
+        local res elem accum
+        res=""
+        accum=""
+        for elem in $(get_argtypes "$1"); do
+            if [ "${elem}" = "${elem%,}" ]; then
+                accum="$accum $elem"
+            else
+                accum="$accum ${elem%,}"
+
+                # trim spaces
+                accum=${accum## }
+                accum=${accum%% }
+                # transliterate
+                [ -z "$2" ] || accum=$($2 "$accum")
+
+                res="$res, $accum"
+                accum=""
+            fi
+        done
+
+        # trim spaces
+        accum=${accum## }
+        accum=${accum%% }
+        # transliterate
+        [ -z "$2" ] || accum=$($2 "$accum")
+
+        res="$res, $accum"
+        echo "${res#, }"
+    fi
+}
+
 # Get the number of arguments to a trace event
 get_argc()
 {
@@ -107,6 +222,18 @@ get_fmt()
     echo "$fmt"
 }
 
+# Transliterate an argument in trace-events (raw) into its native counterpart
+# (e.g., TCGv_i32 -> uint32_t)
+native_type()
+{
+    case "$1" in
+        "TCGv_i32") echo "uint32_t" ;;
+        "TCGv_i64") echo "uint64_t" ;;
+        "TCGv_ptr") echo "void *"   ;;
+        *)          echo "$1"       ;;
+    esac
+}
+
 ################################################################################
 ### Backend code
 
@@ -120,7 +247,7 @@ line_h_nop()
 {
     local func args
     func=$(get_func_name "$1")
-    args=$(get_args "$1")
+    args=$(get_args "$1" native_type)
 
     # Define an empty function for the trace event
     cat <<EOF
@@ -173,7 +300,7 @@ line_h_simple()
     # XXX: why 'simple' backend does not expand into 'nop' when disabled?
     local func args argc trace_args
     func=$(get_func_name "$1")
-    args=$(get_args "$1")
+    args=$(get_args "$1" native_type)
     argc=$(get_argc "$1")
     
     trace_args="$simple_event_num"
@@ -267,7 +394,7 @@ line_h_ust()
     local name func args argnames
     name=$(get_event_name "$1")
     func=$(get_func_name "$1")
-    args=$(get_args "$1")
+    args=$(get_args "$1" native_type)
     argnames=$(get_argnames "$1")
 
     cat <<EOF
@@ -302,7 +429,7 @@ line_c_ust()
 
     local name args argnames fmt
     name=$(get_event_name "$1")
-    args=$(get_args "$1")
+    args=$(get_args "$1" native_type)
     argnames=$(get_argnames "$1")
     fmt=$(get_fmt "$1")
 
