exetrace.hh revision 56
1/*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __EXETRACE_HH__
30#define __EXETRACE_HH__
31
32#include <fstream>
33#include <vector>
34
35#include "sim/host.hh"
36#include "cpu/inst_seq.hh"	// for InstSeqNum
37#include "base/trace.hh"
38#include "cpu/exec_context.hh"
39#include "cpu/static_inst.hh"
40
41class BaseCPU;
42
43
44namespace Trace {
45
46#if 0
47    static const FlagVec ALL =			ULL(0x1);
48    static const FlagVec FULL =			ULL(0x2);
49    static const FlagVec SYMBOLS = 		ULL(0x4);
50    static const FlagVec EXTENDED =		ULL(0x8);
51    static const FlagVec BRANCH_TAKEN = 	ULL(0x10);
52    static const FlagVec BRANCH_NOTTAKEN = 	ULL(0x20);
53    static const FlagVec CALLPAL =		ULL(0x40);
54    static const FlagVec SPECULATIVE =		ULL(0x100);
55    static const FlagVec OMIT_COUNT =		ULL(0x200);
56    static const FlagVec INCLUDE_THREAD_NUM =	ULL(0x400);
57#endif
58
59class InstRecord : public Record
60{
61  protected:
62
63    // The following fields are initialized by the constructor and
64    // thus guaranteed to be valid.
65    BaseCPU *cpu;
66    // need to make this ref-counted so it doesn't go away before we
67    // dump the record
68    StaticInstPtr<TheISA> staticInst;
69    Addr PC;
70    bool misspeculating;
71    unsigned thread;
72
73    // The remaining fields are only valid for particular instruction
74    // types (e.g, addresses for memory ops) or when particular
75    // options are enabled (e.g., tracing full register contents).
76    // Each data field has an associated valid flag to indicate
77    // whether the data field is valid.
78    Addr addr;
79    bool addr_valid;
80
81    union {
82        uint64_t as_int;
83        double as_double;
84    } data;
85    enum {
86        DataInvalid = 0,
87        DataInt8 = 1,	// set to equal number of bytes
88        DataInt16 = 2,
89        DataInt32 = 4,
90        DataInt64 = 8,
91        DataDouble = 3
92    } data_status;
93
94    InstSeqNum fetch_seq;
95    bool fetch_seq_valid;
96
97    InstSeqNum cp_seq;
98    bool cp_seq_valid;
99
100    struct iRegFile {
101        IntRegFile regs;
102    };
103    iRegFile *iregs;
104    bool regs_valid;
105
106  public:
107    InstRecord(Tick _cycle, BaseCPU *_cpu, StaticInstPtr<TheISA> _staticInst,
108               Addr _pc, bool spec, unsigned _thread)
109        : Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc),
110          misspeculating(spec), thread(_thread)
111    {
112        data_status = DataInvalid;
113        addr_valid = false;
114        regs_valid = false;
115
116        fetch_seq_valid = false;
117        cp_seq_valid = false;
118    }
119
120    virtual ~InstRecord() { }
121
122    virtual void dump(std::ostream &outs);
123
124    void setAddr(Addr a) { addr = a; addr_valid = true; }
125
126    void setData(uint64_t d) { data.as_int = d; data_status = DataInt64; }
127    void setData(uint32_t d) { data.as_int = d; data_status = DataInt32; }
128    void setData(uint16_t d) { data.as_int = d; data_status = DataInt16; }
129    void setData(uint8_t d) { data.as_int = d; data_status = DataInt8; }
130
131    void setData(int64_t d) { setData((uint64_t)d); }
132    void setData(int32_t d) { setData((uint32_t)d); }
133    void setData(int16_t d) { setData((uint16_t)d); }
134    void setData(int8_t d)  { setData((uint8_t)d); }
135
136    void setData(double d) { data.as_double = d; data_status = DataDouble; }
137
138    void setFetchSeq(InstSeqNum seq)
139    { fetch_seq = seq; fetch_seq_valid = true; }
140
141    void setCPSeq(InstSeqNum seq)
142    { cp_seq = seq; cp_seq_valid = true; }
143
144    void setRegs(const IntRegFile &regs);
145
146    void finalize() { theLog.append(this); }
147
148    enum InstExecFlagBits {
149        TRACE_MISSPEC = 0,
150        PRINT_CYCLE,
151        PRINT_OP_CLASS,
152        PRINT_THREAD_NUM,
153        PRINT_RESULT_DATA,
154        PRINT_EFF_ADDR,
155        PRINT_INT_REGS,
156        PRINT_FETCH_SEQ,
157        PRINT_CP_SEQ,
158        NUM_BITS
159    };
160
161    static std::vector<bool> flags;
162
163    static void setParams();
164
165    static bool traceMisspec() { return flags[TRACE_MISSPEC]; }
166};
167
168
169inline void
170InstRecord::setRegs(const IntRegFile &regs)
171{
172    if (!iregs)
173      iregs = new iRegFile;
174
175    memcpy(&iregs->regs, regs, sizeof(IntRegFile));
176    regs_valid = true;
177}
178
179inline
180InstRecord *
181getInstRecord(Tick cycle, ExecContext *xc, BaseCPU *cpu,
182              const StaticInstPtr<TheISA> staticInst,
183              Addr pc, int thread = 0)
184{
185    if (DTRACE(InstExec) &&
186        (InstRecord::traceMisspec() || !xc->misspeculating())) {
187        return new InstRecord(cycle, cpu, staticInst, pc,
188                              xc->misspeculating(), thread);
189    }
190
191    return NULL;
192}
193
194
195}
196
197#endif // __EXETRACE_HH__
198