LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/ccu/ccu_microcode - ccu_microcode_v2.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.3 % 235 231
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 29 29

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include <unordered_map>
      12              : 
      13              : #include "string_util.h"
      14              : #include "ccu_microcode.h"
      15              : 
      16              : namespace {
      17              : constexpr uint16_t LOAD_TYPE = 0x0;
      18              : 
      19              : constexpr uint16_t LOADSQEARGSTOX_CODE = 0x1;
      20              : constexpr uint16_t LOADIMDTOX_CODE = 0x2;
      21              : constexpr uint16_t LOADX_CODE = 0x6;
      22              : constexpr uint16_t STOREX_CODE = 0x7;
      23              : constexpr uint16_t CLEARX_CODE = 0x8;
      24              : constexpr uint16_t NOP_CODE = 0x9;
      25              : constexpr uint16_t LOAD_CODE = 0xA;
      26              : constexpr uint16_t STORE_CODE = 0xB;
      27              : constexpr uint16_t ADD_CODE = 0xD;
      28              : constexpr uint16_t SUB_CODE = 0xE;
      29              : constexpr uint16_t MUL_CODE = 0xF;
      30              : constexpr uint16_t AND_CODE = 0x10;
      31              : constexpr uint16_t OR_CODE = 0x11;
      32              : constexpr uint16_t NOT_CODE = 0x12;
      33              : constexpr uint16_t XOR_CODE = 0x13;
      34              : constexpr uint16_t SHL_CODE = 0x14;
      35              : constexpr uint16_t SHR_CODE = 0x15;
      36              : constexpr uint16_t POPCNT_CODE = 0x16;
      37              : 
      38              : constexpr uint16_t CTRL_TYPE = 0x1;
      39              : 
      40              : constexpr uint16_t LOOP_CODE = 0x0;
      41              : constexpr uint16_t LOOPGROUP_CODE = 0x1;
      42              : constexpr uint16_t SETCKBIT_CODE = 0x2;
      43              : constexpr uint16_t CLEARCKBIT_CODE = 0x4;
      44              : constexpr uint16_t JMP_CODE = 0x5;
      45              : constexpr uint16_t WAIT_CODE = 0x7;
      46              : constexpr uint16_t FENCE_CODE = 0x8;
      47              : 
      48              : constexpr uint16_t TRANS_TYPE = 0x2;
      49              : 
      50              : constexpr uint16_t TRANSLOCMEMTOLOCMS_CODE = 0x0;
      51              : constexpr uint16_t TRANSLOCMSTOLOCMEM_CODE = 0x2;
      52              : constexpr uint16_t TRANSLOCMSTOLOCMS_CODE = 0x5;
      53              : constexpr uint16_t TRANSLOCMEMTOLOCMEM_CODE = 0x6;
      54              : constexpr uint16_t TRANSMEM_CODE = 0x10;
      55              : constexpr uint16_t SYNCWTX_CODE = 0xD;
      56              : constexpr uint16_t SYNCATX_CODE = 0xE;
      57              : 
      58              : constexpr uint16_t REDUCE_TYPE = 0x3;
      59              : 
      60              : constexpr uint16_t REDUCE_ADD_CODE = 0x0;
      61              : constexpr uint16_t REDUCE_MAX_CODE = 0x1;
      62              : constexpr uint16_t REDUCE_MIN_CODE = 0x2;
      63              : } // namespace
      64              : 
      65              : namespace Hccl {
      66              : namespace CcuRep {
      67              :     namespace CcuV2 {
      68              :         // *XnId = *sqeArgsId
      69            1 :         void LoadSqeArgsToX(CcuInstr* instr, uint16_t xnId, uint16_t sqeArgsId, uint16_t setCKEId, uint16_t setCKEMask)
      70              :         {
      71            1 :             instr->header = InstrHeader(LOAD_TYPE, LOADSQEARGSTOX_CODE);
      72            1 :             instr->v2.loadSqeArgsToX.xnId = xnId;
      73            1 :             instr->v2.loadSqeArgsToX.sqeArgsId = sqeArgsId;
      74            1 :             instr->v2.loadSqeArgsToX.setCKEId = setCKEId;
      75            1 :             instr->v2.loadSqeArgsToX.setCKEMask = setCKEMask;
      76            1 :         }
      77              : 
      78              :         // *XnId = immediate
      79            1 :         void LoadImdToXn(CcuInstr* instr, uint16_t xnId, uint64_t immediate, uint16_t setCKEId, uint16_t setCKEMask)
      80              :         {
      81            1 :             instr->header = InstrHeader(LOAD_TYPE, LOADIMDTOX_CODE);
      82            1 :             instr->v2.loadImdToX.xnId = xnId;
      83            1 :             instr->v2.loadImdToX.immediate = immediate;
      84            1 :             instr->v2.loadImdToX.setCKEId = setCKEId;
      85            1 :             instr->v2.loadImdToX.setCKEMask = setCKEMask;
      86            1 :         }
      87              : 
      88            1 :         void Nop(CcuInstr* instr) { instr->header = InstrHeader(LOAD_TYPE, NOP_CODE); }
      89              : 
      90              :         inline void
      91            5 :         Operator(CcuInstr* instr, uint16_t xdId, uint16_t xnId, uint16_t xmId, uint16_t setCKEId, uint16_t setCKEMask)
      92              :         {
      93            5 :             instr->v2.operate.xdId = xdId;
      94            5 :             instr->v2.operate.xnId = xnId;
      95            5 :             instr->v2.operate.xmId = xmId;
      96            5 :             instr->v2.operate.setCKEId = setCKEId;
      97            5 :             instr->v2.operate.setCKEMask = setCKEMask;
      98            5 :         }
      99              : 
     100            1 :         void Assign(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t setCKEId, uint16_t setCKEMask)
     101              :         {
     102            1 :             AddI(instr, result, operand, 0, setCKEId, setCKEMask);
     103            1 :         }
     104              : 
     105              :         void
     106            1 :         Add(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
     107              :             uint16_t setCKEMask)
     108              :         {
     109            1 :             instr->header = InstrHeader(LOAD_TYPE, ADD_CODE);
     110            1 :             instr->v2.operate.parMode = 1;
     111            1 :             Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
     112            1 :         }
     113              : 
     114              :         void
     115            2 :         AddI(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t imm, uint16_t setCKEId, uint16_t setCKEMask)
     116              :         {
     117            2 :             instr->header = InstrHeader(LOAD_TYPE, ADD_CODE);
     118            2 :             instr->v2.operate.parMode = 0;
     119            2 :             Operator(instr, result, operand, imm, setCKEId, setCKEMask);
     120            2 :         }
     121              : 
     122              :         void
     123            1 :         Mul(CcuInstr* instr, uint16_t result, uint16_t operand1, uint16_t operand2, uint16_t setCKEId,
     124              :             uint16_t setCKEMask)
     125              :         {
     126            1 :             instr->header = InstrHeader(LOAD_TYPE, MUL_CODE);
     127            1 :             instr->v2.operate.parMode = 1;
     128            1 :             Operator(instr, result, operand1, operand2, setCKEId, setCKEMask);
     129            1 :         }
     130              : 
     131              :         void
     132            1 :         MulI(CcuInstr* instr, uint16_t result, uint16_t operand, uint16_t imm, uint16_t setCKEId, uint16_t setCKEMask)
     133              :         {
     134            1 :             instr->header = InstrHeader(LOAD_TYPE, MUL_CODE);
     135            1 :             instr->v2.operate.parMode = 0;
     136            1 :             Operator(instr, result, operand, imm, setCKEId, setCKEMask);
     137            1 :         }
     138              : 
     139              :         // LoadChannel、LoadInstruction暂不实现
     140              : 
     141            1 :         void LoadFromMem(
     142              :             CcuInstr* instr, uint16_t dst, uint16_t src, uint16_t srcToken, uint16_t len,
     143              :             const CacheConfig& cacheConfig, uint16_t setCKEId, uint16_t setCKEMask)
     144              :         {
     145            1 :             instr->header = InstrHeader(LOAD_TYPE, LOAD_CODE);
     146            1 :             instr->v2.load.xdId = dst;
     147            1 :             instr->v2.load.xsId = src;
     148            1 :             instr->v2.load.xstId = srcToken;
     149            1 :             instr->v2.load.xlId = len;
     150              : 
     151            1 :             instr->v2.load.allocHint = cacheConfig.allocHint & 0x3;
     152            1 :             instr->v2.load.victimHint = cacheConfig.victimHint & 0x3;
     153              : 
     154            1 :             instr->v2.load.setCKEId = setCKEId;
     155            1 :             instr->v2.load.setCKEMask = setCKEMask;
     156            1 :         }
     157              : 
     158            1 :         void LoadXFromMem(
     159              :             CcuInstr* instr, uint16_t dst, uint16_t src, uint16_t srcToken, uint16_t len,
     160              :             const CacheConfig& cacheConfig, uint16_t setCKEId, uint16_t setCKEMask)
     161              :         {
     162            1 :             if (instr == nullptr) {
     163            0 :                 HCCL_ERROR("[CcuV2::LoadXFromMem] instr is nullptr!");
     164            0 :                 return;
     165              :             }
     166            1 :             LoadFromMem(instr, dst, src, srcToken, len, cacheConfig, setCKEId, setCKEMask);
     167            1 :             instr->v2.load.dstType = 0x0;
     168              :         }
     169              : 
     170              :         // HSCB Store暂不实现
     171              : 
     172            1 :         void StoreXToMem(
     173              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t src, uint16_t len,
     174              :             const CacheConfig& cacheConfig, uint16_t setCKEId, uint16_t setCKEMask)
     175              :         {
     176            1 :             instr->header = InstrHeader(LOAD_TYPE, STORE_CODE);
     177            1 :             instr->v2.store.xdId = dst;
     178            1 :             instr->v2.store.xdtId = dstToken;
     179            1 :             instr->v2.store.xsId = src;
     180            1 :             instr->v2.store.xlId = len;
     181              : 
     182            1 :             instr->v2.store.srcType = 0x0;
     183              : 
     184            1 :             instr->v2.store.allocHint = cacheConfig.allocHint & 0x3;
     185            1 :             instr->v2.store.victimHint = cacheConfig.victimHint & 0x3;
     186              : 
     187            1 :             instr->v2.store.setCKEId = setCKEId;
     188            1 :             instr->v2.store.setCKEMask = setCKEMask;
     189            1 :         }
     190              : 
     191              :         // startInstrId ~ endInstrId之间的指令构成loop
     192              :         // Xm寄存器中的内容:LoopCtxId[52:45], Offset[44:13], IterNum[12:0]
     193              :         // IterNum[12:0] loop执行IterNum次 loop每次执行, 地址偏移为Offset loop在第LoopCtxId个LoopEngine上执行
     194            1 :         void Loop(
     195              :             CcuInstr* instr, uint16_t startInstrId, uint16_t endInstrId, uint16_t iterNum, uint16_t offset,
     196              :             uint16_t contextId)
     197              :         {
     198            1 :             instr->header = InstrHeader(CTRL_TYPE, LOOP_CODE);
     199            1 :             instr->v2.loop.startInstrId = startInstrId;
     200            1 :             instr->v2.loop.endInstrId = endInstrId;
     201            1 :             instr->v2.loop.xmId = iterNum;
     202            1 :             instr->v2.loop.xnId = offset;
     203            1 :             instr->v2.loop.xpId = contextId;
     204            1 :             instr->v2.loop.mode = 0;
     205            1 :             instr->v2.loop.wishCKEBit = 0;
     206            1 :         }
     207              : 
     208              :         // startLoopInstrId为LoopGroup所包含的Loop的起始地址
     209              :         // Xn寄存器中的内容:ExtendNum[22:16], RepeatLoopIndex[15:9], LoopNum[8:0]
     210              :         // Xm寄存器中的内容:gsaOffset[52:21], MSOffset[20:10], ckeOffset[9:0]
     211              :         // xnOffset[52:21], xnOffset[31:0]
     212              :         // 从startLoopInstrId开始,共LoopNum个Loop,并且从RepeatLoopIndex个开始,展开ExtendNum次
     213              :         // 每个展开的Loop,使用的MSId偏移为msOffset,使用的CKEId偏移为ckeOffset,使用的地址偏移为gsaOffset,
     214              :         // 使用的XnId偏移为xnOffset
     215            1 :         void LoopGroup(
     216              :             CcuInstr* instr, uint16_t startLoopInstrId, uint16_t loopGroupConfig, uint16_t resOffset, uint16_t xnOffset)
     217              :         {
     218            1 :             instr->header = InstrHeader(CTRL_TYPE, LOOPGROUP_CODE);
     219            1 :             instr->v2.loopGroup.startLoopInstrId = startLoopInstrId;
     220            1 :             instr->v2.loopGroup.xnId = loopGroupConfig;
     221            1 :             instr->v2.loopGroup.xmId = resOffset;
     222            1 :             instr->v2.loopGroup.xpId = xnOffset;
     223            1 :         }
     224              : 
     225              :         // 后续函数中, 均需要wait到<waitCKEId, waitCKEMask>后, 再执行相关操作, 执行完之后再set<setCKEId, setCKEMask>
     226              :         // clearType = 1时, wait到之后需要对<waitCKEId, waitCKEMask>清零, 否则不清零
     227              : 
     228            1 :         void SetCKE(
     229              :             CcuInstr* instr, uint16_t setCKEId, uint16_t setCKEMask, uint16_t waitCKEId, uint16_t waitCKEMask,
     230              :             uint16_t clearType)
     231              :         {
     232            1 :             instr->header = InstrHeader(CTRL_TYPE, SETCKBIT_CODE);
     233            1 :             instr->v2.setCKE.clearType = clearType & 0x1;
     234            1 :             instr->v2.setCKE.setCKEId = setCKEId;
     235            1 :             instr->v2.setCKE.setCKEMask = setCKEMask;
     236            1 :             instr->v2.setCKE.waitCKEId = waitCKEId;
     237            1 :             instr->v2.setCKE.waitCKEMask = waitCKEMask;
     238            1 :         }
     239              : 
     240            1 :         void ClearCKE(
     241              :             CcuInstr* instr, uint16_t clearCKEId, uint16_t clearMask, uint16_t waitCKEId, uint16_t waitCKEMask,
     242              :             uint16_t clearType)
     243              :         {
     244            1 :             instr->header = InstrHeader(CTRL_TYPE, CLEARCKBIT_CODE);
     245            1 :             instr->v2.clearCKE.clearType = clearType & 0x1;
     246            1 :             instr->v2.clearCKE.clearCKEId = clearCKEId;
     247            1 :             instr->v2.clearCKE.clearMask = clearMask;
     248            1 :             instr->v2.clearCKE.waitCKEId = waitCKEId;
     249            1 :             instr->v2.clearCKE.waitCKEMask = waitCKEMask;
     250            1 :         }
     251              : 
     252            1 :         void Jump(
     253              :             CcuInstr* instr, uint16_t relTarInstrXnId, uint16_t conditionXnId, uint16_t expectedXnId,
     254              :             uint16_t conditionType)
     255              :         {
     256            1 :             instr->header = InstrHeader(CTRL_TYPE, JMP_CODE);
     257            1 :             instr->v2.jmp.expectedXnId = expectedXnId;
     258            1 :             instr->v2.jmp.conditionXnId = conditionXnId;
     259            1 :             instr->v2.jmp.relTarInstrXnId = relTarInstrXnId;
     260            1 :             instr->v2.jmp.conditionType = conditionType & 0xF;
     261            1 :         }
     262              : 
     263              :         // Wait暂不实现
     264              :         // Fence暂不实现
     265              : 
     266              :         // 本端Memory传输到本端MS
     267            1 :         void TransLocMemToLocMS(
     268              :             CcuInstr* instr, uint16_t ms, uint16_t src, uint16_t srcToken, uint16_t len, uint16_t offset,
     269              :             uint16_t setCKEId, uint16_t setCKEMask, const CacheConfig& cacheConfig)
     270              :         {
     271            1 :             instr->header = InstrHeader(TRANS_TYPE, TRANSLOCMEMTOLOCMS_CODE);
     272            1 :             instr->v2.transLocMemToLocMS.msId = ms;
     273            1 :             instr->v2.transLocMemToLocMS.xsId = src;
     274            1 :             instr->v2.transLocMemToLocMS.xstId = srcToken;
     275            1 :             instr->v2.transLocMemToLocMS.xlId = len;
     276            1 :             instr->v2.transLocMemToLocMS.xoId = offset;
     277            1 :             instr->v2.transLocMemToLocMS.allocHint = cacheConfig.allocHint & 0x3;
     278            1 :             instr->v2.transLocMemToLocMS.victimHint = cacheConfig.victimHint & 0x3;
     279            1 :             instr->v2.transLocMemToLocMS.setCKEId = setCKEId;
     280            1 :             instr->v2.transLocMemToLocMS.setCKEMask = setCKEMask;
     281            1 :         }
     282              : 
     283              :         // 本端MS传输到本端Memory
     284            1 :         void TransLocMSToLocMem(
     285              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t ms, uint16_t len, uint16_t offset,
     286              :             uint16_t setCKEId, uint16_t setCKEMask, const CacheConfig& cacheConfig)
     287              :         {
     288            1 :             instr->header = InstrHeader(TRANS_TYPE, TRANSLOCMSTOLOCMEM_CODE);
     289            1 :             instr->v2.transLocMSToLocMem.xdId = dst;
     290            1 :             instr->v2.transLocMSToLocMem.xdtId = dstToken;
     291            1 :             instr->v2.transLocMSToLocMem.msId = ms;
     292            1 :             instr->v2.transLocMSToLocMem.xlId = len;
     293            1 :             instr->v2.transLocMSToLocMem.xoId = offset;
     294            1 :             instr->v2.transLocMSToLocMem.allocHint = cacheConfig.allocHint & 0x3;
     295            1 :             instr->v2.transLocMSToLocMem.victimHint = cacheConfig.victimHint & 0x3;
     296            1 :             instr->v2.transLocMSToLocMem.setCKEId = setCKEId;
     297            1 :             instr->v2.transLocMSToLocMem.setCKEMask = setCKEMask;
     298            1 :         }
     299              : 
     300            1 :         void TransLocMemToLocMem(
     301              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t src, uint16_t srcToken, uint16_t len,
     302              :             uint16_t usedMSId, uint16_t setCKEId, uint16_t setCKEMask, const CacheConfig& srcCacheConfig,
     303              :             const CacheConfig& dstcacheConfig)
     304              :         {
     305            1 :             instr->header = InstrHeader(TRANS_TYPE, TRANSLOCMEMTOLOCMEM_CODE);
     306            1 :             instr->v2.transLocMemToLocMem.xdId = dst;
     307            1 :             instr->v2.transLocMemToLocMem.xdtId = dstToken;
     308            1 :             instr->v2.transLocMemToLocMem.xsId = src;
     309            1 :             instr->v2.transLocMemToLocMem.xstId = srcToken;
     310            1 :             instr->v2.transLocMemToLocMem.xlId = len;
     311            1 :             instr->v2.transLocMemToLocMem.usedMSId = usedMSId;
     312            1 :             instr->v2.transLocMemToLocMem.msNum = CCU_MS_INTERLEAVE;
     313              : 
     314            1 :             instr->v2.transLocMemToLocMem.srcAllocHint = srcCacheConfig.allocHint & 0x3;
     315            1 :             instr->v2.transLocMemToLocMem.srcVictimHint = srcCacheConfig.victimHint & 0x3;
     316            1 :             instr->v2.transLocMemToLocMem.dstAllocHint = dstcacheConfig.allocHint & 0x3;
     317            1 :             instr->v2.transLocMemToLocMem.dstVictimHint = dstcacheConfig.victimHint & 0x3;
     318              : 
     319            1 :             instr->v2.transLocMemToLocMem.setCKEId = setCKEId;
     320            1 :             instr->v2.transLocMemToLocMem.setCKEMask = setCKEMask;
     321            1 :         }
     322              : 
     323            1 :         void TransMem(
     324              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t src, uint16_t srcToken, uint16_t len,
     325              :             uint16_t channel, const TransMemNotifyInfo& notify, const TransMemReduceInfo& reduce,
     326              :             const TransMemConfig& config, uint16_t setCKEId, uint16_t setCKEMask)
     327              :         {
     328            1 :             instr->header = InstrHeader(TRANS_TYPE, TRANSMEM_CODE);
     329            1 :             instr->v2.transMem.xdId = dst;
     330            1 :             instr->v2.transMem.xdtId = dstToken;
     331            1 :             instr->v2.transMem.xsId = src;
     332            1 :             instr->v2.transMem.xstId = srcToken;
     333            1 :             instr->v2.transMem.xlId = len;
     334            1 :             instr->v2.transMem.xcId = channel;
     335            1 :             instr->v2.transMem.xnId = notify.xnId;
     336            1 :             instr->v2.transMem.xntId = notify.xntId;
     337            1 :             instr->v2.transMem.value = notify.value;
     338            1 :             instr->v2.transMem.udfType = reduce.udfType & 0xFF;
     339            1 :             instr->v2.transMem.reduceDataType = reduce.reduceDataType & 0xF;
     340            1 :             instr->v2.transMem.reduceOpCode = reduce.reduceOpCode & 0xF;
     341              : 
     342            1 :             instr->v2.transMem.order = config.order & 0x7;
     343            1 :             instr->v2.transMem.fence = config.fence & 0x1;
     344            1 :             instr->v2.transMem.cqe = config.cqe & 0x1;
     345            1 :             instr->v2.transMem.nf = config.nf & 0x1;
     346            1 :             instr->v2.transMem.udfEnable = config.udfEnable & 0x1;
     347            1 :             instr->v2.transMem.splitMode = config.splitMode & 0x1;
     348            1 :             instr->v2.transMem.se = config.se & 0x1;
     349            1 :             instr->v2.transMem.rmtJettyType = config.rmtJettyType & 0x3;
     350              : 
     351            1 :             instr->v2.transMem.setCKEId = setCKEId;
     352            1 :             instr->v2.transMem.setCKEMask = setCKEMask;
     353            1 :         }
     354              : 
     355              :         // 将本端Xn的值写入远端8B地址
     356            3 :         inline void SyncWtX(
     357              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t xn, uint16_t channelId, uint16_t setCKEId,
     358              :             uint16_t setCKEMask)
     359              :         {
     360            3 :             instr->header = InstrHeader(TRANS_TYPE, SYNCWTX_CODE);
     361            3 :             instr->v2.syncWtX.xdId = dst;
     362            3 :             instr->v2.syncWtX.xdtId = dstToken;
     363            3 :             instr->v2.syncWtX.xsId = xn;
     364            3 :             instr->v2.syncWtX.xcId = channelId;
     365              : 
     366            3 :             instr->v2.syncWtX.setCKEId = setCKEId;
     367            3 :             instr->v2.syncWtX.setCKEMask = setCKEMask;
     368            3 :         }
     369              : 
     370              :         // 将本端Xn的值写入远端8B地址并置位远端CKE
     371            1 :         void SyncWtX(
     372              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t xn, uint16_t channelId,
     373              :             const TransMemNotifyInfo& notify, uint16_t setCKEId, uint16_t setCKEMask)
     374              :         {
     375            1 :             SyncWtX(instr, dst, dstToken, xn, channelId, setCKEId, setCKEMask);
     376            1 :             instr->v2.syncWtX.xnId = notify.xnId;
     377            1 :             instr->v2.syncWtX.xntId = notify.xntId;
     378            1 :             instr->v2.syncWtX.value = notify.value;
     379              : 
     380            1 :             instr->v2.syncWtX.notifyValid = 1;
     381            1 :             instr->v2.syncWtX.parMode = 1;
     382            1 :         }
     383              : 
     384              :         // 置位远端CKE
     385            1 :         void SyncWtX(
     386              :             CcuInstr* instr, const TransMemNotifyInfo& notify, uint16_t channelId, uint16_t setCKEId,
     387              :             uint16_t setCKEMask)
     388              :         {
     389            1 :             SyncWtX(instr, notify.xnId, notify.xntId, notify.value, channelId, setCKEId, setCKEMask);
     390              : 
     391            1 :             instr->v2.syncWtX.notifyValid = 0;
     392            1 :             instr->v2.syncWtX.parMode = 0;
     393            1 :         }
     394              : 
     395              :         // 将本端Xn的值以atomic store add的方式写入远端8B地址
     396            1 :         void SyncAtX(
     397              :             CcuInstr* instr, uint16_t dst, uint16_t dstToken, uint16_t mask, uint16_t channelId, uint16_t setCKEId,
     398              :             uint16_t setCKEMask)
     399              :         {
     400            1 :             instr->header = InstrHeader(TRANS_TYPE, SYNCATX_CODE);
     401            1 :             instr->v2.syncAtX.xdId = dst;
     402            1 :             instr->v2.syncAtX.xdtId = dstToken;
     403            1 :             instr->v2.syncAtX.xsId = mask;
     404            1 :             instr->v2.syncAtX.xcId = channelId;
     405              : 
     406            1 :             instr->v2.syncAtX.parMode = 1;
     407              : 
     408            1 :             instr->v2.syncAtX.setCKEId = setCKEId;
     409            1 :             instr->v2.syncAtX.setCKEMask = setCKEMask;
     410            1 :         }
     411              : 
     412              :         // MSA~MSH Reduce到 MSA
     413            3 :         inline void Reduce(
     414              :             CcuInstr* instr, uint16_t* ms, uint16_t count, uint16_t castEn, uint16_t dataType, uint16_t setCKEId,
     415              :             uint16_t setCKEMask)
     416              :         {
     417              :             // 由调用者保证传入的count >= 2(reduce的数据源)
     418            3 :             count -= 2; // CCU指令中指定count数为实际参与运算的MS数减2
     419              : 
     420           27 :             for (uint16_t index = 0; index < CCU_REDUCE_MAX_MS; index++) {
     421           24 :                 instr->v2.reduce.msId[index] = ms[index];
     422              :             }
     423            3 :             instr->v2.reduce.count = count & 0x7;
     424            3 :             instr->v2.reduce.castEn = castEn & 0x3;
     425            3 :             instr->v2.reduce.dataType = dataType & 0x1f;
     426            3 :             instr->v2.reduce.setCKEId = setCKEId;
     427            3 :             instr->v2.reduce.setCKEMask = setCKEMask;
     428            3 :         }
     429              : 
     430            1 :         void ReduceAdd(
     431              :             CcuInstr* instr, uint16_t* ms, uint16_t count, uint16_t castEn, uint16_t dataType, uint16_t setCKEId,
     432              :             uint16_t setCKEMask)
     433              :         {
     434            1 :             if (instr == nullptr) {
     435            0 :                 HCCL_ERROR("[CcuV2::ReduceAdd] instr is nullptr!");
     436            0 :                 return;
     437              :             }
     438            1 :             instr->header = InstrHeader(REDUCE_TYPE, REDUCE_ADD_CODE);
     439            1 :             Reduce(instr, ms, count, castEn, dataType, setCKEId, setCKEMask);
     440              :         }
     441              : 
     442            1 :         void ReduceMax(
     443              :             CcuInstr* instr, uint16_t* ms, uint16_t count, uint16_t dataType, uint16_t setCKEId, uint16_t setCKEMask)
     444              :         {
     445            1 :             instr->header = InstrHeader(REDUCE_TYPE, REDUCE_MAX_CODE);
     446            1 :             Reduce(instr, ms, count, 0, dataType, setCKEId, setCKEMask);
     447            1 :         }
     448              : 
     449            1 :         void ReduceMin(
     450              :             CcuInstr* instr, uint16_t* ms, uint16_t count, uint16_t dataType, uint16_t setCKEId, uint16_t setCKEMask)
     451              :         {
     452            1 :             instr->header = InstrHeader(REDUCE_TYPE, REDUCE_MIN_CODE);
     453            1 :             Reduce(instr, ms, count, 0, dataType, setCKEId, setCKEMask);
     454            1 :         }
     455              :     }; // namespace CcuV2
     456              : 
     457              : }; // namespace CcuRep
     458              : }; // namespace Hccl
        

Generated by: LCOV version 2.0-1