trace.c revision 8b23a6c7e1aee255004dd19098d4c2462b61b849
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2006-2007 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <limits.h>
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <inttypes.h>
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/stat.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/types.h>
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/time.h>
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <time.h>
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h"
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "exec-all.h"
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "trace.h"
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "varint.h"
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceBB trace_bb;
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceInsn trace_insn;
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceStatic trace_static;
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceAddr trace_load;
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceAddr trace_store;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceExc trace_exc;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTracePid trace_pid;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTraceMethod trace_method;
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic TraceHeader header;
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *trace_filename;
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tracing;
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint trace_cache_miss;
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint trace_all_addr;
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The simulation time in cpu clock cycles
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t sim_time = 1;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The current process id
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint current_pid;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The start and end (wall-clock) time in microseconds
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t start_time, end_time;
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t elapsed_usecs;
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// For debugging output
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFILE *ftrace_debug;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by an InsnRec after compression.
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This is very conservative but needed to ensure no buffer overflows.
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxInsnCompressed 14
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by an BBRec after compression.
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This is very conservative but needed to ensure no buffer overflows.
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxBBCompressed 32
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by an AddrRec after compression.
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This is very conservative but needed to ensure no buffer overflows.
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxAddrCompressed 14
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a MethodRec after compression.
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This is very conservative but needed to ensure no buffer overflows.
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxMethodCompressed 18
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by an exception record after
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// compression.
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxExcCompressed 38
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// kPidSwitch, or kPidExit after compression.
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxPidCompressed 15
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidFork,
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// or kPidClone after compression.
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxPid2Compressed 20
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidExecArgs
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// after compression, not counting the bytes for the args.
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxExecArgsCompressed 15
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidName
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// after compression, not counting the bytes for the name.
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxNameCompressed 20
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidMmap
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// after compression, not counting the bytes for the pathname.
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxMmapCompressed 33
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidMunmap,
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// after compression.
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxMunmapCompressed 28
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidSymbol
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// after compression, not counting the bytes for the symbol name.
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxSymbolCompressed 24
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// The maximum number of bytes consumed by a pid record for kPidKthreadName
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// after compression, not counting the bytes for the name.
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define kMaxKthreadNameCompressed 25
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_cleanup();
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Return current time in microseconds as a 64-bit integer.
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64 Now() {
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct timeval        tv;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gettimeofday(&tv, NULL);
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64 val = tv.tv_sec;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    val = val * 1000000ull + tv.tv_usec;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void create_trace_dir(const char *dirname)
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int err;
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    err = path_mkdir(dirname, 0755);
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (err != 0 && errno != EEXIST) {
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("err: %d\n", err);
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(dirname);
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char *create_trace_path(const char *filename, const char *ext)
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname;
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *base_start, *base_end;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ii, len, base_len, dir_len, path_len, qtrace_len;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Handle error cases
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (filename == NULL || *filename == 0 || strcmp(filename, "/") == 0)
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Ignore a trailing slash, if any
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = strlen(filename);
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (filename[len - 1] == '/')
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len -= 1;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Find the basename.  We don't use basename(3) because there are
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // different behaviors for GNU and Posix in the case where the
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // last character is a slash.
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    base_start = base_end = &filename[len];
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (ii = 0; ii < len; ++ii) {
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        base_start -= 1;
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*base_start == '/') {
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            base_start += 1;
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    base_len = base_end - base_start;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dir_len = len - base_len;
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qtrace_len = strlen("/qtrace");
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create space for the pathname: "/dir/basename/qtrace.ext"
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // The "ext" string already contains the dot, so just add a byte
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // for the terminating zero.
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    path_len = dir_len + base_len + qtrace_len + strlen(ext) + 1;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fname = malloc(path_len);
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (dir_len > 0)
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strncpy(fname, filename, dir_len);
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fname[dir_len] = 0;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncat(fname, base_start, base_len);
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strcat(fname, "/qtrace");
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strcat(fname, ext);
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fname;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid convert_secs_to_date_time(time_t secs, uint32_t *pdate, uint32_t *ptime)
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct tm *tm = localtime(&secs);
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t year = tm->tm_year + 1900;
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t thousands = year / 1000;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    year -= thousands * 1000;
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t hundreds = year / 100;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    year -= hundreds * 100;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t tens = year / 10;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    year -= tens * 10;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t ones = year;
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    year = (thousands << 12) | (hundreds << 8) | (tens << 4) | ones;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mon = tm->tm_mon + 1;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tens = mon / 10;
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ones = (mon - tens * 10);
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mon = (tens << 4) | ones;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t day = tm->tm_mday;
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tens = day / 10;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ones = (day - tens * 10);
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    day = (tens << 4) | ones;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pdate = (year << 16) | (mon << 8) | day;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t hour = tm->tm_hour;
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tens = hour / 10;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ones = (hour - tens * 10);
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hour = (tens << 4) | ones;
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t min = tm->tm_min;
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tens = min / 10;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ones = (min - tens * 10);
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    min = (tens << 4) | ones;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t sec = tm->tm_sec;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tens = sec / 10;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ones = (sec - tens * 10);
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sec = (tens << 4) | ones;
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *ptime = (hour << 16) | (min << 8) | sec;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid write_trace_header(TraceHeader *header)
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TraceHeader swappedHeader;
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy(&swappedHeader, header, sizeof(TraceHeader));
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.version);
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.start_sec);
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.start_usec);
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.pdate);
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.ptime);
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.num_used_pids);
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert32(swappedHeader.first_unused_pid);
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert64(swappedHeader.num_static_bb);
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert64(swappedHeader.num_static_insn);
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert64(swappedHeader.num_dynamic_bb);
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert64(swappedHeader.num_dynamic_insn);
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert64(swappedHeader.elapsed_usecs);
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&swappedHeader, sizeof(TraceHeader), 1, trace_static.fstream);
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_bb(const char *filename)
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".bb");
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.filename = fname;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fstream = fopen(fname, "wb");
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fstream == NULL) {
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.fstream = fstream;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.next = &trace_bb.buffer[0];
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.flush_time = 0;
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.compressed_ptr = trace_bb.compressed;
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.high_water_ptr = &trace_bb.compressed[kCompressedSize] - kMaxBBCompressed;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.prev_bb_num = 0;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.prev_bb_time = 0;
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.num_insns = 0;
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.recnum = 0;
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_insn(const char *filename)
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create the instruction time trace file
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".insn");
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.filename = fname;
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fstream = fopen(fname, "wb");
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fstream == NULL) {
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.fstream = fstream;
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.current = &trace_insn.dummy;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.dummy.time_diff = 0;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.dummy.repeat = 0;
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.prev_time = 0;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.compressed_ptr = trace_insn.compressed;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.high_water_ptr = &trace_insn.compressed[kCompressedSize] - kMaxInsnCompressed;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_static(const char *filename)
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create the static basic block trace file
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".static");
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.filename = fname;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fstream = fopen(fname, "wb");
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fstream == NULL) {
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.fstream = fstream;
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.next_insn = 0;
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.bb_num = 1;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.bb_addr = 0;
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Write an empty header to reserve space for it in the file.
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // The header will be filled in later when post-processing the
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // trace file.
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(&header, 0, sizeof(TraceHeader));
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Write out the version number so that tools can detect if the trace
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // file format is the same as what they expect.
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    header.version = TRACE_VERSION;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Record the start time in the header now.
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct timeval tv;
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct timezone tz;
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gettimeofday(&tv, &tz);
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    header.start_sec = tv.tv_sec;
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    header.start_usec = tv.tv_usec;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    convert_secs_to_date_time(header.start_sec, &header.pdate, &header.ptime);
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    write_trace_header(&header);
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Write out the record for the unused basic block number 0.
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t zero = 0;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&zero, sizeof(uint64_t), 1, trace_static.fstream);	// bb_num
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&zero, sizeof(uint32_t), 1, trace_static.fstream);	// bb_addr
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&zero, sizeof(uint32_t), 1, trace_static.fstream);	// num_insns
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_addr(const char *filename)
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // The "qtrace.load" and "qtrace.store" files are optional
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_load.fstream = NULL;
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_store.fstream = NULL;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_all_addr || trace_cache_miss) {
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Create the "qtrace.load" file
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *fname = create_trace_path(filename, ".load");
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.filename = fname;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        FILE *fstream = fopen(fname, "wb");
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (fstream == NULL) {
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            perror(fname);
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.fstream = fstream;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.next = &trace_load.buffer[0];
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.compressed_ptr = trace_load.compressed;
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.high_water_ptr = &trace_load.compressed[kCompressedSize] - kMaxAddrCompressed;
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.prev_addr = 0;
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_load.prev_time = 0;
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Create the "qtrace.store" file
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fname = create_trace_path(filename, ".store");
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.filename = fname;
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fstream = fopen(fname, "wb");
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (fstream == NULL) {
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            perror(fname);
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.fstream = fstream;
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.next = &trace_store.buffer[0];
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.compressed_ptr = trace_store.compressed;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.high_water_ptr = &trace_store.compressed[kCompressedSize] - kMaxAddrCompressed;
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.prev_addr = 0;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_store.prev_time = 0;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_exc(const char *filename)
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create the exception trace file
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".exc");
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.filename = fname;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fstream = fopen(fname, "wb");
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fstream == NULL) {
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.fstream = fstream;
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.compressed_ptr = trace_exc.compressed;
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.high_water_ptr = &trace_exc.compressed[kCompressedSize] - kMaxExcCompressed;
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.prev_time = 0;
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.prev_bb_recnum = 0;
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_pid(const char *filename)
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create the pid trace file
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".pid");
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.filename = fname;
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fstream = fopen(fname, "wb");
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fstream == NULL) {
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.fstream = fstream;
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = trace_pid.compressed;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = 0;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid create_trace_method(const char *filename)
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create the method trace file
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".method");
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.filename = fname;
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fstream = fopen(fname, "wb");
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fstream == NULL) {
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.fstream = fstream;
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.compressed_ptr = trace_method.compressed;
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.prev_time = 0;
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.prev_addr = 0;
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.prev_pid = 0;
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_init(const char *filename)
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Create the trace files
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_dir(filename);
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_bb(filename);
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_insn(filename);
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_static(filename);
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_addr(filename);
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_exc(filename);
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_pid(filename);
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_trace_method(filename);
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *fname = create_trace_path(filename, ".debug");
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ftrace_debug = fopen(fname, "wb");
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug == NULL) {
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror(fname);
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ftrace_debug = NULL;
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    atexit(trace_cleanup);
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // If tracing is on, then start timing the simulator
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tracing)
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        start_time = Now();
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* the following array is used to deal with def-use register interlocks, which we
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * can compute statically (ignoring conditions), very fortunately.
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the idea is that interlock_base contains the number of cycles "executed" from
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the start of a basic block. It is set to 0 in trace_bb_start, and incremented
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in each call to get_insn_ticks_arm.
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * interlocks[N] correspond to the value of interlock_base after which a register N
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * can be used by another operation, it is set each time an instruction writes to
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the register in get_insn_ticks()
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int   interlocks[16];
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int   interlock_base;
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_interlock_def(int  reg, int  delay)
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (reg >= 0)
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        interlocks[reg] = interlock_base + delay;
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_interlock_use(int  reg)
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  delay = 0;
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (reg >= 0)
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        delay = interlocks[reg] - interlock_base;
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (delay < 0)
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            delay = 0;
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return delay;
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_bb_start(uint32_t bb_addr)
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.bb_addr = bb_addr;
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.is_thumb = 0;
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    interlock_base = 0;
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < 16; nn++)
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        interlocks[nn] = 0;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_add_insn(uint32_t insn, int is_thumb)
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.insns[trace_static.next_insn++] = insn;
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // This relies on the fact that a basic block does not contain a mix
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // of ARM and Thumb instructions.  If that is not true, then many
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // software tools that read the trace will have to change.
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.is_thumb = is_thumb;
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_bb_end()
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int		ii, num_insns;
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t	insn;
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t bb_num = hostToLE64(trace_static.bb_num);
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // If these are Thumb instructions, then encode that fact by setting
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // the low bit of the basic-block address to 1.
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t bb_addr = trace_static.bb_addr | trace_static.is_thumb;
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bb_addr = hostToLE32(bb_addr);
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    num_insns = hostToLE32(trace_static.next_insn);
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&bb_num, sizeof(bb_num), 1, trace_static.fstream);
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&bb_addr, sizeof(bb_addr), 1, trace_static.fstream);
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fwrite(&num_insns, sizeof(num_insns), 1, trace_static.fstream);
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (ii = 0; ii < trace_static.next_insn; ++ii) {
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        insn = hostToLE32(trace_static.insns[ii]);
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&insn, sizeof(insn), 1, trace_static.fstream);
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.bb_num += 1;
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_static.next_insn = 0;
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_cleanup()
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tracing) {
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        end_time = Now();
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        elapsed_usecs += end_time - start_time;
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    header.elapsed_usecs = elapsed_usecs;
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    double elapsed_secs = elapsed_usecs / 1000000.0;
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    double cycles_per_sec = 0;
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (elapsed_secs != 0)
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cycles_per_sec = sim_time / elapsed_secs;
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *suffix = "";
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cycles_per_sec >= 1000000) {
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cycles_per_sec /= 1000000.0;
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        suffix = "M";
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (cycles_per_sec > 1000) {
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cycles_per_sec /= 1000.0;
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        suffix = "K";
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("Elapsed seconds: %.2f, simulated cycles/sec: %.1f%s\n",
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           elapsed_secs, cycles_per_sec, suffix);
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_bb.fstream) {
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        BBRec *ptr;
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        BBRec *next = trace_bb.next;
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *comp_ptr = trace_bb.compressed_ptr;
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int64_t prev_bb_num = trace_bb.prev_bb_num;
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t prev_bb_time = trace_bb.prev_bb_time;
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ptr = trace_bb.buffer; ptr != next; ++ptr) {
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (comp_ptr >= trace_bb.high_water_ptr) {
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t size = comp_ptr - trace_bb.compressed;
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fwrite(trace_bb.compressed, sizeof(char), size,
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       trace_bb.fstream);
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = trace_bb.compressed;
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int64_t bb_diff = ptr->bb_num - prev_bb_num;
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_bb_num = ptr->bb_num;
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint64_t time_diff = ptr->start_time - prev_bb_time;
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_bb_time = ptr->start_time;
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(time_diff, comp_ptr);
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ptr->repeat)
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Add an extra record at the end containing the ending simulation
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // time and a basic block number of 0.
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t time_diff = sim_time - prev_bb_time;
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (time_diff > 0) {
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int64_t bb_diff = -prev_bb_num;
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(time_diff, comp_ptr);
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(0, comp_ptr);
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_bb.compressed;
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size)
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fwrite(trace_bb.compressed, sizeof(char), size, trace_bb.fstream);
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Terminate the file with three zeros so that we can detect
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // the end of file quickly.
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t zeros = 0;
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&zeros, 3, 1, trace_bb.fstream);
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_bb.fstream);
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_insn.fstream) {
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        InsnRec *ptr;
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        InsnRec *current = trace_insn.current + 1;
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *comp_ptr = trace_insn.compressed_ptr;
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ptr = trace_insn.buffer; ptr != current; ++ptr) {
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (comp_ptr >= trace_insn.high_water_ptr) {
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t size = comp_ptr - trace_insn.compressed;
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t rval = fwrite(trace_insn.compressed, sizeof(char),
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                       size, trace_insn.fstream);
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (rval != size) {
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(stderr, "fwrite() failed\n");
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    perror(trace_insn.filename);
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    exit(1);
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = trace_insn.compressed;
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_insn.compressed;
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size) {
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint32_t rval = fwrite(trace_insn.compressed, sizeof(char), size,
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   trace_insn.fstream);
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (rval != size) {
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(stderr, "fwrite() failed\n");
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                perror(trace_insn.filename);
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                exit(1);
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_insn.fstream);
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_static.fstream) {
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fseek(trace_static.fstream, 0, SEEK_SET);
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        write_trace_header(&header);
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_static.fstream);
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_load.fstream) {
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        AddrRec *ptr;
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *comp_ptr = trace_load.compressed_ptr;
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        AddrRec *next = trace_load.next;
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t prev_addr = trace_load.prev_addr;
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t prev_time = trace_load.prev_time;
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ptr = trace_load.buffer; ptr != next; ++ptr) {
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (comp_ptr >= trace_load.high_water_ptr) {
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t size = comp_ptr - trace_load.compressed;
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fwrite(trace_load.compressed, sizeof(char), size,
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       trace_load.fstream);
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = trace_load.compressed;
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int addr_diff = ptr->addr - prev_addr;
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint64_t time_diff = ptr->time - prev_time;
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_addr = ptr->addr;
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_time = ptr->time;
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(time_diff, comp_ptr);
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_load.compressed;
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size) {
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fwrite(trace_load.compressed, sizeof(char), size,
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   trace_load.fstream);
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Terminate the file with two zeros so that we can detect
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // the end of file quickly.
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t zeros = 0;
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&zeros, 2, 1, trace_load.fstream);
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_load.fstream);
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_store.fstream) {
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        AddrRec *ptr;
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *comp_ptr = trace_store.compressed_ptr;
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        AddrRec *next = trace_store.next;
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t prev_addr = trace_store.prev_addr;
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t prev_time = trace_store.prev_time;
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ptr = trace_store.buffer; ptr != next; ++ptr) {
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (comp_ptr >= trace_store.high_water_ptr) {
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t size = comp_ptr - trace_store.compressed;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fwrite(trace_store.compressed, sizeof(char), size,
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       trace_store.fstream);
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = trace_store.compressed;
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int addr_diff = ptr->addr - prev_addr;
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint64_t time_diff = ptr->time - prev_time;
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_addr = ptr->addr;
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_time = ptr->time;
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(time_diff, comp_ptr);
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_store.compressed;
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size) {
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fwrite(trace_store.compressed, sizeof(char), size,
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   trace_store.fstream);
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Terminate the file with two zeros so that we can detect
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // the end of file quickly.
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t zeros = 0;
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&zeros, 2, 1, trace_store.fstream);
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_store.fstream);
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_exc.fstream) {
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = trace_exc.compressed_ptr - trace_exc.compressed;
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size) {
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fwrite(trace_exc.compressed, sizeof(char), size,
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   trace_exc.fstream);
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Terminate the file with 7 zeros so that we can detect
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // the end of file quickly.
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t zeros = 0;
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&zeros, 7, 1, trace_exc.fstream);
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_exc.fstream);
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream) {
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = trace_pid.compressed_ptr - trace_pid.compressed;
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size) {
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fwrite(trace_pid.compressed, sizeof(char), size,
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   trace_pid.fstream);
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Terminate the file with 2 zeros so that we can detect
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // the end of file quickly.
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t zeros = 0;
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&zeros, 2, 1, trace_pid.fstream);
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_pid.fstream);
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_method.fstream) {
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = trace_method.compressed_ptr - trace_method.compressed;
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (size) {
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fwrite(trace_method.compressed, sizeof(char), size,
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   trace_method.fstream);
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Terminate the file with 2 zeros so that we can detect
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // the end of file quickly.
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t zeros = 0;
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(&zeros, 2, 1, trace_method.fstream);
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(trace_method.fstream);
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fclose(ftrace_debug);
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Define the number of clock ticks for some instructions.  Add one to these
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// (in some cases) if there is an interlock.  We currently do not check for
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// interlocks.
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_OTHER	1
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMULxy	1
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMLAWy	1
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMLALxy	2
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_MUL	2
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_MLA	2
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_MULS	4	// no interlock penalty
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_MLAS	4	// no interlock penalty
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_UMULL	3
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_UMLAL	3
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMULL	3
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMLAL	3
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_UMULLS	5	// no interlock penalty
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_UMLALS	5	// no interlock penalty
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMULLS	5	// no interlock penalty
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TICKS_SMLALS	5	// no interlock penalty
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Compute the number of cycles that this instruction will take,
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// not including any I-cache or D-cache misses.  This function
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// is called for each instruction in a basic block when that
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// block is being translated.
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint get_insn_ticks_arm(uint32_t insn)
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   result   =  1;   /* by default, use 1 cycle */
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* See Chapter 12 of the ARM920T Reference Manual for details about clock cycles */
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first check for invalid condition codes */
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((insn >> 28) == 0xf)
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((insn >> 25) == 0x7d) {  /* BLX */
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            result = 3;
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto Exit;
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* XXX: if we get there, we're either in an UNDEFINED instruction     */
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /*      or in co-processor related ones. For now, only return 1 cycle */
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto Exit;
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* other cases */
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch ((insn >> 25) & 7)
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((insn & 0x00000090) == 0x00000090)  /* Multiplies, extra load/store, Table 3-2 */
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: TODO: Add support for multiplier operand content penalties in the translator */
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((insn & 0x0fc000f0) == 0x00000090)   /* 3-2: Multiply (accumulate) */
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm = (insn & 15);
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rs = (insn >> 8) & 15;
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rn = (insn >> 12) & 15;
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((insn & 0x00200000) != 0) {  /* MLA */
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result += _interlock_use(Rn);
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    } else {   /* MLU */
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (Rn != 0)      /* UNDEFINED */
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            goto Exit;
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* cycles=2+m, assume m=1, this should be adjusted at interpretation time */
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += 2 + _interlock_use(Rm) + _interlock_use(Rs);
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0f8000f0) == 0x00800090)  /* 3-2: Multiply (accumulate) long */
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm   = (insn & 15);
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rs   = (insn >> 8) & 15;
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  RdLo = (insn >> 12) & 15;
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  RdHi = (insn >> 16) & 15;
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((insn & 0x00200000) != 0) { /* SMLAL & UMLAL */
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result += _interlock_use(RdLo) + _interlock_use(RdHi);
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* else SMLL and UMLL */
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* cucles=3+m, assume m=1, this should be adjusted at interpretation time */
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += 3 + _interlock_use(Rm) + _interlock_use(Rs);
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0fd00ff0) == 0x01000090)  /* 3-2: Swap/swap byte */
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm = (insn & 15);
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 8) & 15;
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result = 2 + _interlock_use(Rm);
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    _interlock_def(Rd, result+1);
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0e400ff0) == 0x00000090)  /* 3-2: load/store halfword, reg offset */
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm = (insn & 15);
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 12) & 15;
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rn = (insn >> 16) & 15;
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rn) + _interlock_use(Rm);
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((insn & 0x00100000) != 0)  /* it's a load, there's a 2-cycle interlock */
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd, result+2);
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0e400ff0) == 0x00400090)  /* 3-2: load/store halfword, imm offset */
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 12) & 15;
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rn = (insn >> 16) & 15;
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rn);
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((insn & 0x00100000) != 0)  /* it's a load, there's a 2-cycle interlock */
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd, result+2);
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0e500fd0) == 0x000000d0) /* 3-2: load/store two words, reg offset */
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* XXX: TODO: Enhanced DSP instructions */
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0e500fd0) == 0x001000d0) /* 3-2: load/store half/byte, reg offset */
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm = (insn & 15);
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 12) & 15;
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rn = (insn >> 16) & 15;
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rn) + _interlock_use(Rm);
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((insn & 0x00100000) != 0)  /* load, 2-cycle interlock */
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd, result+2);
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0e5000d0) == 0x004000d0) /* 3-2: load/store two words, imm offset */
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* XXX: TODO: Enhanced DSP instructions */
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0e5000d0) == 0x005000d0) /* 3-2: load/store half/byte, imm offset */
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 12) & 15;
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rn = (insn >> 16) & 15;
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rn);
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((insn & 0x00100000) != 0)  /* load, 2-cycle interlock */
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd, result+2);
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* UNDEFINED */
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if ((insn & 0x0f900000) == 0x01000000)  /* Misc. instructions, table 3-3 */
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                switch ((insn >> 4) & 15)
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 0:
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if ((insn & 0x0fb0fff0) == 0x0120f000) /* move register to status register */
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        {
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int  Rm = (insn & 15);
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            result += _interlock_use(Rm);
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 1:
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if ( ((insn & 0x0ffffff0) == 0x01200010) ||  /* branch/exchange */
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             ((insn & 0x0fff0ff0) == 0x01600010) )   /* count leading zeroes */
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        {
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int  Rm = (insn & 15);
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            result += _interlock_use(Rm);
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 3:
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if ((insn & 0x0ffffff0) == 0x01200030)   /* link/exchange */
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        {
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int  Rm = (insn & 15);
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            result += _interlock_use(Rm);
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    default:
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* TODO: Enhanced DSP instructions */
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        ;
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else  /* Data processing */
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rm = (insn & 15);
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 16) & 15;
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn) + _interlock_use(Rm);
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((insn & 0x10)) {   /* register-controlled shift => 1 cycle penalty */
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rs = (insn >> 8) & 15;
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += 1 + _interlock_use(Rs);
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((insn & 0x01900000) == 0x01900000)
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* either UNDEFINED or move immediate to CPSR */
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else  /* Data processing immediate */
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 12) & 15;
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:  /* load/store immediate */
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 16) & 15;
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (insn & 0x00100000) {  /* LDR */
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 12) & 15;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (Rd == 15)  /* loading PC */
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result = 5;
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd,result+1);
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((insn & 0x10) == 0)  /* load/store register offset */
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rm = (insn & 15);
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 16) & 15;
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rm) + _interlock_use(Rn);
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (insn & 0x00100000) {  /* LDR */
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 12) & 15;
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (Rd == 15)
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result = 5;
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd,result+1);
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* else UNDEFINED */
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 4:  /* load/store multiple */
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int       Rn   = (insn >> 16) & 15;
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t  mask = (insn & 0xffff);
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int       count;
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (count = 0; mask; count++)
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    mask &= (mask-1);
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (insn & 0x00100000)  /* LDM */
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  nn;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (insn & 0x8000) {  /* loading PC */
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result = count+4;
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    } else {  /* not loading PC */
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result = (count < 2) ? 2 : count;
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* create defs, all registers locked until the end of the load */
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for (nn = 0; nn < 15; nn++)
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if ((insn & (1U << nn)) != 0)
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            _interlock_def(nn,result);
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else  /* STM */
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result = (count < 2) ? 2 : count;
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 5:  /* branch and branch+link */
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 6:  /* coprocessor load/store */
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 16) & 15;
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (insn & 0x00100000)
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rn);
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: other things to do ? */
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default: /* i.e. 7 */
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* XXX: TODO: co-processor related things */
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ;
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit:
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    interlock_base += result;
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* old code - this seems to be completely buggy ?? */
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((insn & 0x0ff0f090) == 0x01600080) {
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return TICKS_SMULxy;
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if ((insn & 0x0ff00090) == 0x01200080) {
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return TICKS_SMLAWy;
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if ((insn & 0x0ff00090) == 0x01400080) {
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return TICKS_SMLALxy;
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if ((insn & 0x0f0000f0) == 0x00000090) {
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // multiply
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint8_t bit23 = (insn >> 23) & 0x1;
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint8_t bit22_U = (insn >> 22) & 0x1;
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint8_t bit21_A = (insn >> 21) & 0x1;
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint8_t bit20_S = (insn >> 20) & 0x1;
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (bit23 == 0) {
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            // 32-bit multiply
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (bit22_U != 0) {
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                // This is an unexpected bit pattern.
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return TICKS_OTHER;
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (bit21_A == 0) {
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (bit20_S)
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return TICKS_MULS;
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return TICKS_MUL;
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (bit20_S)
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return TICKS_MLAS;
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return TICKS_MLA;
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // 64-bit multiply
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (bit22_U == 0) {
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            // Unsigned multiply long
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (bit21_A == 0) {
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (bit20_S)
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return TICKS_UMULLS;
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return TICKS_UMULL;
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (bit20_S)
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return TICKS_UMLALS;
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return TICKS_UMLAL;
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Signed multiply long
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (bit21_A == 0) {
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (bit20_S)
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return TICKS_SMULLS;
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return TICKS_SMULL;
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (bit20_S)
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return TICKS_SMLALS;
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return TICKS_SMLAL;
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return TICKS_OTHER;
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint  get_insn_ticks_thumb(uint32_t  insn)
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  result = 1;
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch ((insn >> 11) & 31)
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:   /* Shift by immediate */
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rm = (insn >> 3) & 7;
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rm);
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:  /* Add/Substract */
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((insn & 0x0400) == 0) {  /* register value */
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm = (insn >> 6) & 7;
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rm);
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 4:  /* move immediate */
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 5:
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 6:
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 7:  /* add/substract/compare immediate */
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 7;
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rd);
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 8:
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((insn & 0x0400) == 0)  /* data processing register */
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* the registers can also be Rs and Rn in some cases */
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* but they're always read anyway and located at the */
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* same place, so we don't check the opcode          */
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rm = (insn >> 3) & 7;
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  Rd = (insn >> 3) & 7;
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(Rm) + _interlock_use(Rd);
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else switch ((insn >> 8) & 3)
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 0:
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 1:
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 2:  /* special data processing */
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        {
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int  Rn = (insn & 7) | ((insn >> 4) & 0x8);
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int  Rm = ((insn >> 3) & 15);
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            result += _interlock_use(Rn) + _interlock_use(Rm);
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 3:
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if ((insn & 0xff07) == 0x4700)  /* branch/exchange */
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        {
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int  Rm = (insn >> 3) & 15;
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            result = 3 + _interlock_use(Rm);
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* else UNDEFINED */
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 9:  /* load from literal pool */
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 7;
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                _interlock_def(Rd,result+1);
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 10:
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 11:  /* load/store register offset */
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn & 7);
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rm = (insn >> 6) & 7;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn) + _interlock_use(Rm);
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                switch ((insn >> 9) & 7)
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 0: /* STR  */
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 1: /* STRH */
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 2: /* STRB */
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result += _interlock_use(Rd);
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 3: /* LDRSB */
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 5: /* LDRH */
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 6: /* LDRB */
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 7: /* LDRSH */
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd,result+2);
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 4: /* LDR */
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(Rd,result+1);
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 12:  /* store word immediate offset */
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 14:  /* store byte immediate offset */
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn & 7);
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rd) + _interlock_use(Rn);
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 13:  /* load word immediate offset */
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn & 7);
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                _interlock_def(Rd,result+1);
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 15:  /* load byte immediate offset */
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn & 7);
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                _interlock_def(Rd,result+2);
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 16:  /* store halfword immediate offset */
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn & 7);
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn) + _interlock_use(Rd);
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 17:  /* load halfword immediate offset */
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn & 7);
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rn = (insn >> 3) & 7;
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rn);
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                _interlock_def(Rd,result+2);
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 18:  /* store to stack */
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 3;
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rd);
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 19:  /* load from stack */
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 3;
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                _interlock_def(Rd,result+1);
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 20:  /* add to PC */
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 21:  /* add to SP */
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 3;
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rd);
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 22:
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 23:  /* misc. instructions, table 6-2 */
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((insn & 0xff00) == 0xb000)  /* adjust stack pointer */
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result += _interlock_use(14);
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else if ((insn & 0x0600) == 0x0400)  /* push pop register list */
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    uint32_t  mask = insn & 0x01ff;
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int       count, nn;
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for (count = 0; mask; count++)
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        mask &= (mask-1);
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result = (count < 2) ? 2 : count;
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (insn & 0x0800)  /* pop register list */
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    {
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        for (nn = 0; nn < 9; nn++)
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (insn & (1 << nn))
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                _interlock_def(nn, result);
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else  /* push register list */
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    {
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        for (nn = 0; nn < 9; nn++)
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (insn & (1 << nn))
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                result += _interlock_use(nn);
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* else  software breakpoint */
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 24:  /* store multiple */
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 7;
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t  mask = insn & 255;
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int       count, nn;
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (count = 0; mask; count++)
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    mask &= (mask-1);
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result = (count < 2) ? 2 : count;
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rd);
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (nn = 0; nn < 8; nn++)
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (insn & (1 << nn))
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        result += _interlock_use(nn);
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 25:  /* load multiple */
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  Rd = (insn >> 8) & 7;
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t  mask = insn & 255;
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int       count, nn;
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (count = 0; mask; count++)
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    mask &= (mask-1);
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result  = (count < 2) ? 2 : count;
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result += _interlock_use(Rd);
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (nn = 0; nn < 8; nn++)
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (insn & (1 << nn))
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        _interlock_def(nn, result);
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 26:
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 27:  /* conditional branch / undefined / software interrupt */
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch ((insn >> 8) & 15)
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 14: /* UNDEFINED */
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 15: /* SWI */
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                default:  /* conditional branch */
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    result = 3;
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 28:  /* unconditional branch */
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            result = 3;
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 29:  /* BLX suffix or undefined */
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((insn & 1) == 0)
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result = 3;
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 30:  /* BLX/BLX prefix */
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 31:  /* BL suffix */
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            result = 3;
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    interlock_base += result;
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* old code */
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((insn & 0xfc00) == 0x4340) /* MUL */
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return TICKS_SMULxy;
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return TICKS_OTHER;
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Adds an exception trace record.
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_exception(uint32 target_pc)
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_exc.fstream == NULL)
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Sometimes we get an unexpected exception as the first record.  If the
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // basic block number is zero, then we know it is bogus.
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_bb.current_bb_num == 0)
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t current_pc = trace_bb.current_bb_addr + 4 * (trace_bb.num_insns - 1);
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug) {
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%llu exc pc: 0x%x bb_addr: 0x%x num_insns: %d current_pc: 0x%x bb_num %llu bb_start_time %llu\n",
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sim_time, target_pc, trace_bb.current_bb_addr,
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                trace_bb.num_insns, current_pc, trace_bb.current_bb_num,
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                trace_bb.current_bb_start_time);
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_exc.compressed_ptr;
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (comp_ptr >= trace_exc.high_water_ptr) {
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_exc.compressed;
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_exc.compressed, sizeof(char), size, trace_exc.fstream);
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_exc.compressed;
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_exc.prev_time;
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.prev_time = sim_time;
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t bb_recnum_diff = trace_bb.recnum - trace_exc.prev_bb_recnum;
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.prev_bb_recnum = trace_bb.recnum;
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(current_pc, comp_ptr);
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(bb_recnum_diff, comp_ptr);
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(target_pc, comp_ptr);
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(trace_bb.current_bb_num, comp_ptr);
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(trace_bb.current_bb_start_time, comp_ptr);
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(trace_bb.num_insns, comp_ptr);
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_exc.compressed_ptr = comp_ptr;
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_pid_1arg(int pid, int rec_type)
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + kMaxPidCompressed;
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(pid, comp_ptr);
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr;
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_pid_2arg(int tgid, int pid, int rec_type)
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + kMaxPid2Compressed;
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(tgid, comp_ptr);
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(pid, comp_ptr);
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr;
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_switch(int pid)
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug && trace_pid.fstream)
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld switch %d\n", sim_time, pid);
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid_1arg(pid, kPidSwitch);
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    current_pid = pid;
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_fork(int tgid, int pid)
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug && trace_pid.fstream)
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld fork %d\n", sim_time, pid);
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid_2arg(tgid, pid, kPidFork);
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_clone(int tgid, int pid)
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug && trace_pid.fstream)
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld clone %d\n", sim_time, pid);
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid_2arg(tgid, pid, kPidClone);
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_exit(int exitcode)
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug && trace_pid.fstream)
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld exit %d\n", sim_time, exitcode);
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid_1arg(exitcode, kPidExit);
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_name(char *name)
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug && trace_pid.fstream) {
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld pid %d name %s\n",
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sim_time, current_pid, name);
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int len = strlen(name);
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + len + kMaxNameCompressed;
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidName;
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(current_pid, comp_ptr);
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(len, comp_ptr);
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy(comp_ptr, name, len);
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr += len;
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr;
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_execve(const char *argv, int len)
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ii;
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Count the number of args
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int alen = 0;
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int sum_len = 0;
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int argc = 0;
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *ptr = argv;
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (sum_len < len) {
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        argc += 1;
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alen = strlen(ptr);
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ptr += alen + 1;
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sum_len += alen + 1;
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug) {
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld argc: %d\n", sim_time, argc);
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alen = 0;
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ptr = argv;
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ii = 0; ii < argc; ++ii) {
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(ftrace_debug, "  argv[%d]: %s\n", ii, ptr);
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            alen = strlen(ptr);
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ptr += alen + 1;
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + len + 5 * argc + kMaxExecArgsCompressed;
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidExec;
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(argc, comp_ptr);
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ptr = argv;
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (ii = 0; ii < argc; ++ii) {
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alen = strlen(ptr);
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = varint_encode(alen, comp_ptr);
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strncpy(comp_ptr, ptr, alen);
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr += alen;
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ptr += alen + 1;
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr;
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_mmap(unsigned long vstart, unsigned long vend,
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned long offset, const char *path)
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld mmap %08lx - %08lx, offset %08lx '%s'\n",
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sim_time, vstart, vend, offset, path);
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int len = strlen(path);
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + len + kMaxMmapCompressed;
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidMmap;
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(vstart, comp_ptr);
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(vend, comp_ptr);
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(offset, comp_ptr);
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(len, comp_ptr);
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy(comp_ptr, path, len);
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr + len;
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_munmap(unsigned long vstart, unsigned long vend)
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld munmap %08lx - %08lx\n",
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sim_time, vstart, vend);
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + kMaxMunmapCompressed;
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidMunmap;
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(vstart, comp_ptr);
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(vend, comp_ptr);
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr;
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_dynamic_symbol_add(unsigned long vaddr, const char *name)
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld sym %08lx '%s'\n", sim_time, vaddr, name);
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int len = strlen(name);
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + len + kMaxSymbolCompressed;
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidSymbolAdd;
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(vaddr, comp_ptr);
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(len, comp_ptr);
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy(comp_ptr, name, len);
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr + len;
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_dynamic_symbol_remove(unsigned long vaddr)
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld remove %08lx\n", sim_time, vaddr);
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + kMaxSymbolCompressed;
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidSymbolRemove;
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(vaddr, comp_ptr);
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr;
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_init_name(int tgid, int pid, const char *name)
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_pid.fstream == NULL)
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld kthread %d %s\n", sim_time, pid, name);
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int len = strlen(name);
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_pid.compressed_ptr;
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + len + kMaxKthreadNameCompressed;
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_pid.compressed;
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_pid.compressed;
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_pid.prev_time;
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.prev_time = sim_time;
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int rec_type = kPidKthreadName;
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(rec_type, comp_ptr);
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(tgid, comp_ptr);
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(pid, comp_ptr);
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(len, comp_ptr);
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy(comp_ptr, name, len);
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_pid.compressed_ptr = comp_ptr + len;
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_init_exec(unsigned long start, unsigned long end,
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     unsigned long offset, const char *exe)
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This function is called by the generated code to record the basic
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// block number.
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_bb_helper(uint64_t bb_num, TranslationBlock *tb)
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BBRec *bb_rec = tb->bb_rec;
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t prev_time = tb->prev_time;
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.current_bb_addr = tb->pc;
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.current_bb_num = bb_num;
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.current_bb_start_time = sim_time;
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.num_insns = 0;
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.recnum += 1;
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug)
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "t%lld %lld\n", sim_time, bb_num);
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (bb_rec && bb_rec->bb_num == bb_num && prev_time > trace_bb.flush_time) {
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t time_diff = sim_time - prev_time;
17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (bb_rec->repeat == 0) {
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bb_rec->repeat = 1;
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bb_rec->time_diff = time_diff;
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tb->prev_time = sim_time;
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (time_diff == bb_rec->time_diff) {
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bb_rec->repeat += 1;
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tb->prev_time = sim_time;
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BBRec *next = trace_bb.next;
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (next == &trace_bb.buffer[kMaxNumBasicBlocks]) {
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        BBRec *ptr;
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *comp_ptr = trace_bb.compressed_ptr;
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int64_t prev_bb_num = trace_bb.prev_bb_num;
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t prev_bb_time = trace_bb.prev_bb_time;
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ptr = trace_bb.buffer; ptr != next; ++ptr) {
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (comp_ptr >= trace_bb.high_water_ptr) {
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t size = comp_ptr - trace_bb.compressed;
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fwrite(trace_bb.compressed, sizeof(char), size, trace_bb.fstream);
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = trace_bb.compressed;
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int64_t bb_diff = ptr->bb_num - prev_bb_num;
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_bb_num = ptr->bb_num;
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint64_t time_diff = ptr->start_time - prev_bb_time;
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev_bb_time = ptr->start_time;
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(time_diff, comp_ptr);
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ptr->repeat)
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_bb.compressed_ptr = comp_ptr;
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_bb.prev_bb_num = prev_bb_num;
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_bb.prev_bb_time = prev_bb_time;
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        next = trace_bb.buffer;
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_bb.flush_time = sim_time;
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb->bb_rec = next;
17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next->bb_num = bb_num;
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next->start_time = sim_time;
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next->time_diff = 0;
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next->repeat = 0;
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb->prev_time = sim_time;
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next += 1;
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.next = next;
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// This function is called by the generated code to record the simulation
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// time at the start of each instruction.
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_insn_helper()
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    InsnRec *current = trace_insn.current;
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_insn.prev_time;
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.prev_time = sim_time;
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // Keep track of the number of traced instructions so far in this
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // basic block in case we get an exception in the middle of the bb.
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb.num_insns += 1;
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ftrace_debug) {
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t current_pc = trace_bb.current_bb_addr + 4 * (trace_bb.num_insns - 1);
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(ftrace_debug, "%llu %x\n", sim_time, current_pc);
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (time_diff == current->time_diff) {
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        current->repeat += 1;
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (current->repeat != 0)
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // The repeat count wrapped around, so back up one and create
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // a new record.
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        current->repeat -= 1;
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    current += 1;
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (current == &trace_insn.buffer[kInsnBufferSize]) {
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        InsnRec *ptr;
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char *comp_ptr = trace_insn.compressed_ptr;
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (ptr = trace_insn.buffer; ptr != current; ++ptr) {
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (comp_ptr >= trace_insn.high_water_ptr) {
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t size = comp_ptr - trace_insn.compressed;
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                uint32_t rval = fwrite(trace_insn.compressed, sizeof(char),
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                       size, trace_insn.fstream);
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (rval != size) {
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(stderr, "fwrite() failed\n");
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    perror(trace_insn.filename);
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    exit(1);
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                comp_ptr = trace_insn.compressed;
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            comp_ptr = varint_encode(ptr->repeat, comp_ptr);
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        trace_insn.compressed_ptr = comp_ptr;
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        current = trace_insn.buffer;
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    current->time_diff = time_diff;
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    current->repeat = 0;
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn.current = current;
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Adds an interpreted method trace record.  Each trace record is a time
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// stamped entry or exit to a method in a language executed by a "virtual
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// machine".  This allows profiling tools to show the method names instead
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// of the core virtual machine interpreter.
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid trace_interpreted_method(uint32_t addr, int call_type)
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (trace_method.fstream == NULL)
18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fprintf(stderr, "trace_method time: %llu p%d 0x%x %d\n",
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sim_time, current_pid, addr, call_type);
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *comp_ptr = trace_method.compressed_ptr;
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *max_end_ptr = comp_ptr + kMaxMethodCompressed;
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_end_ptr >= &trace_method.compressed[kCompressedSize]) {
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t size = comp_ptr - trace_method.compressed;
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fwrite(trace_method.compressed, sizeof(char), size, trace_method.fstream);
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        comp_ptr = trace_method.compressed;
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t time_diff = sim_time - trace_method.prev_time;
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.prev_time = sim_time;
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t addr_diff = addr - trace_method.prev_addr;
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.prev_addr = addr;
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t pid_diff = current_pid - trace_method.prev_pid;
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.prev_pid = current_pid;
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(time_diff, comp_ptr);
18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode_signed(pid_diff, comp_ptr);
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    comp_ptr = varint_encode(call_type, comp_ptr);
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_method.compressed_ptr = comp_ptr;
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1880