tarmac_record.hh revision 13915
12568SN/A/*
212652Sandreas.sandberg@arm.com * Copyright (c) 2017-2018 ARM Limited
38668Sgeoffrey.blake@arm.com * All rights reserved
48668Sgeoffrey.blake@arm.com *
58668Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall
68668Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual
78668Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating
88668Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software
98668Sgeoffrey.blake@arm.com * licensed hereunder.  You may use the software subject to the license
108668Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated
118668Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software,
128668Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form.
138668Sgeoffrey.blake@arm.com *
142568SN/A * Redistribution and use in source and binary forms, with or without
1510975Sdavid.hashe@amd.com * modification, are permitted provided that the following conditions are
162568SN/A * met: redistributions of source code must retain the above copyright
172568SN/A * notice, this list of conditions and the following disclaimer;
182568SN/A * redistributions in binary form must reproduce the above copyright
192568SN/A * notice, this list of conditions and the following disclaimer in the
202568SN/A * documentation and/or other materials provided with the distribution;
212568SN/A * neither the name of the copyright holders nor the names of its
222568SN/A * contributors may be used to endorse or promote products derived from
232568SN/A * this software without specific prior written permission.
242568SN/A *
252568SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262568SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272568SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282568SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292568SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302568SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312568SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322568SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332568SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342568SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352568SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362568SN/A *
372568SN/A * Authors: Giacomo Travaglini
382568SN/A */
392568SN/A
402665Ssaidi@eecs.umich.edu/**
412665Ssaidi@eecs.umich.edu * @file: The file contains the informations used to generate records
422665Ssaidi@eecs.umich.edu *        for the pre-ARMv8 cores.
432568SN/A */
442568SN/A
452568SN/A#ifndef __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
462568SN/A#define __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
472568SN/A
482568SN/A#include "arch/arm/tracers/tarmac_base.hh"
492568SN/A#include "base/printable.hh"
503260Ssaidi@eecs.umich.edu#include "config/the_isa.hh"
5111793Sbrandon.potter@amd.com#include "cpu/reg_class.hh"
5211793Sbrandon.potter@amd.com#include "cpu/static_inst.hh"
5312821Srmk35@cl.cam.ac.uk
548229Snate@binkert.orgnamespace Trace {
553260Ssaidi@eecs.umich.edu
5612822Srmk35@cl.cam.ac.ukclass TarmacContext;
5712822Srmk35@cl.cam.ac.uk
588229Snate@binkert.orgclass TarmacTracer;
595314Sstever@gmail.com
6012334Sgabeblack@google.com/**
613348Sbinkertn@umich.edu * Returns the string representation of the instruction set being
6212652Sandreas.sandberg@arm.com * currently run according to the Tarmac format.
632568SN/A *
644022Sstever@eecs.umich.edu * @param isetstate: enum variable (ISetState) specifying an ARM
654022Sstever@eecs.umich.edu *                   instruction set.
664022Sstever@eecs.umich.edu * @return instruction set in string format.
674022Sstever@eecs.umich.edu */
684022Sstever@eecs.umich.edustd::string
694022Sstever@eecs.umich.eduiSetStateToStr(TarmacBaseRecord::ISetState isetstate);
704022Sstever@eecs.umich.edu
7111600Sandreas.hansson@arm.com/**
7211600Sandreas.hansson@arm.com * Returns the string representation of the ARM Operating Mode
732641Sstever@eecs.umich.edu * (CPSR.M[3:0] field) according to the Tarmac format.
744022Sstever@eecs.umich.edu *
754022Sstever@eecs.umich.edu * @param opMode: ARM operating mode.
762641Sstever@eecs.umich.edu * @return operating mode in string format.
774022Sstever@eecs.umich.edu */
784022Sstever@eecs.umich.edustd::string
7910885Sandreas.hansson@arm.comopModeToStr(ArmISA::OperatingMode opMode);
8010885Sandreas.hansson@arm.com
814022Sstever@eecs.umich.edu/**
824473Sstever@eecs.umich.edu * TarmacTracer Record:
834473Sstever@eecs.umich.edu * Record generated by the TarmacTracer for every executed instruction.
845319Sstever@gmail.com * The record is composed by a set of entries, matching the tracing
855319Sstever@gmail.com * capabilities provided by the Tarmac specifications:
865319Sstever@gmail.com *
874022Sstever@eecs.umich.edu * - Instruction Entry
8811284Sandreas.hansson@arm.com * - Register Entry
894022Sstever@eecs.umich.edu * - Memory Entry
904022Sstever@eecs.umich.edu */
9111287Sandreas.hansson@arm.comclass TarmacTracerRecord : public TarmacBaseRecord
9211199Sandreas.hansson@arm.com{
9311600Sandreas.hansson@arm.com  public:
9411199Sandreas.hansson@arm.com    /** Instruction Entry */
9511199Sandreas.hansson@arm.com    struct TraceInstEntry: public InstEntry, Printable
9611199Sandreas.hansson@arm.com    {
9711199Sandreas.hansson@arm.com        TraceInstEntry(const TarmacContext& tarmCtx, bool predicate);
9811600Sandreas.hansson@arm.com
9911199Sandreas.hansson@arm.com        virtual void print(std::ostream& outs,
10012344Snikos.nikoleris@arm.com                           int verbosity = 0,
10112344Snikos.nikoleris@arm.com                           const std::string &prefix = "") const override;
10212344Snikos.nikoleris@arm.com
10310883Sali.jafri@arm.com      protected:
10411600Sandreas.hansson@arm.com        /** Number of instructions being traced */
1054022Sstever@eecs.umich.edu        static uint64_t instCount;
1064022Sstever@eecs.umich.edu
1074022Sstever@eecs.umich.edu        /** True if instruction is executed in secure mode */
1084022Sstever@eecs.umich.edu        bool secureMode;
10911600Sandreas.hansson@arm.com        /**
1104022Sstever@eecs.umich.edu         * Instruction size:
1114022Sstever@eecs.umich.edu         * 16 for 16-bit Thumb Instruction
1124022Sstever@eecs.umich.edu         * 32 otherwise (ARM and BigThumb)
1134022Sstever@eecs.umich.edu         */
1144022Sstever@eecs.umich.edu        uint8_t instSize;
1154022Sstever@eecs.umich.edu    };
1164022Sstever@eecs.umich.edu
11710886Sandreas.hansson@arm.com    /** Register Entry */
11811284Sandreas.hansson@arm.com    struct TraceRegEntry: public RegEntry, Printable
11910886Sandreas.hansson@arm.com    {
1204022Sstever@eecs.umich.edu      public:
12111600Sandreas.hansson@arm.com        TraceRegEntry(const TarmacContext& tarmCtx, const RegId& reg);
12211600Sandreas.hansson@arm.com
1234628Sstever@eecs.umich.edu        /**
1247465Ssteve.reinhardt@amd.com         * This updates the register entry using the update table. It is
12511600Sandreas.hansson@arm.com         * a required step after the register entry generation.
12611600Sandreas.hansson@arm.com         * If unupdated, the entry will be marked as invalid.
1277465Ssteve.reinhardt@amd.com         * The entry update cannot be done automatically at TraceRegEntry
1284628Sstever@eecs.umich.edu         * construction: the entries are extended by consequent Tarmac
12911287Sandreas.hansson@arm.com         * Tracer versions (like V8), and virtual functions should
1307465Ssteve.reinhardt@amd.com         * be avoided during construction.
13110325Sgeoffrey.blake@arm.com         */
13211600Sandreas.hansson@arm.com        void update(const TarmacContext& tarmCtx);
13311600Sandreas.hansson@arm.com
1347465Ssteve.reinhardt@amd.com        virtual void print(std::ostream& outs,
13510325Sgeoffrey.blake@arm.com                           int verbosity = 0,
13610325Sgeoffrey.blake@arm.com                           const std::string &prefix = "") const override;
13711287Sandreas.hansson@arm.com
1387465Ssteve.reinhardt@amd.com      protected:
13910885Sandreas.hansson@arm.com        /** Register update functions. */
14010885Sandreas.hansson@arm.com        virtual void
14110885Sandreas.hansson@arm.com        updateMisc(const TarmacContext& tarmCtx, RegIndex regRelIdx);
14211600Sandreas.hansson@arm.com
14311600Sandreas.hansson@arm.com        virtual void
1444022Sstever@eecs.umich.edu        updateCC(const TarmacContext& tarmCtx, RegIndex regRelIdx);
14510885Sandreas.hansson@arm.com
14610885Sandreas.hansson@arm.com        virtual void
14711287Sandreas.hansson@arm.com        updateFloat(const TarmacContext& tarmCtx, RegIndex regRelIdx);
1484040Ssaidi@eecs.umich.edu
14910885Sandreas.hansson@arm.com        virtual void
15010885Sandreas.hansson@arm.com        updateInt(const TarmacContext& tarmCtx, RegIndex regRelIdx);
15110885Sandreas.hansson@arm.com
15211600Sandreas.hansson@arm.com      public:
15311600Sandreas.hansson@arm.com        /** True if register entry is valid */
15410885Sandreas.hansson@arm.com        bool regValid;
15510885Sandreas.hansson@arm.com        /** Register class */
15610885Sandreas.hansson@arm.com        RegClass regClass;
15711600Sandreas.hansson@arm.com        /** Register arch number */
15811600Sandreas.hansson@arm.com        RegIndex regRel;
1595507Sstever@gmail.com        /** Register name to be printed */
1605507Sstever@gmail.com        std::string regName;
1616076Sgblack@eecs.umich.edu    };
1625507Sstever@gmail.com
1634626Sstever@eecs.umich.edu    /** Memory Entry */
16411284Sandreas.hansson@arm.com    struct TraceMemEntry: public MemEntry, Printable
1654626Sstever@eecs.umich.edu    {
1664626Sstever@eecs.umich.edu      public:
16710325Sgeoffrey.blake@arm.com        TraceMemEntry(const TarmacContext& tarmCtx,
16811284Sandreas.hansson@arm.com                      uint8_t _size, Addr _addr, uint64_t _data);
1697669Ssteve.reinhardt@amd.com
1707669Ssteve.reinhardt@amd.com        virtual void print(std::ostream& outs,
1714626Sstever@eecs.umich.edu                           int verbosity = 0,
17211287Sandreas.hansson@arm.com                           const std::string &prefix = "") const override;
1734626Sstever@eecs.umich.edu
1744040Ssaidi@eecs.umich.edu      protected:
17511284Sandreas.hansson@arm.com        /** True if memory access is a load */
1764040Ssaidi@eecs.umich.edu        bool loadAccess;
1774040Ssaidi@eecs.umich.edu    };
17811287Sandreas.hansson@arm.com
1794870Sstever@eecs.umich.edu  public:
1805650Sgblack@eecs.umich.edu    TarmacTracerRecord(Tick _when, ThreadContext *_thread,
1815650Sgblack@eecs.umich.edu                       const StaticInstPtr _staticInst, ArmISA::PCState _pc,
1826063Sgblack@eecs.umich.edu                       TarmacTracer& _tracer,
1835650Sgblack@eecs.umich.edu                       const StaticInstPtr _macroStaticInst = NULL);
1846063Sgblack@eecs.umich.edu
18511256Santhony.gutierrez@amd.com    virtual void dump() override;
18611256Santhony.gutierrez@amd.com
18711256Santhony.gutierrez@amd.com    using InstPtr = std::unique_ptr<TraceInstEntry>;
18811256Santhony.gutierrez@amd.com    using MemPtr = std::unique_ptr<TraceMemEntry>;
18912347Snikos.nikoleris@arm.com    using RegPtr = std::unique_ptr<TraceRegEntry>;
19012347Snikos.nikoleris@arm.com
19112347Snikos.nikoleris@arm.com  protected:
19212347Snikos.nikoleris@arm.com    /** Generates an Entry for the executed instruction. */
19312347Snikos.nikoleris@arm.com    virtual void addInstEntry(std::vector<InstPtr>& queue,
19412347Snikos.nikoleris@arm.com                              const TarmacContext& ptr);
19512347Snikos.nikoleris@arm.com
19612347Snikos.nikoleris@arm.com    /** Generates an Entry for every triggered memory access */
19712347Snikos.nikoleris@arm.com    virtual void addMemEntry(std::vector<MemPtr>& queue,
19812347Snikos.nikoleris@arm.com                             const TarmacContext& ptr);
19912347Snikos.nikoleris@arm.com
20012347Snikos.nikoleris@arm.com    /** Generate an Entry for every register being written. */
20112347Snikos.nikoleris@arm.com    virtual void addRegEntry(std::vector<RegPtr>& queue,
20212347Snikos.nikoleris@arm.com                             const TarmacContext& ptr);
20312347Snikos.nikoleris@arm.com
20412347Snikos.nikoleris@arm.com  protected:
20512347Snikos.nikoleris@arm.com    /** Generate and update a register entry. */
20612347Snikos.nikoleris@arm.com    template<typename RegEntry>
2074870Sstever@eecs.umich.edu    RegEntry
2084986Ssaidi@eecs.umich.edu    genRegister(const TarmacContext& tarmCtx, const RegId& reg)
2094870Sstever@eecs.umich.edu    {
2105314Sstever@gmail.com        RegEntry single_reg(tarmCtx, reg);
2118436SBrad.Beckmann@amd.com        single_reg.update(tarmCtx);
2128436SBrad.Beckmann@amd.com
2138436SBrad.Beckmann@amd.com        return single_reg;
2148436SBrad.Beckmann@amd.com    }
2155314Sstever@gmail.com
2168184Ssomayeh@cs.wisc.edu    template<typename RegEntry>
2178184Ssomayeh@cs.wisc.edu    void
21811284Sandreas.hansson@arm.com    mergeCCEntry(std::vector<RegPtr>& queue, const TarmacContext& tarmCtx)
2198716Snilay@cs.wisc.edu    {
22011600Sandreas.hansson@arm.com        // Find all CC Entries and move them at the end of the queue
22110886Sandreas.hansson@arm.com        auto it = std::remove_if(
22210886Sandreas.hansson@arm.com            queue.begin(), queue.end(),
22311287Sandreas.hansson@arm.com            [] (RegPtr& reg) ->bool { return (reg->regClass == CCRegClass); }
22410886Sandreas.hansson@arm.com        );
2254022Sstever@eecs.umich.edu
2262592SN/A        if (it != queue.end()) {
2273607Srdreslin@umich.edu            // Remove all CC Entries.
22810028SGiacomo.Gabrielli@arm.com            queue.erase(it, queue.end());
22910570Sandreas.hansson@arm.com
2302641Sstever@eecs.umich.edu            auto is_cpsr = [] (RegPtr& reg) ->bool
23112821Srmk35@cl.cam.ac.uk            {
23212821Srmk35@cl.cam.ac.uk                return (reg->regClass == MiscRegClass) &&
23312821Srmk35@cl.cam.ac.uk                       (reg->regRel == ArmISA::MISCREG_CPSR);
23412821Srmk35@cl.cam.ac.uk            };
2353260Ssaidi@eecs.umich.edu
23610028SGiacomo.Gabrielli@arm.com            // Looking for the presence of a CPSR register entry.
23710028SGiacomo.Gabrielli@arm.com            auto cpsr_it = std::find_if(
2384626Sstever@eecs.umich.edu                queue.begin(), queue.end(), is_cpsr
2394626Sstever@eecs.umich.edu            );
2404626Sstever@eecs.umich.edu
2413260Ssaidi@eecs.umich.edu            // If CPSR entry not present, generate one
2425314Sstever@gmail.com            if (cpsr_it == queue.end()) {
2435314Sstever@gmail.com                RegId reg(MiscRegClass, ArmISA::MISCREG_CPSR);
24410570Sandreas.hansson@arm.com                queue.push_back(
24510376Sandreas.hansson@arm.com                    m5::make_unique<RegEntry>(
2465314Sstever@gmail.com                        genRegister<RegEntry>(tarmCtx, reg))
2475314Sstever@gmail.com                );
2485314Sstever@gmail.com            }
24910570Sandreas.hansson@arm.com        }
25010570Sandreas.hansson@arm.com    }
25110570Sandreas.hansson@arm.com
2525314Sstever@gmail.com    /** Flush queues to the trace output */
2535314Sstever@gmail.com    template<typename Queue>
2545314Sstever@gmail.com    void flushQueues(Queue& queue);
25512821Srmk35@cl.cam.ac.uk    template<typename Queue, typename... Args>
25612821Srmk35@cl.cam.ac.uk    void flushQueues(Queue& queue, Args & ... args);
25712821Srmk35@cl.cam.ac.uk
25812821Srmk35@cl.cam.ac.uk  protected:
25912821Srmk35@cl.cam.ac.uk    /** Reference to tracer */
26012821Srmk35@cl.cam.ac.uk    TarmacTracer& tracer;
2613260Ssaidi@eecs.umich.edu};
2624626Sstever@eecs.umich.edu
26312822Srmk35@cl.cam.ac.uk} // namespace Trace
26412821Srmk35@cl.cam.ac.uk
26512821Srmk35@cl.cam.ac.uk#endif // __ARCH_ARM_TRACERS_TARMAC_RECORD_HH__
2668668Sgeoffrey.blake@arm.com