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