IMG_INTERNAL IMG_VOID ChangeProgramStructToExecPred(PINTERMEDIATE_STATE psState) { USC_LIST sFuncLoopsInfoLst; FindProgramLoops(psState, &sFuncLoopsInfoLst); RestructureProgramLoopsToExecPred(psState, &sFuncLoopsInfoLst); FreeFuncLoopsInfoList(psState, &sFuncLoopsInfoLst); if (psState->uExecPredTemp != USC_UNDEF) { PINST psInst = AllocateInst(psState, IMG_NULL); SetOpcode(psState, psInst, IMOV); SetDest(psState, psInst, 0 /* uDestIdx */, USEASM_REGTYPE_TEMP, psState->uExecPredTemp, UF_REGFORMAT_F32); SetSrc(psState, psInst, 0, USEASM_REGTYPE_IMMEDIATE, 0, UF_REGFORMAT_F32); InsertInstBefore(psState, psState->psMainProg->sCfg.psEntry, psInst, psState->psMainProg->sCfg.psEntry->psBody); { SAFE_LIST_ITERATOR sIter; InstListIteratorInitialize(psState, ICNDSM, &sIter); for (; InstListIteratorContinue(&sIter); InstListIteratorNext(&sIter)) { PINST psCndsmInst; IMG_UINT32 uAdjust; psCndsmInst = InstListIteratorCurrent(&sIter); uAdjust = psCndsmInst->asArg[3].uNumber; if (AddStaticSecAttr(psState, uAdjust, NULL /* puArgType */, NULL /* puArgNum */)) { IMG_UINT32 uArgType, uArgNumber; /* Use the secondary attribute as the instruction source. */ AddStaticSecAttr(psState, uAdjust, &uArgType, &uArgNumber); SetSrc(psState, psCndsmInst, 3, uArgType, uArgNumber, UF_REGFORMAT_F32); } else { PINST psLimmInst; IMG_UINT32 uImmTemp = GetNextRegister(psState); PCODEBLOCK psLimmCodeBlock = AllocateBlock(psState, psCndsmInst->psBlock->psOwner); RedirectEdgesFromPredecessors(psState, psCndsmInst->psBlock, psLimmCodeBlock, IMG_FALSE); SetBlockUnconditional(psState, psLimmCodeBlock, psCndsmInst->psBlock); /* Add a LIMM instruction to load the immediate value into a temporary register. */ psLimmInst = AllocateInst(psState, psCndsmInst); SetOpcode(psState, psLimmInst, ILIMM); SetDestTempArg(psState, psLimmInst, 0 /* uDestIdx */, uImmTemp, UF_REGFORMAT_F32); psLimmInst->asArg[0].uType = USEASM_REGTYPE_IMMEDIATE; psLimmInst->asArg[0].uNumber = uAdjust; InsertInstBefore(psState, psLimmCodeBlock, psLimmInst, psLimmCodeBlock->psBody); /* Use the temporary register as the instruction source. */ SetSourceTempArg(psState, psCndsmInst, 3, uImmTemp, UF_REGFORMAT_F32); } } InstListIteratorFinalise(&sIter); } } return; }
/* Retarget a stack that's already been build to a different * destination address, "daddr". "laddr" is supplied for convenience */ static bool_t retarget(struct udp_data *ud, struct sockaddr_in *laddr, struct sockaddr_in *daddr) { uint32_t NOCLOBBER arpaddr; FlowMan_RouteInfo * NOCLOBBER ri = NULL; FlowMan_SAP rsap; Net_IPHostAddr ipaddr; Net_EtherAddr hwaddr; /* route the new dest addr, and make sure we don't need to change * interface */ rsap.tag = FlowMan_PT_UDP; rsap.u.UDP.addr.a = daddr->sin_addr.s_addr; rsap.u.UDP.port = daddr->sin_port; TRY { ri = FlowMan$ActiveRoute(ud->fman, &rsap); } CATCH_FlowMan$NoRoute() { ri = NULL; } ENDTRY; if (!ri) { printf("retarget: no route to host %x\n", ntohl(daddr->sin_addr.s_addr)); return False; } if (strcmp(ri->ifname, ud->curif)) { printf("retarget: route to %x requires going through %s, but stack " "is built to %s\n", ntohl(daddr->sin_addr.s_addr), ri->ifname, ud->curif); free(ri->ifname); free(ri->type); free(ri); return False; } if (ri->gateway) arpaddr = ri->gateway; else arpaddr = daddr->sin_addr.s_addr; TRC(eprintf("retarget: ARPing for %I\n", arpaddr)); { bool_t NOCLOBBER ok = True; TRY { FlowMan$ARP(ud->fman, arpaddr, &hwaddr); } CATCH_Context$NotFound(UNUSED name) { ok = False; } ENDTRY; if(!ok) return False; } TRC(eprintf("Retargeted remote hwaddr: %02x:%02x:%02x:%02x:%02x:%02x%s\n", hwaddr.a[0], hwaddr.a[1], hwaddr.a[2], hwaddr.a[3], hwaddr.a[4], hwaddr.a[5], (ri->gateway)?" (using gateway)":"")); free(ri->ifname); free(ri); Ether$SetDest(ud->eth, &hwaddr); ipaddr.a = daddr->sin_addr.s_addr; IP$SetDest(ud->ip, &ipaddr); UDP$SetTXPort(ud->udp, daddr->sin_port); return True; }
/****************************************************************************** FUNCTION : AppendExecPredInst DESCRIPTION : Append a Execution Predication related instruciton to a CFG block PARAMETERS : psState - Compiler intermediate state psBlock - CFG block in which to append the instruction eOpcode - Opcode of the new instruction uCondPred - Index of the intermediate predicate controlling conditional execution (result of previous test) Not used for ICNDEND; bCondPredInv - Whether the state of the predicate should be inverted. Not used for ICNDEND. uLoopPred - Index of the intermediate predicate to indicate whether a loop is complete. Used for ICNDLT only. RETURNS : IMG_VOID OUTPUT : Nothing ******************************************************************************/ static IMG_VOID AppendExecPredInst( PINTERMEDIATE_STATE psState, PCODEBLOCK psBlock, IOPCODE eOpcode, IMG_UINT32 uCondPred, IMG_BOOL bCondPredInv, IMG_UINT32 uLoopPred, IMG_UINT32 uAdjust) { PINST psExecPredInst; IMG_UINT32 uCurrSrc = 0; if (psState->uExecPredTemp == USC_UNDEF) { psState->uExecPredTemp = GetNextRegister(psState); } /* Create and append the CNDx instruction to the block */ psExecPredInst = AllocateInst(psState, NULL); if(eOpcode == ICNDLT || eOpcode == ICNDEND) { SetOpcodeAndDestCount(psState, psExecPredInst, eOpcode, 2); } else { SetOpcodeAndDestCount(psState, psExecPredInst, eOpcode, 1); } SetDest(psState, psExecPredInst, 0 /* uDestIdx */, USEASM_REGTYPE_TEMP, psState->uExecPredTemp, UF_REGFORMAT_F32); if (eOpcode == ICNDLT) { MakePredicateDest(psState, psExecPredInst, 1, uLoopPred); } else if (eOpcode == ICNDEND) { psExecPredInst->asDest[1].uType = USC_REGTYPE_DUMMY; } SetSrc(psState, psExecPredInst, uCurrSrc, USEASM_REGTYPE_TEMP, psState->uExecPredTemp, UF_REGFORMAT_F32); uCurrSrc++; if (eOpcode != ICNDEND) { if(uCondPred != USC_PREDREG_NONE) { MakePredicateSource(psState, psExecPredInst, uCurrSrc, uCondPred); } else { psExecPredInst->asArg[uCurrSrc].uType = USEASM_REGTYPE_IMMEDIATE; psExecPredInst->asArg[uCurrSrc].uNumber = 0; } uCurrSrc++; psExecPredInst->asArg[uCurrSrc].uType = USEASM_REGTYPE_IMMEDIATE; if(bCondPredInv) { psExecPredInst->asArg[uCurrSrc].uNumber = 1; } else { psExecPredInst->asArg[uCurrSrc].uNumber = 0; } uCurrSrc++; } { psExecPredInst->asArg[uCurrSrc].uType = USEASM_REGTYPE_IMMEDIATE; if ((eOpcode == ICNDLT) || (eOpcode == ICNDSTLOOP) || (eOpcode == ICNDEFLOOP) || (eOpcode == ICNDSM)) { psExecPredInst->asArg[uCurrSrc].uNumber = uAdjust; } else { psExecPredInst->asArg[uCurrSrc].uNumber = 1; } } AppendInst(psState, psBlock, psExecPredInst); }