110259SAndrew.Bardsley@arm.com/*
213610Sgiacomo.gabrielli@arm.com * Copyright (c) 2013-2014, 2016-2017 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
4011793Sbrandon.potter@amd.com#include "cpu/minor/scoreboard.hh"
4111793Sbrandon.potter@amd.com
4210259SAndrew.Bardsley@arm.com#include "arch/registers.hh"
4310259SAndrew.Bardsley@arm.com#include "cpu/reg_class.hh"
4410259SAndrew.Bardsley@arm.com#include "debug/MinorScoreboard.hh"
4510259SAndrew.Bardsley@arm.com#include "debug/MinorTiming.hh"
4610259SAndrew.Bardsley@arm.com
4710259SAndrew.Bardsley@arm.comnamespace Minor
4810259SAndrew.Bardsley@arm.com{
4910259SAndrew.Bardsley@arm.com
5010259SAndrew.Bardsley@arm.combool
5112106SRekai.GonzalezAlberquilla@arm.comScoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
5210259SAndrew.Bardsley@arm.com{
5310259SAndrew.Bardsley@arm.com    bool ret = false;
5410259SAndrew.Bardsley@arm.com
5512104Snathanael.premillieu@arm.com    if (reg.isZeroReg()) {
5610259SAndrew.Bardsley@arm.com        /* Don't bother with the zero register */
5710259SAndrew.Bardsley@arm.com        ret = false;
5810259SAndrew.Bardsley@arm.com    } else {
5912106SRekai.GonzalezAlberquilla@arm.com        switch (reg.classValue())
6010259SAndrew.Bardsley@arm.com        {
6110259SAndrew.Bardsley@arm.com          case IntRegClass:
6212106SRekai.GonzalezAlberquilla@arm.com            scoreboard_index = reg.index();
6310259SAndrew.Bardsley@arm.com            ret = true;
6410259SAndrew.Bardsley@arm.com            break;
6510259SAndrew.Bardsley@arm.com          case FloatRegClass:
6610259SAndrew.Bardsley@arm.com            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
6712106SRekai.GonzalezAlberquilla@arm.com                reg.index();
6810259SAndrew.Bardsley@arm.com            ret = true;
6910259SAndrew.Bardsley@arm.com            break;
7012109SRekai.GonzalezAlberquilla@arm.com          case VecRegClass:
7112109SRekai.GonzalezAlberquilla@arm.com            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
7212109SRekai.GonzalezAlberquilla@arm.com                TheISA::NumFloatRegs + reg.index();
7312109SRekai.GonzalezAlberquilla@arm.com            ret = true;
7412109SRekai.GonzalezAlberquilla@arm.com            break;
7512109SRekai.GonzalezAlberquilla@arm.com          case VecElemClass:
7612109SRekai.GonzalezAlberquilla@arm.com            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
7713597Sgiacomo.travaglini@arm.com                TheISA::NumFloatRegs + reg.flatIndex();
7812109SRekai.GonzalezAlberquilla@arm.com            ret = true;
7912109SRekai.GonzalezAlberquilla@arm.com            break;
8013610Sgiacomo.gabrielli@arm.com          case VecPredRegClass:
8113610Sgiacomo.gabrielli@arm.com            scoreboard_index = TheISA::NumIntRegs + TheISA::NumCCRegs +
8213610Sgiacomo.gabrielli@arm.com                TheISA::NumFloatRegs + TheISA::NumVecRegs + reg.index();
8313610Sgiacomo.gabrielli@arm.com            ret = true;
8413610Sgiacomo.gabrielli@arm.com            break;
8510259SAndrew.Bardsley@arm.com          case CCRegClass:
8612106SRekai.GonzalezAlberquilla@arm.com            scoreboard_index = TheISA::NumIntRegs + reg.index();
8710259SAndrew.Bardsley@arm.com            ret = true;
8810259SAndrew.Bardsley@arm.com            break;
8910259SAndrew.Bardsley@arm.com          case MiscRegClass:
9010259SAndrew.Bardsley@arm.com              /* Don't bother with Misc registers */
9110259SAndrew.Bardsley@arm.com            ret = false;
9210259SAndrew.Bardsley@arm.com            break;
9312109SRekai.GonzalezAlberquilla@arm.com          default:
9412109SRekai.GonzalezAlberquilla@arm.com            panic("Unknown register class: %d",
9512109SRekai.GonzalezAlberquilla@arm.com                    static_cast<int>(reg.classValue()));
9610259SAndrew.Bardsley@arm.com        }
9710259SAndrew.Bardsley@arm.com    }
9810259SAndrew.Bardsley@arm.com
9910259SAndrew.Bardsley@arm.com    return ret;
10010259SAndrew.Bardsley@arm.com}
10110259SAndrew.Bardsley@arm.com
10212104Snathanael.premillieu@arm.com/** Flatten a RegId, irrespective of what reg type it's pointing to */
10312104Snathanael.premillieu@arm.comstatic RegId
10412106SRekai.GonzalezAlberquilla@arm.comflattenRegIndex(const RegId& reg, ThreadContext *thread_context)
10510259SAndrew.Bardsley@arm.com{
10612106SRekai.GonzalezAlberquilla@arm.com    return thread_context->flattenRegId(reg);
10710259SAndrew.Bardsley@arm.com}
10810259SAndrew.Bardsley@arm.com
10910259SAndrew.Bardsley@arm.comvoid
11010259SAndrew.Bardsley@arm.comScoreboard::markupInstDests(MinorDynInstPtr inst, Cycles retire_time,
11110259SAndrew.Bardsley@arm.com    ThreadContext *thread_context, bool mark_unpredictable)
11210259SAndrew.Bardsley@arm.com{
11310259SAndrew.Bardsley@arm.com    if (inst->isFault())
11410259SAndrew.Bardsley@arm.com        return;
11510259SAndrew.Bardsley@arm.com
11610259SAndrew.Bardsley@arm.com    StaticInstPtr staticInst = inst->staticInst;
11710259SAndrew.Bardsley@arm.com    unsigned int num_dests = staticInst->numDestRegs();
11810259SAndrew.Bardsley@arm.com
11910259SAndrew.Bardsley@arm.com    /** Mark each destination register */
12010259SAndrew.Bardsley@arm.com    for (unsigned int dest_index = 0; dest_index < num_dests;
12110259SAndrew.Bardsley@arm.com        dest_index++)
12210259SAndrew.Bardsley@arm.com    {
12312104Snathanael.premillieu@arm.com        RegId reg = flattenRegIndex(
12412104Snathanael.premillieu@arm.com                staticInst->destRegIdx(dest_index), thread_context);
12510259SAndrew.Bardsley@arm.com        Index index;
12610259SAndrew.Bardsley@arm.com
12710259SAndrew.Bardsley@arm.com        if (findIndex(reg, index)) {
12810259SAndrew.Bardsley@arm.com            if (mark_unpredictable)
12910259SAndrew.Bardsley@arm.com                numUnpredictableResults[index]++;
13010259SAndrew.Bardsley@arm.com
13110259SAndrew.Bardsley@arm.com            inst->flatDestRegIdx[dest_index] = reg;
13210259SAndrew.Bardsley@arm.com
13310259SAndrew.Bardsley@arm.com            numResults[index]++;
13410259SAndrew.Bardsley@arm.com            returnCycle[index] = retire_time;
13510259SAndrew.Bardsley@arm.com            /* We should be able to rely on only being given accending
13610259SAndrew.Bardsley@arm.com             *  execSeqNums, but sanity check */
13710259SAndrew.Bardsley@arm.com            if (inst->id.execSeqNum > writingInst[index]) {
13810259SAndrew.Bardsley@arm.com                writingInst[index] = inst->id.execSeqNum;
13910259SAndrew.Bardsley@arm.com                fuIndices[index] = inst->fuIndex;
14010259SAndrew.Bardsley@arm.com            }
14110259SAndrew.Bardsley@arm.com
14210259SAndrew.Bardsley@arm.com            DPRINTF(MinorScoreboard, "Marking up inst: %s"
14310259SAndrew.Bardsley@arm.com                " regIndex: %d final numResults: %d returnCycle: %d\n",
14410259SAndrew.Bardsley@arm.com                *inst, index, numResults[index], returnCycle[index]);
14510259SAndrew.Bardsley@arm.com        } else {
14610259SAndrew.Bardsley@arm.com            /* Use ZeroReg to mark invalid/untracked dests */
14712106SRekai.GonzalezAlberquilla@arm.com            inst->flatDestRegIdx[dest_index] = RegId(IntRegClass,
14812106SRekai.GonzalezAlberquilla@arm.com                                                     TheISA::ZeroReg);
14910259SAndrew.Bardsley@arm.com        }
15010259SAndrew.Bardsley@arm.com    }
15110259SAndrew.Bardsley@arm.com}
15210259SAndrew.Bardsley@arm.com
15310259SAndrew.Bardsley@arm.comInstSeqNum
15410259SAndrew.Bardsley@arm.comScoreboard::execSeqNumToWaitFor(MinorDynInstPtr inst,
15510259SAndrew.Bardsley@arm.com    ThreadContext *thread_context)
15610259SAndrew.Bardsley@arm.com{
15710259SAndrew.Bardsley@arm.com    InstSeqNum ret = 0;
15810259SAndrew.Bardsley@arm.com
15910259SAndrew.Bardsley@arm.com    if (inst->isFault())
16010259SAndrew.Bardsley@arm.com        return ret;
16110259SAndrew.Bardsley@arm.com
16210259SAndrew.Bardsley@arm.com    StaticInstPtr staticInst = inst->staticInst;
16310259SAndrew.Bardsley@arm.com    unsigned int num_srcs = staticInst->numSrcRegs();
16410259SAndrew.Bardsley@arm.com
16510259SAndrew.Bardsley@arm.com    for (unsigned int src_index = 0; src_index < num_srcs; src_index++) {
16612104Snathanael.premillieu@arm.com        RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
16710259SAndrew.Bardsley@arm.com            thread_context);
16810259SAndrew.Bardsley@arm.com        unsigned short int index;
16910259SAndrew.Bardsley@arm.com
17010259SAndrew.Bardsley@arm.com        if (findIndex(reg, index)) {
17110259SAndrew.Bardsley@arm.com            if (writingInst[index] > ret)
17210259SAndrew.Bardsley@arm.com                ret = writingInst[index];
17310259SAndrew.Bardsley@arm.com        }
17410259SAndrew.Bardsley@arm.com    }
17510259SAndrew.Bardsley@arm.com
17610259SAndrew.Bardsley@arm.com    DPRINTF(MinorScoreboard, "Inst: %s depends on execSeqNum: %d\n",
17710259SAndrew.Bardsley@arm.com        *inst, ret);
17810259SAndrew.Bardsley@arm.com
17910259SAndrew.Bardsley@arm.com    return ret;
18010259SAndrew.Bardsley@arm.com}
18110259SAndrew.Bardsley@arm.com
18210259SAndrew.Bardsley@arm.comvoid
18310259SAndrew.Bardsley@arm.comScoreboard::clearInstDests(MinorDynInstPtr inst, bool clear_unpredictable)
18410259SAndrew.Bardsley@arm.com{
18510259SAndrew.Bardsley@arm.com    if (inst->isFault())
18610259SAndrew.Bardsley@arm.com        return;
18710259SAndrew.Bardsley@arm.com
18810259SAndrew.Bardsley@arm.com    StaticInstPtr staticInst = inst->staticInst;
18910259SAndrew.Bardsley@arm.com    unsigned int num_dests = staticInst->numDestRegs();
19010259SAndrew.Bardsley@arm.com
19110259SAndrew.Bardsley@arm.com    /** Mark each destination register */
19210259SAndrew.Bardsley@arm.com    for (unsigned int dest_index = 0; dest_index < num_dests;
19310259SAndrew.Bardsley@arm.com        dest_index++)
19410259SAndrew.Bardsley@arm.com    {
19512106SRekai.GonzalezAlberquilla@arm.com        const RegId& reg = inst->flatDestRegIdx[dest_index];
19610259SAndrew.Bardsley@arm.com        Index index;
19710259SAndrew.Bardsley@arm.com
19810259SAndrew.Bardsley@arm.com        if (findIndex(reg, index)) {
19910259SAndrew.Bardsley@arm.com            if (clear_unpredictable && numUnpredictableResults[index] != 0)
20010259SAndrew.Bardsley@arm.com                numUnpredictableResults[index] --;
20110259SAndrew.Bardsley@arm.com
20210259SAndrew.Bardsley@arm.com            numResults[index] --;
20310259SAndrew.Bardsley@arm.com
20410259SAndrew.Bardsley@arm.com            if (numResults[index] == 0) {
20510259SAndrew.Bardsley@arm.com                returnCycle[index] = Cycles(0);
20610259SAndrew.Bardsley@arm.com                writingInst[index] = 0;
20710259SAndrew.Bardsley@arm.com                fuIndices[index] = -1;
20810259SAndrew.Bardsley@arm.com            }
20910259SAndrew.Bardsley@arm.com
21010259SAndrew.Bardsley@arm.com            DPRINTF(MinorScoreboard, "Clearing inst: %s"
21110259SAndrew.Bardsley@arm.com                " regIndex: %d final numResults: %d\n",
21210259SAndrew.Bardsley@arm.com                *inst, index, numResults[index]);
21310259SAndrew.Bardsley@arm.com        }
21410259SAndrew.Bardsley@arm.com    }
21510259SAndrew.Bardsley@arm.com}
21610259SAndrew.Bardsley@arm.com
21710259SAndrew.Bardsley@arm.combool
21810259SAndrew.Bardsley@arm.comScoreboard::canInstIssue(MinorDynInstPtr inst,
21910259SAndrew.Bardsley@arm.com    const std::vector<Cycles> *src_reg_relative_latencies,
22010259SAndrew.Bardsley@arm.com    const std::vector<bool> *cant_forward_from_fu_indices,
22110259SAndrew.Bardsley@arm.com    Cycles now, ThreadContext *thread_context)
22210259SAndrew.Bardsley@arm.com{
22310259SAndrew.Bardsley@arm.com    /* Always allow fault to be issued */
22410259SAndrew.Bardsley@arm.com    if (inst->isFault())
22510259SAndrew.Bardsley@arm.com        return true;
22610259SAndrew.Bardsley@arm.com
22710259SAndrew.Bardsley@arm.com    StaticInstPtr staticInst = inst->staticInst;
22810259SAndrew.Bardsley@arm.com    unsigned int num_srcs = staticInst->numSrcRegs();
22910259SAndrew.Bardsley@arm.com
23010259SAndrew.Bardsley@arm.com    /* Default to saying you can issue */
23110259SAndrew.Bardsley@arm.com    bool ret = true;
23210259SAndrew.Bardsley@arm.com
23310259SAndrew.Bardsley@arm.com    unsigned int num_relative_latencies = 0;
23410259SAndrew.Bardsley@arm.com    Cycles default_relative_latency = Cycles(0);
23510259SAndrew.Bardsley@arm.com
23610259SAndrew.Bardsley@arm.com    /* Where relative latencies are given, the default is the last
23710259SAndrew.Bardsley@arm.com     *  one as that allows the rel. lat. list to be shorted than the
23810259SAndrew.Bardsley@arm.com     *  number of src. regs */
23910259SAndrew.Bardsley@arm.com    if (src_reg_relative_latencies &&
24010259SAndrew.Bardsley@arm.com        src_reg_relative_latencies->size() != 0)
24110259SAndrew.Bardsley@arm.com    {
24210259SAndrew.Bardsley@arm.com        num_relative_latencies = src_reg_relative_latencies->size();
24310259SAndrew.Bardsley@arm.com        default_relative_latency = (*src_reg_relative_latencies)
24410259SAndrew.Bardsley@arm.com            [num_relative_latencies-1];
24510259SAndrew.Bardsley@arm.com    }
24610259SAndrew.Bardsley@arm.com
24710259SAndrew.Bardsley@arm.com    /* For each source register, find the latest result */
24810259SAndrew.Bardsley@arm.com    unsigned int src_index = 0;
24910259SAndrew.Bardsley@arm.com    while (src_index < num_srcs && /* More registers */
25010259SAndrew.Bardsley@arm.com        ret /* Still possible */)
25110259SAndrew.Bardsley@arm.com    {
25212104Snathanael.premillieu@arm.com        RegId reg = flattenRegIndex(staticInst->srcRegIdx(src_index),
25310259SAndrew.Bardsley@arm.com            thread_context);
25410259SAndrew.Bardsley@arm.com        unsigned short int index;
25510259SAndrew.Bardsley@arm.com
25610259SAndrew.Bardsley@arm.com        if (findIndex(reg, index)) {
25710259SAndrew.Bardsley@arm.com            bool cant_forward = fuIndices[index] != 1 &&
25810259SAndrew.Bardsley@arm.com                cant_forward_from_fu_indices &&
25910259SAndrew.Bardsley@arm.com                index < cant_forward_from_fu_indices->size() &&
26010259SAndrew.Bardsley@arm.com                (*cant_forward_from_fu_indices)[index];
26110259SAndrew.Bardsley@arm.com
26210259SAndrew.Bardsley@arm.com            Cycles relative_latency = (cant_forward ? Cycles(0) :
26310259SAndrew.Bardsley@arm.com                (src_index >= num_relative_latencies ?
26410259SAndrew.Bardsley@arm.com                    default_relative_latency :
26510259SAndrew.Bardsley@arm.com                    (*src_reg_relative_latencies)[src_index]));
26610259SAndrew.Bardsley@arm.com
26710259SAndrew.Bardsley@arm.com            if (returnCycle[index] > (now + relative_latency) ||
26810259SAndrew.Bardsley@arm.com                numUnpredictableResults[index] != 0)
26910259SAndrew.Bardsley@arm.com            {
27010259SAndrew.Bardsley@arm.com                ret = false;
27110259SAndrew.Bardsley@arm.com            }
27210259SAndrew.Bardsley@arm.com        }
27310259SAndrew.Bardsley@arm.com        src_index++;
27410259SAndrew.Bardsley@arm.com    }
27510259SAndrew.Bardsley@arm.com
27610259SAndrew.Bardsley@arm.com    if (DTRACE(MinorTiming)) {
27710259SAndrew.Bardsley@arm.com        if (ret && num_srcs > num_relative_latencies &&
27810259SAndrew.Bardsley@arm.com            num_relative_latencies != 0)
27910259SAndrew.Bardsley@arm.com        {
28010259SAndrew.Bardsley@arm.com            DPRINTF(MinorTiming, "Warning, inst: %s timing extra decode has"
28110259SAndrew.Bardsley@arm.com                " more src. regs: %d than relative latencies: %d\n",
28210259SAndrew.Bardsley@arm.com                staticInst->disassemble(0), num_srcs, num_relative_latencies);
28310259SAndrew.Bardsley@arm.com        }
28410259SAndrew.Bardsley@arm.com    }
28510259SAndrew.Bardsley@arm.com
28610259SAndrew.Bardsley@arm.com    return ret;
28710259SAndrew.Bardsley@arm.com}
28810259SAndrew.Bardsley@arm.com
28910259SAndrew.Bardsley@arm.comvoid
29010259SAndrew.Bardsley@arm.comScoreboard::minorTrace() const
29110259SAndrew.Bardsley@arm.com{
29210259SAndrew.Bardsley@arm.com    std::ostringstream result_stream;
29310259SAndrew.Bardsley@arm.com
29410259SAndrew.Bardsley@arm.com    bool printed_element = false;
29510259SAndrew.Bardsley@arm.com
29610259SAndrew.Bardsley@arm.com    unsigned int i = 0;
29710259SAndrew.Bardsley@arm.com    while (i < numRegs) {
29810259SAndrew.Bardsley@arm.com        unsigned short int num_results = numResults[i];
29910259SAndrew.Bardsley@arm.com        unsigned short int num_unpredictable_results =
30010259SAndrew.Bardsley@arm.com            numUnpredictableResults[i];
30110259SAndrew.Bardsley@arm.com
30210259SAndrew.Bardsley@arm.com        if (!(num_results == 0 && num_unpredictable_results == Cycles(0))) {
30310259SAndrew.Bardsley@arm.com            if (printed_element)
30410259SAndrew.Bardsley@arm.com                result_stream << ',';
30510259SAndrew.Bardsley@arm.com
30610259SAndrew.Bardsley@arm.com            result_stream << '(' << i << ','
30710259SAndrew.Bardsley@arm.com                 << num_results << '/'
30810259SAndrew.Bardsley@arm.com                 << num_unpredictable_results << '/'
30910259SAndrew.Bardsley@arm.com                 << returnCycle[i] << '/'
31010259SAndrew.Bardsley@arm.com                 << writingInst[i] << ')';
31110259SAndrew.Bardsley@arm.com
31210259SAndrew.Bardsley@arm.com            printed_element = true;
31310259SAndrew.Bardsley@arm.com        }
31410259SAndrew.Bardsley@arm.com
31510259SAndrew.Bardsley@arm.com        i++;
31610259SAndrew.Bardsley@arm.com    }
31710259SAndrew.Bardsley@arm.com
31810259SAndrew.Bardsley@arm.com    MINORTRACE("busy=%s\n", result_stream.str());
31910259SAndrew.Bardsley@arm.com}
32010259SAndrew.Bardsley@arm.com
32110259SAndrew.Bardsley@arm.com}
322