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 4011793Sbrandon.potter@amd.com#include "cpu/minor/func_unit.hh" 4111793Sbrandon.potter@amd.com 4210259SAndrew.Bardsley@arm.com#include <iomanip> 4310259SAndrew.Bardsley@arm.com#include <sstream> 4410259SAndrew.Bardsley@arm.com#include <typeinfo> 4510259SAndrew.Bardsley@arm.com 4610259SAndrew.Bardsley@arm.com#include "debug/MinorTiming.hh" 4710259SAndrew.Bardsley@arm.com#include "enums/OpClass.hh" 4810259SAndrew.Bardsley@arm.com 4910259SAndrew.Bardsley@arm.comMinorOpClass * 5010259SAndrew.Bardsley@arm.comMinorOpClassParams::create() 5110259SAndrew.Bardsley@arm.com{ 5210259SAndrew.Bardsley@arm.com return new MinorOpClass(this); 5310259SAndrew.Bardsley@arm.com} 5410259SAndrew.Bardsley@arm.com 5510259SAndrew.Bardsley@arm.comMinorOpClassSet * 5610259SAndrew.Bardsley@arm.comMinorOpClassSetParams::create() 5710259SAndrew.Bardsley@arm.com{ 5810259SAndrew.Bardsley@arm.com return new MinorOpClassSet(this); 5910259SAndrew.Bardsley@arm.com} 6010259SAndrew.Bardsley@arm.com 6110259SAndrew.Bardsley@arm.comMinorFUTiming * 6210259SAndrew.Bardsley@arm.comMinorFUTimingParams::create() 6310259SAndrew.Bardsley@arm.com{ 6410259SAndrew.Bardsley@arm.com return new MinorFUTiming(this); 6510259SAndrew.Bardsley@arm.com} 6610259SAndrew.Bardsley@arm.com 6710259SAndrew.Bardsley@arm.comMinorFU * 6810259SAndrew.Bardsley@arm.comMinorFUParams::create() 6910259SAndrew.Bardsley@arm.com{ 7010259SAndrew.Bardsley@arm.com return new MinorFU(this); 7110259SAndrew.Bardsley@arm.com} 7210259SAndrew.Bardsley@arm.com 7310259SAndrew.Bardsley@arm.comMinorFUPool * 7410259SAndrew.Bardsley@arm.comMinorFUPoolParams::create() 7510259SAndrew.Bardsley@arm.com{ 7610259SAndrew.Bardsley@arm.com return new MinorFUPool(this); 7710259SAndrew.Bardsley@arm.com} 7810259SAndrew.Bardsley@arm.com 7910259SAndrew.Bardsley@arm.comMinorOpClassSet::MinorOpClassSet(const MinorOpClassSetParams *params) : 8010259SAndrew.Bardsley@arm.com SimObject(params), 8110259SAndrew.Bardsley@arm.com opClasses(params->opClasses), 8210259SAndrew.Bardsley@arm.com /* Initialise to true for an empty list so that 'fully capable' is 8310259SAndrew.Bardsley@arm.com * the default */ 8410259SAndrew.Bardsley@arm.com capabilityList(Num_OpClasses, (opClasses.empty() ? true : false)) 8510259SAndrew.Bardsley@arm.com{ 8610259SAndrew.Bardsley@arm.com for (unsigned int i = 0; i < opClasses.size(); i++) 8710259SAndrew.Bardsley@arm.com capabilityList[opClasses[i]->opClass] = true; 8810259SAndrew.Bardsley@arm.com} 8910259SAndrew.Bardsley@arm.com 9010259SAndrew.Bardsley@arm.comMinorFUTiming::MinorFUTiming( 9110259SAndrew.Bardsley@arm.com const MinorFUTimingParams *params) : 9210259SAndrew.Bardsley@arm.com SimObject(params), 9310259SAndrew.Bardsley@arm.com mask(params->mask), 9410259SAndrew.Bardsley@arm.com match(params->match), 9510259SAndrew.Bardsley@arm.com description(params->description), 9610259SAndrew.Bardsley@arm.com suppress(params->suppress), 9710259SAndrew.Bardsley@arm.com extraCommitLat(params->extraCommitLat), 9810259SAndrew.Bardsley@arm.com extraCommitLatExpr(params->extraCommitLatExpr), 9910259SAndrew.Bardsley@arm.com extraAssumedLat(params->extraAssumedLat), 10010259SAndrew.Bardsley@arm.com srcRegsRelativeLats(params->srcRegsRelativeLats), 10110259SAndrew.Bardsley@arm.com opClasses(params->opClasses) 10210259SAndrew.Bardsley@arm.com{ } 10310259SAndrew.Bardsley@arm.com 10410259SAndrew.Bardsley@arm.comnamespace Minor 10510259SAndrew.Bardsley@arm.com{ 10610259SAndrew.Bardsley@arm.com 10710259SAndrew.Bardsley@arm.comvoid 10810259SAndrew.Bardsley@arm.comQueuedInst::reportData(std::ostream &os) const 10910259SAndrew.Bardsley@arm.com{ 11010259SAndrew.Bardsley@arm.com inst->reportData(os); 11110259SAndrew.Bardsley@arm.com} 11210259SAndrew.Bardsley@arm.com 11310259SAndrew.Bardsley@arm.comFUPipeline::FUPipeline(const std::string &name, const MinorFU &description_, 11410259SAndrew.Bardsley@arm.com ClockedObject &timeSource_) : 11510259SAndrew.Bardsley@arm.com FUPipelineBase(name, "insts", description_.opLat), 11610259SAndrew.Bardsley@arm.com description(description_), 11710259SAndrew.Bardsley@arm.com timeSource(timeSource_), 11810259SAndrew.Bardsley@arm.com nextInsertCycle(Cycles(0)) 11910259SAndrew.Bardsley@arm.com{ 12010259SAndrew.Bardsley@arm.com /* Issue latencies are set to 1 in calls to addCapability here. 12110259SAndrew.Bardsley@arm.com * Issue latencies are associated with the pipeline as a whole, 12210259SAndrew.Bardsley@arm.com * rather than instruction classes in Minor */ 12310259SAndrew.Bardsley@arm.com 12410259SAndrew.Bardsley@arm.com /* All pipelines should be able to execute No_OpClass instructions */ 12510259SAndrew.Bardsley@arm.com addCapability(No_OpClass, description.opLat, 1); 12610259SAndrew.Bardsley@arm.com 12710259SAndrew.Bardsley@arm.com /* Add the capabilities listed in the MinorFU for this functional unit */ 12810259SAndrew.Bardsley@arm.com for (unsigned int i = 0; i < description.opClasses->opClasses.size(); 12910259SAndrew.Bardsley@arm.com i++) 13010259SAndrew.Bardsley@arm.com { 13110259SAndrew.Bardsley@arm.com addCapability(description.opClasses->opClasses[i]->opClass, 13210259SAndrew.Bardsley@arm.com description.opLat, 1); 13310259SAndrew.Bardsley@arm.com } 13410259SAndrew.Bardsley@arm.com 13510259SAndrew.Bardsley@arm.com for (unsigned int i = 0; i < description.timings.size(); i++) { 13610259SAndrew.Bardsley@arm.com MinorFUTiming &timing = *(description.timings[i]); 13710259SAndrew.Bardsley@arm.com 13810259SAndrew.Bardsley@arm.com if (DTRACE(MinorTiming)) { 13910259SAndrew.Bardsley@arm.com std::ostringstream lats; 14010259SAndrew.Bardsley@arm.com 14110259SAndrew.Bardsley@arm.com unsigned int num_lats = timing.srcRegsRelativeLats.size(); 14210259SAndrew.Bardsley@arm.com unsigned int j = 0; 14310259SAndrew.Bardsley@arm.com while (j < num_lats) { 14410259SAndrew.Bardsley@arm.com lats << timing.srcRegsRelativeLats[j]; 14510259SAndrew.Bardsley@arm.com 14610259SAndrew.Bardsley@arm.com j++; 14710259SAndrew.Bardsley@arm.com if (j != num_lats) 14810259SAndrew.Bardsley@arm.com lats << ','; 14910259SAndrew.Bardsley@arm.com } 15010259SAndrew.Bardsley@arm.com 15110259SAndrew.Bardsley@arm.com DPRINTFS(MinorTiming, static_cast<Named *>(this), 15210259SAndrew.Bardsley@arm.com "Adding extra timing decode pattern %d to FU" 15310259SAndrew.Bardsley@arm.com " mask: %016x match: %016x srcRegLatencies: %s\n", 15410259SAndrew.Bardsley@arm.com i, timing.mask, timing.match, lats.str()); 15510259SAndrew.Bardsley@arm.com } 15610259SAndrew.Bardsley@arm.com } 15710259SAndrew.Bardsley@arm.com 15810259SAndrew.Bardsley@arm.com const std::vector<unsigned> &cant_forward = 15910259SAndrew.Bardsley@arm.com description.cantForwardFromFUIndices; 16010259SAndrew.Bardsley@arm.com 16110259SAndrew.Bardsley@arm.com /* Setup the bit vector cantForward... with the set indices 16210259SAndrew.Bardsley@arm.com * specified in the parameters */ 16310259SAndrew.Bardsley@arm.com for (auto i = cant_forward.begin(); i != cant_forward.end(); ++i) { 16410259SAndrew.Bardsley@arm.com cantForwardFromFUIndices.resize((*i) + 1, false); 16510259SAndrew.Bardsley@arm.com cantForwardFromFUIndices[*i] = true; 16610259SAndrew.Bardsley@arm.com } 16710259SAndrew.Bardsley@arm.com} 16810259SAndrew.Bardsley@arm.com 16910259SAndrew.Bardsley@arm.comCycles 17010259SAndrew.Bardsley@arm.comFUPipeline::cyclesBeforeInsert() 17110259SAndrew.Bardsley@arm.com{ 17210259SAndrew.Bardsley@arm.com if (nextInsertCycle == 0 || timeSource.curCycle() > nextInsertCycle) 17310259SAndrew.Bardsley@arm.com return Cycles(0); 17410259SAndrew.Bardsley@arm.com else 17510259SAndrew.Bardsley@arm.com return nextInsertCycle - timeSource.curCycle(); 17610259SAndrew.Bardsley@arm.com} 17710259SAndrew.Bardsley@arm.com 17810259SAndrew.Bardsley@arm.combool 17910259SAndrew.Bardsley@arm.comFUPipeline::canInsert() const 18010259SAndrew.Bardsley@arm.com{ 18110259SAndrew.Bardsley@arm.com return nextInsertCycle == 0 || timeSource.curCycle() >= nextInsertCycle; 18210259SAndrew.Bardsley@arm.com} 18310259SAndrew.Bardsley@arm.com 18410259SAndrew.Bardsley@arm.comvoid 18510259SAndrew.Bardsley@arm.comFUPipeline::advance() 18610259SAndrew.Bardsley@arm.com{ 18710259SAndrew.Bardsley@arm.com bool was_stalled = stalled; 18810259SAndrew.Bardsley@arm.com 18910259SAndrew.Bardsley@arm.com /* If an instruction was pushed into the pipeline, set the delay before 19010259SAndrew.Bardsley@arm.com * the next instruction can follow */ 19110259SAndrew.Bardsley@arm.com if (alreadyPushed()) { 19210259SAndrew.Bardsley@arm.com if (nextInsertCycle <= timeSource.curCycle()) { 19310259SAndrew.Bardsley@arm.com nextInsertCycle = timeSource.curCycle() + description.issueLat; 19410259SAndrew.Bardsley@arm.com } 19510259SAndrew.Bardsley@arm.com } else if (was_stalled && nextInsertCycle != 0) { 19610259SAndrew.Bardsley@arm.com /* Don't count stalled cycles as part of the issue latency */ 19710259SAndrew.Bardsley@arm.com ++nextInsertCycle; 19810259SAndrew.Bardsley@arm.com } 19910259SAndrew.Bardsley@arm.com FUPipelineBase::advance(); 20010259SAndrew.Bardsley@arm.com} 20110259SAndrew.Bardsley@arm.com 20210259SAndrew.Bardsley@arm.comMinorFUTiming * 20310417Sandreas.hansson@arm.comFUPipeline::findTiming(const StaticInstPtr &inst) 20410259SAndrew.Bardsley@arm.com{ 20510259SAndrew.Bardsley@arm.com#if THE_ISA == ARM_ISA 20610259SAndrew.Bardsley@arm.com /* This should work for any ISA with a POD mach_inst */ 20710259SAndrew.Bardsley@arm.com TheISA::ExtMachInst mach_inst = inst->machInst; 20810259SAndrew.Bardsley@arm.com#else 20910259SAndrew.Bardsley@arm.com /* Just allow extra decode based on op classes */ 21010259SAndrew.Bardsley@arm.com uint64_t mach_inst = 0; 21110259SAndrew.Bardsley@arm.com#endif 21210259SAndrew.Bardsley@arm.com 21310259SAndrew.Bardsley@arm.com const std::vector<MinorFUTiming *> &timings = 21410259SAndrew.Bardsley@arm.com description.timings; 21510259SAndrew.Bardsley@arm.com unsigned int num_timings = timings.size(); 21610259SAndrew.Bardsley@arm.com 21710259SAndrew.Bardsley@arm.com for (unsigned int i = 0; i < num_timings; i++) { 21810259SAndrew.Bardsley@arm.com MinorFUTiming &timing = *timings[i]; 21910259SAndrew.Bardsley@arm.com 22010259SAndrew.Bardsley@arm.com if (timing.provides(inst->opClass()) && 22110259SAndrew.Bardsley@arm.com (mach_inst & timing.mask) == timing.match) 22210259SAndrew.Bardsley@arm.com { 22310259SAndrew.Bardsley@arm.com DPRINTFS(MinorTiming, static_cast<Named *>(this), 22410259SAndrew.Bardsley@arm.com "Found extra timing match (pattern %d '%s')" 22510259SAndrew.Bardsley@arm.com " %s %16x (type %s)\n", 22610259SAndrew.Bardsley@arm.com i, timing.description, inst->disassemble(0), mach_inst, 22711169Sandreas.hansson@arm.com typeid(inst).name()); 22810259SAndrew.Bardsley@arm.com 22910259SAndrew.Bardsley@arm.com return &timing; 23010259SAndrew.Bardsley@arm.com } 23110259SAndrew.Bardsley@arm.com } 23210259SAndrew.Bardsley@arm.com 23310259SAndrew.Bardsley@arm.com if (num_timings != 0) { 23410259SAndrew.Bardsley@arm.com DPRINTFS(MinorTiming, static_cast<Named *>(this), 23510259SAndrew.Bardsley@arm.com "No extra timing info. found for inst: %s" 23610259SAndrew.Bardsley@arm.com " mach_inst: %16x\n", 23710259SAndrew.Bardsley@arm.com inst->disassemble(0), mach_inst); 23810259SAndrew.Bardsley@arm.com } 23910259SAndrew.Bardsley@arm.com 24010259SAndrew.Bardsley@arm.com return NULL; 24110259SAndrew.Bardsley@arm.com} 24210259SAndrew.Bardsley@arm.com 24310259SAndrew.Bardsley@arm.com} 244