110259SAndrew.Bardsley@arm.com/*
210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited
310259SAndrew.Bardsley@arm.com * All rights reserved
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall
610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual
710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating
810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software
910259SAndrew.Bardsley@arm.com * licensed hereunder.  You may use the software subject to the license
1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated
1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software,
1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form.
1310259SAndrew.Bardsley@arm.com *
1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
2410259SAndrew.Bardsley@arm.com *
2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610259SAndrew.Bardsley@arm.com *
3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley
3810259SAndrew.Bardsley@arm.com */
3910259SAndrew.Bardsley@arm.com
4010259SAndrew.Bardsley@arm.com#include "cpu/minor/decode.hh"
4111793Sbrandon.potter@amd.com
4210259SAndrew.Bardsley@arm.com#include "cpu/minor/pipeline.hh"
4310259SAndrew.Bardsley@arm.com#include "debug/Decode.hh"
4410259SAndrew.Bardsley@arm.com
4510259SAndrew.Bardsley@arm.comnamespace Minor
4610259SAndrew.Bardsley@arm.com{
4710259SAndrew.Bardsley@arm.com
4810259SAndrew.Bardsley@arm.comDecode::Decode(const std::string &name,
4910259SAndrew.Bardsley@arm.com    MinorCPU &cpu_,
5010259SAndrew.Bardsley@arm.com    MinorCPUParams &params,
5110259SAndrew.Bardsley@arm.com    Latch<ForwardInstData>::Output inp_,
5210259SAndrew.Bardsley@arm.com    Latch<ForwardInstData>::Input out_,
5311567Smitch.hayenga@arm.com    std::vector<InputBuffer<ForwardInstData>> &next_stage_input_buffer) :
5410259SAndrew.Bardsley@arm.com    Named(name),
5510259SAndrew.Bardsley@arm.com    cpu(cpu_),
5610259SAndrew.Bardsley@arm.com    inp(inp_),
5710259SAndrew.Bardsley@arm.com    out(out_),
5810259SAndrew.Bardsley@arm.com    nextStageReserve(next_stage_input_buffer),
5910259SAndrew.Bardsley@arm.com    outputWidth(params.executeInputWidth),
6010259SAndrew.Bardsley@arm.com    processMoreThanOneInput(params.decodeCycleInput),
6111567Smitch.hayenga@arm.com    decodeInfo(params.numThreads),
6211567Smitch.hayenga@arm.com    threadPriority(0)
6310259SAndrew.Bardsley@arm.com{
6410259SAndrew.Bardsley@arm.com    if (outputWidth < 1)
6510259SAndrew.Bardsley@arm.com        fatal("%s: executeInputWidth must be >= 1 (%d)\n", name, outputWidth);
6610259SAndrew.Bardsley@arm.com
6710259SAndrew.Bardsley@arm.com    if (params.decodeInputBufferSize < 1) {
6810259SAndrew.Bardsley@arm.com        fatal("%s: decodeInputBufferSize must be >= 1 (%d)\n", name,
6910259SAndrew.Bardsley@arm.com        params.decodeInputBufferSize);
7010259SAndrew.Bardsley@arm.com    }
7111567Smitch.hayenga@arm.com
7211567Smitch.hayenga@arm.com    /* Per-thread input buffers */
7311567Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < params.numThreads; tid++) {
7411567Smitch.hayenga@arm.com        inputBuffer.push_back(
7511567Smitch.hayenga@arm.com            InputBuffer<ForwardInstData>(
7611567Smitch.hayenga@arm.com                name + ".inputBuffer" + std::to_string(tid), "insts",
7711567Smitch.hayenga@arm.com                params.decodeInputBufferSize));
7811567Smitch.hayenga@arm.com    }
7910259SAndrew.Bardsley@arm.com}
8010259SAndrew.Bardsley@arm.com
8110259SAndrew.Bardsley@arm.comconst ForwardInstData *
8211567Smitch.hayenga@arm.comDecode::getInput(ThreadID tid)
8310259SAndrew.Bardsley@arm.com{
8410259SAndrew.Bardsley@arm.com    /* Get insts from the inputBuffer to work with */
8511567Smitch.hayenga@arm.com    if (!inputBuffer[tid].empty()) {
8611567Smitch.hayenga@arm.com        const ForwardInstData &head = inputBuffer[tid].front();
8710259SAndrew.Bardsley@arm.com
8811567Smitch.hayenga@arm.com        return (head.isBubble() ? NULL : &(inputBuffer[tid].front()));
8910259SAndrew.Bardsley@arm.com    } else {
9010259SAndrew.Bardsley@arm.com        return NULL;
9110259SAndrew.Bardsley@arm.com    }
9210259SAndrew.Bardsley@arm.com}
9310259SAndrew.Bardsley@arm.com
9410259SAndrew.Bardsley@arm.comvoid
9511567Smitch.hayenga@arm.comDecode::popInput(ThreadID tid)
9610259SAndrew.Bardsley@arm.com{
9711567Smitch.hayenga@arm.com    if (!inputBuffer[tid].empty())
9811567Smitch.hayenga@arm.com        inputBuffer[tid].pop();
9910259SAndrew.Bardsley@arm.com
10011567Smitch.hayenga@arm.com    decodeInfo[tid].inputIndex = 0;
10111567Smitch.hayenga@arm.com    decodeInfo[tid].inMacroop = false;
10210259SAndrew.Bardsley@arm.com}
10310259SAndrew.Bardsley@arm.com
10410259SAndrew.Bardsley@arm.com#if TRACING_ON
10510259SAndrew.Bardsley@arm.com/** Add the tracing data to an instruction.  This originates in
10610259SAndrew.Bardsley@arm.com *  decode because this is the first place that execSeqNums are known
10710259SAndrew.Bardsley@arm.com *  (these are used as the 'FetchSeq' in tracing data) */
10810259SAndrew.Bardsley@arm.comstatic void
10910259SAndrew.Bardsley@arm.comdynInstAddTracing(MinorDynInstPtr inst, StaticInstPtr static_inst,
11010259SAndrew.Bardsley@arm.com    MinorCPU &cpu)
11110259SAndrew.Bardsley@arm.com{
11210259SAndrew.Bardsley@arm.com    inst->traceData = cpu.getTracer()->getInstRecord(curTick(),
11310259SAndrew.Bardsley@arm.com        cpu.getContext(inst->id.threadId),
11410259SAndrew.Bardsley@arm.com        inst->staticInst, inst->pc, static_inst);
11510259SAndrew.Bardsley@arm.com
11610259SAndrew.Bardsley@arm.com    /* Use the execSeqNum as the fetch sequence number as this most closely
11710259SAndrew.Bardsley@arm.com     *  matches the other processor models' idea of fetch sequence */
11810259SAndrew.Bardsley@arm.com    if (inst->traceData)
11910259SAndrew.Bardsley@arm.com        inst->traceData->setFetchSeq(inst->id.execSeqNum);
12010259SAndrew.Bardsley@arm.com}
12110259SAndrew.Bardsley@arm.com#endif
12210259SAndrew.Bardsley@arm.com
12310259SAndrew.Bardsley@arm.comvoid
12410259SAndrew.Bardsley@arm.comDecode::evaluate()
12510259SAndrew.Bardsley@arm.com{
12611567Smitch.hayenga@arm.com    /* Push input onto appropriate input buffer */
12711567Smitch.hayenga@arm.com    if (!inp.outputWire->isBubble())
12811567Smitch.hayenga@arm.com        inputBuffer[inp.outputWire->threadId].setTail(*inp.outputWire);
12911567Smitch.hayenga@arm.com
13010259SAndrew.Bardsley@arm.com    ForwardInstData &insts_out = *out.inputWire;
13110259SAndrew.Bardsley@arm.com
13210259SAndrew.Bardsley@arm.com    assert(insts_out.isBubble());
13310259SAndrew.Bardsley@arm.com
13411567Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < cpu.numThreads; tid++)
13511567Smitch.hayenga@arm.com        decodeInfo[tid].blocked = !nextStageReserve[tid].canReserve();
13610259SAndrew.Bardsley@arm.com
13711567Smitch.hayenga@arm.com    ThreadID tid = getScheduledThread();
13811567Smitch.hayenga@arm.com
13911567Smitch.hayenga@arm.com    if (tid != InvalidThreadID) {
14011567Smitch.hayenga@arm.com        DecodeThreadInfo &decode_info = decodeInfo[tid];
14111567Smitch.hayenga@arm.com        const ForwardInstData *insts_in = getInput(tid);
14210259SAndrew.Bardsley@arm.com
14310259SAndrew.Bardsley@arm.com        unsigned int output_index = 0;
14410259SAndrew.Bardsley@arm.com
14510259SAndrew.Bardsley@arm.com        /* Pack instructions into the output while we can.  This may involve
14610259SAndrew.Bardsley@arm.com         * using more than one input line */
14710259SAndrew.Bardsley@arm.com        while (insts_in &&
14811567Smitch.hayenga@arm.com           decode_info.inputIndex < insts_in->width() && /* Still more input */
14910259SAndrew.Bardsley@arm.com           output_index < outputWidth /* Still more output to fill */)
15010259SAndrew.Bardsley@arm.com        {
15111567Smitch.hayenga@arm.com            MinorDynInstPtr inst = insts_in->insts[decode_info.inputIndex];
15210259SAndrew.Bardsley@arm.com
15310259SAndrew.Bardsley@arm.com            if (inst->isBubble()) {
15410259SAndrew.Bardsley@arm.com                /* Skip */
15511567Smitch.hayenga@arm.com                decode_info.inputIndex++;
15611567Smitch.hayenga@arm.com                decode_info.inMacroop = false;
15710259SAndrew.Bardsley@arm.com            } else {
15810259SAndrew.Bardsley@arm.com                StaticInstPtr static_inst = inst->staticInst;
15910259SAndrew.Bardsley@arm.com                /* Static inst of a macro-op above the output_inst */
16010259SAndrew.Bardsley@arm.com                StaticInstPtr parent_static_inst = NULL;
16110259SAndrew.Bardsley@arm.com                MinorDynInstPtr output_inst = inst;
16210259SAndrew.Bardsley@arm.com
16310259SAndrew.Bardsley@arm.com                if (inst->isFault()) {
16410259SAndrew.Bardsley@arm.com                    DPRINTF(Decode, "Fault being passed: %d\n",
16510259SAndrew.Bardsley@arm.com                        inst->fault->name());
16610259SAndrew.Bardsley@arm.com
16711567Smitch.hayenga@arm.com                    decode_info.inputIndex++;
16811567Smitch.hayenga@arm.com                    decode_info.inMacroop = false;
16910259SAndrew.Bardsley@arm.com                } else if (static_inst->isMacroop()) {
17010259SAndrew.Bardsley@arm.com                    /* Generate a new micro-op */
17110259SAndrew.Bardsley@arm.com                    StaticInstPtr static_micro_inst;
17210259SAndrew.Bardsley@arm.com
17310259SAndrew.Bardsley@arm.com                    /* Set up PC for the next micro-op emitted */
17411567Smitch.hayenga@arm.com                    if (!decode_info.inMacroop) {
17511567Smitch.hayenga@arm.com                        decode_info.microopPC = inst->pc;
17611567Smitch.hayenga@arm.com                        decode_info.inMacroop = true;
17710259SAndrew.Bardsley@arm.com                    }
17810259SAndrew.Bardsley@arm.com
17910259SAndrew.Bardsley@arm.com                    /* Get the micro-op static instruction from the
18010259SAndrew.Bardsley@arm.com                     * static_inst. */
18110259SAndrew.Bardsley@arm.com                    static_micro_inst =
18211567Smitch.hayenga@arm.com                        static_inst->fetchMicroop(
18311567Smitch.hayenga@arm.com                                decode_info.microopPC.microPC());
18410259SAndrew.Bardsley@arm.com
18510259SAndrew.Bardsley@arm.com                    output_inst = new MinorDynInst(inst->id);
18611567Smitch.hayenga@arm.com                    output_inst->pc = decode_info.microopPC;
18710259SAndrew.Bardsley@arm.com                    output_inst->staticInst = static_micro_inst;
18810259SAndrew.Bardsley@arm.com                    output_inst->fault = NoFault;
18910259SAndrew.Bardsley@arm.com
19010259SAndrew.Bardsley@arm.com                    /* Allow a predicted next address only on the last
19110259SAndrew.Bardsley@arm.com                     *  microop */
19210259SAndrew.Bardsley@arm.com                    if (static_micro_inst->isLastMicroop()) {
19310259SAndrew.Bardsley@arm.com                        output_inst->predictedTaken = inst->predictedTaken;
19410259SAndrew.Bardsley@arm.com                        output_inst->predictedTarget = inst->predictedTarget;
19510259SAndrew.Bardsley@arm.com                    }
19610259SAndrew.Bardsley@arm.com
19710259SAndrew.Bardsley@arm.com                    DPRINTF(Decode, "Microop decomposition inputIndex:"
19810259SAndrew.Bardsley@arm.com                        " %d output_index: %d lastMicroop: %s microopPC:"
19910259SAndrew.Bardsley@arm.com                        " %d.%d inst: %d\n",
20011567Smitch.hayenga@arm.com                        decode_info.inputIndex, output_index,
20110259SAndrew.Bardsley@arm.com                        (static_micro_inst->isLastMicroop() ?
20210259SAndrew.Bardsley@arm.com                            "true" : "false"),
20311567Smitch.hayenga@arm.com                        decode_info.microopPC.instAddr(),
20411567Smitch.hayenga@arm.com                        decode_info.microopPC.microPC(),
20510259SAndrew.Bardsley@arm.com                        *output_inst);
20610259SAndrew.Bardsley@arm.com
20710259SAndrew.Bardsley@arm.com                    /* Acknowledge that the static_inst isn't mine, it's my
20810259SAndrew.Bardsley@arm.com                     * parent macro-op's */
20910259SAndrew.Bardsley@arm.com                    parent_static_inst = static_inst;
21010259SAndrew.Bardsley@arm.com
21111567Smitch.hayenga@arm.com                    static_micro_inst->advancePC(decode_info.microopPC);
21210259SAndrew.Bardsley@arm.com
21310259SAndrew.Bardsley@arm.com                    /* Step input if this is the last micro-op */
21410259SAndrew.Bardsley@arm.com                    if (static_micro_inst->isLastMicroop()) {
21511567Smitch.hayenga@arm.com                        decode_info.inputIndex++;
21611567Smitch.hayenga@arm.com                        decode_info.inMacroop = false;
21710259SAndrew.Bardsley@arm.com                    }
21810259SAndrew.Bardsley@arm.com                } else {
21910259SAndrew.Bardsley@arm.com                    /* Doesn't need decomposing, pass on instruction */
22010259SAndrew.Bardsley@arm.com                    DPRINTF(Decode, "Passing on inst: %s inputIndex:"
22110259SAndrew.Bardsley@arm.com                        " %d output_index: %d\n",
22211567Smitch.hayenga@arm.com                        *output_inst, decode_info.inputIndex, output_index);
22310259SAndrew.Bardsley@arm.com
22410259SAndrew.Bardsley@arm.com                    parent_static_inst = static_inst;
22510259SAndrew.Bardsley@arm.com
22610259SAndrew.Bardsley@arm.com                    /* Step input */
22711567Smitch.hayenga@arm.com                    decode_info.inputIndex++;
22811567Smitch.hayenga@arm.com                    decode_info.inMacroop = false;
22910259SAndrew.Bardsley@arm.com                }
23010259SAndrew.Bardsley@arm.com
23110259SAndrew.Bardsley@arm.com                /* Set execSeqNum of output_inst */
23211567Smitch.hayenga@arm.com                output_inst->id.execSeqNum = decode_info.execSeqNum;
23310259SAndrew.Bardsley@arm.com                /* Add tracing */
23410259SAndrew.Bardsley@arm.com#if TRACING_ON
23510259SAndrew.Bardsley@arm.com                dynInstAddTracing(output_inst, parent_static_inst, cpu);
23610259SAndrew.Bardsley@arm.com#endif
23710259SAndrew.Bardsley@arm.com
23810259SAndrew.Bardsley@arm.com                /* Step to next sequence number */
23911567Smitch.hayenga@arm.com                decode_info.execSeqNum++;
24010259SAndrew.Bardsley@arm.com
24110259SAndrew.Bardsley@arm.com                /* Correctly size the output before writing */
24211321Ssteve.reinhardt@amd.com                if (output_index == 0) insts_out.resize(outputWidth);
24310259SAndrew.Bardsley@arm.com                /* Push into output */
24410259SAndrew.Bardsley@arm.com                insts_out.insts[output_index] = output_inst;
24510259SAndrew.Bardsley@arm.com                output_index++;
24610259SAndrew.Bardsley@arm.com            }
24710259SAndrew.Bardsley@arm.com
24810259SAndrew.Bardsley@arm.com            /* Have we finished with the input? */
24911567Smitch.hayenga@arm.com            if (decode_info.inputIndex == insts_in->width()) {
25010259SAndrew.Bardsley@arm.com                /* If we have just been producing micro-ops, we *must* have
25110259SAndrew.Bardsley@arm.com                 * got to the end of that for inputIndex to be pushed past
25210259SAndrew.Bardsley@arm.com                 * insts_in->width() */
25311567Smitch.hayenga@arm.com                assert(!decode_info.inMacroop);
25411567Smitch.hayenga@arm.com                popInput(tid);
25510259SAndrew.Bardsley@arm.com                insts_in = NULL;
25610259SAndrew.Bardsley@arm.com
25710259SAndrew.Bardsley@arm.com                if (processMoreThanOneInput) {
25810259SAndrew.Bardsley@arm.com                    DPRINTF(Decode, "Wrapping\n");
25911567Smitch.hayenga@arm.com                    insts_in = getInput(tid);
26010259SAndrew.Bardsley@arm.com                }
26110259SAndrew.Bardsley@arm.com            }
26210259SAndrew.Bardsley@arm.com        }
26310259SAndrew.Bardsley@arm.com
26410259SAndrew.Bardsley@arm.com        /* The rest of the output (if any) should already have been packed
26510259SAndrew.Bardsley@arm.com         *  with bubble instructions by insts_out's initialisation
26610259SAndrew.Bardsley@arm.com         *
26710259SAndrew.Bardsley@arm.com         *  for (; output_index < outputWidth; output_index++)
26810259SAndrew.Bardsley@arm.com         *      assert(insts_out.insts[output_index]->isBubble());
26910259SAndrew.Bardsley@arm.com         */
27010259SAndrew.Bardsley@arm.com    }
27110259SAndrew.Bardsley@arm.com
27210259SAndrew.Bardsley@arm.com    /* If we generated output, reserve space for the result in the next stage
27310259SAndrew.Bardsley@arm.com     *  and mark the stage as being active this cycle */
27410259SAndrew.Bardsley@arm.com    if (!insts_out.isBubble()) {
27510259SAndrew.Bardsley@arm.com        /* Note activity of following buffer */
27610259SAndrew.Bardsley@arm.com        cpu.activityRecorder->activity();
27711567Smitch.hayenga@arm.com        insts_out.threadId = tid;
27811567Smitch.hayenga@arm.com        nextStageReserve[tid].reserve();
27910259SAndrew.Bardsley@arm.com    }
28010259SAndrew.Bardsley@arm.com
28110259SAndrew.Bardsley@arm.com    /* If we still have input to process and somewhere to put it,
28210259SAndrew.Bardsley@arm.com     *  mark stage as active */
28311567Smitch.hayenga@arm.com    for (ThreadID i = 0; i < cpu.numThreads; i++)
28411567Smitch.hayenga@arm.com    {
28511567Smitch.hayenga@arm.com        if (getInput(i) && nextStageReserve[i].canReserve()) {
28611567Smitch.hayenga@arm.com            cpu.activityRecorder->activateStage(Pipeline::DecodeStageId);
28711567Smitch.hayenga@arm.com            break;
28811567Smitch.hayenga@arm.com        }
28911567Smitch.hayenga@arm.com    }
29010259SAndrew.Bardsley@arm.com
29110259SAndrew.Bardsley@arm.com    /* Make sure the input (if any left) is pushed */
29211567Smitch.hayenga@arm.com    if (!inp.outputWire->isBubble())
29311567Smitch.hayenga@arm.com        inputBuffer[inp.outputWire->threadId].pushTail();
29411567Smitch.hayenga@arm.com}
29511567Smitch.hayenga@arm.com
29611567Smitch.hayenga@arm.cominline ThreadID
29711567Smitch.hayenga@arm.comDecode::getScheduledThread()
29811567Smitch.hayenga@arm.com{
29911567Smitch.hayenga@arm.com    /* Select thread via policy. */
30011567Smitch.hayenga@arm.com    std::vector<ThreadID> priority_list;
30111567Smitch.hayenga@arm.com
30211567Smitch.hayenga@arm.com    switch (cpu.threadPolicy) {
30311567Smitch.hayenga@arm.com      case Enums::SingleThreaded:
30411567Smitch.hayenga@arm.com        priority_list.push_back(0);
30511567Smitch.hayenga@arm.com        break;
30611567Smitch.hayenga@arm.com      case Enums::RoundRobin:
30711567Smitch.hayenga@arm.com        priority_list = cpu.roundRobinPriority(threadPriority);
30811567Smitch.hayenga@arm.com        break;
30911567Smitch.hayenga@arm.com      case Enums::Random:
31011567Smitch.hayenga@arm.com        priority_list = cpu.randomPriority();
31111567Smitch.hayenga@arm.com        break;
31211567Smitch.hayenga@arm.com      default:
31311567Smitch.hayenga@arm.com        panic("Unknown fetch policy");
31411567Smitch.hayenga@arm.com    }
31511567Smitch.hayenga@arm.com
31611567Smitch.hayenga@arm.com    for (auto tid : priority_list) {
31713965Sgiacomo.travaglini@arm.com        if (getInput(tid) && !decodeInfo[tid].blocked) {
31811567Smitch.hayenga@arm.com            threadPriority = tid;
31911567Smitch.hayenga@arm.com            return tid;
32011567Smitch.hayenga@arm.com        }
32111567Smitch.hayenga@arm.com    }
32211567Smitch.hayenga@arm.com
32311567Smitch.hayenga@arm.com   return InvalidThreadID;
32410259SAndrew.Bardsley@arm.com}
32510259SAndrew.Bardsley@arm.com
32610259SAndrew.Bardsley@arm.combool
32710259SAndrew.Bardsley@arm.comDecode::isDrained()
32810259SAndrew.Bardsley@arm.com{
32911567Smitch.hayenga@arm.com    for (const auto &buffer : inputBuffer) {
33011567Smitch.hayenga@arm.com        if (!buffer.empty())
33111567Smitch.hayenga@arm.com            return false;
33211567Smitch.hayenga@arm.com    }
33311567Smitch.hayenga@arm.com
33411567Smitch.hayenga@arm.com    return (*inp.outputWire).isBubble();
33510259SAndrew.Bardsley@arm.com}
33610259SAndrew.Bardsley@arm.com
33710259SAndrew.Bardsley@arm.comvoid
33810259SAndrew.Bardsley@arm.comDecode::minorTrace() const
33910259SAndrew.Bardsley@arm.com{
34010259SAndrew.Bardsley@arm.com    std::ostringstream data;
34110259SAndrew.Bardsley@arm.com
34211567Smitch.hayenga@arm.com    if (decodeInfo[0].blocked)
34310259SAndrew.Bardsley@arm.com        data << 'B';
34410259SAndrew.Bardsley@arm.com    else
34510259SAndrew.Bardsley@arm.com        (*out.inputWire).reportData(data);
34610259SAndrew.Bardsley@arm.com
34710259SAndrew.Bardsley@arm.com    MINORTRACE("insts=%s\n", data.str());
34811567Smitch.hayenga@arm.com    inputBuffer[0].minorTrace();
34910259SAndrew.Bardsley@arm.com}
35010259SAndrew.Bardsley@arm.com
35110259SAndrew.Bardsley@arm.com}
352