예제 #1
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate an extended swizzle (SWZ) instruction.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	prec	precision flags for instruction
 * @param	dst		destination 
 * @param	src		source operand 
 * @param	optionX	swizzle selector for x coordinate
 * @param	optionY	swizzle selector for y coordinate
 * @param	optionZ	swizzle selector for z coordinate
 * @param	optionW	swizzle selector for w coordinate
 */
void GlesGenInstSwizzle(ShaderProgramGenerator *	gen,
					 	Opcode 						op,
					 	Precision					prec,
					 	const DstReg *				dst,
					 	SrcRef						src,
					 	ExtSwizzleOption			optionX,
					 	ExtSwizzleOption			optionY,
					 	ExtSwizzleOption			optionZ,
					 	ExtSwizzleOption			optionW) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	GLES_ASSERT(dst);
	GLES_ASSERT(src.base);
	
	gen->instructionCount++;
		
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstSwizzle));
	InitInstSwizzle(&inst->swizzle, op, prec, dst, src, 
						optionX, optionY, optionZ, optionW);
	AppendInst(gen->currentList->tail, inst);
}
예제 #2
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate an conditional instruction.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	cond	branch condition
 * @param	selectX	selector for 1st condition flag
 * @param	selectY	selector for 2nd condition flag
 * @param	selectZ	selector for 3rd condition flag
 * @param	selectW	selector for 4th condition flag
 */
void GlesGenInstCond(struct ShaderProgramGenerator *	gen,
				 	 Opcode								op,
					 Cond								cond,
					 GLubyte							selectX,
					 GLubyte							selectY,
					 GLubyte							selectZ,
					 GLubyte							selectW) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	
	/* this is a special case, since an IF with a constant condition will be removed */
	if (cond != CondT && cond != CondF) {
		gen->instructionCount++;
	}
		
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstCond));
	InitInstCond(&inst->cond, op, cond, selectX, selectY, selectZ, selectW);
	AppendInst(gen->currentList->tail, inst);
}
예제 #3
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate a texture access instruction.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	prec	precision modifier
 * @param	target	texture target to use
 * @param	dst		destination
 * @param	src		texture coordinate vector
 * @param	sampler	texture sampler variable to access texture memory
 * @param	offset	offset for sampler array
 */
void GlesGenInstTex(ShaderProgramGenerator *	gen,
					Opcode						op,
				 	Precision					prec,
					TextureTarget				target,
					const DstReg *				dst,
					const SrcReg *				src,
					ProgVar *					sampler,
					GLsizeiptr					offset) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	GLES_ASSERT(dst);
	GLES_ASSERT(src);
	GLES_ASSERT(sampler);
	
	gen->instructionCount++;
		
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstTex));
	InitInstTex(&inst->tex, op, prec, target, dst, src, sampler, offset);
	AppendInst(gen->currentList->tail, inst);
}
예제 #4
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate a binary instruction.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	prec	precision flags for instruction
 * @param	dst		destination 
 * @param	arg0	source operand 0
 * @param	arg1	source operand 1
 * @param	arg2	source operand 2
 */
void GlesGenInstTernary(ShaderProgramGenerator *	gen, 
					    Opcode 						op,
					    Precision					prec,
					    const DstReg *				dst,
					   	const SrcReg *				arg0,
					    const SrcReg *				arg1,
					    const SrcReg *				arg2) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	GLES_ASSERT(dst);
	GLES_ASSERT(arg0);
	GLES_ASSERT(arg1);
	GLES_ASSERT(arg2);
	
	gen->instructionCount++;
		
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstTernary));
	InitInstTernary(&inst->ternary, op, prec, dst, arg0, arg1, arg2);
	AppendInst(gen->currentList->tail, inst);
}
예제 #5
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate a branch or subroutine call instruction.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	target	branch target
 * @param	cond	branch condition
 * @param	selectX	selector for 1st condition flag
 * @param	selectY	selector for 2nd condition flag
 * @param	selectZ	selector for 3rd condition flag
 * @param	selectW	selector for 4th condition flag
 */
void GlesGenInstBranch(ShaderProgramGenerator *	gen,
					   Opcode					op,
					   Label *					target,
					   Cond						cond,
					   GLubyte					selectX,
					   GLubyte					selectY,
					   GLubyte					selectZ,
					   GLubyte					selectW) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	GLES_ASSERT(target);
	
	gen->instructionCount++;
		
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstBranch));
	InitInstBranch(&inst->branch, op, target, cond, selectX, selectY, selectZ, selectW);
	AppendInst(gen->currentList->tail, inst);
}
예제 #6
0
/* 
 * CallInst     -> [VarName =] call VarName(Operand, Operand, ...)
 * */
void GenerateFunctionCall (Type ty, Symbol recv, Symbol faddr, Vector args, int callNum)
{
	ILArg   p;
	IRInst  inst;

	CALLOC(inst);
	if (recv) 
        recv->ref++;
	faddr->ref++;

	FOR_EACH_ITEM (ILArg, p, args)
		p->sym->ref++;
	ENDFOR

	inst->ty      = ty;
	inst->opcode  = CALL;
    inst->callNum = callNum;
    /* 返回值 */
	inst->opds[0] = recv;
	inst->opds[1] = faddr;
    /* 参数 */
	inst->opds[2] = (Symbol)args;
	AppendInst (inst);

    /* 给返回值创建临时变量 */
	if (recv != NULL)
		DefineTemp (recv, CALL, (Symbol)inst, NULL);
}
예제 #7
0
/* 
 * ReturnInst   -> return VarName
 * */
void GenerateReturn (Type ty, Symbol src)
{
	IRInst inst;

	CALLOC(inst);
	src->ref++;
	inst->ty      = ty;
	inst->opcode  = RET;
	inst->opds[0] = src;
	inst->opds[1] = inst->opds[2] = NULL;
	AppendInst (inst);
}
예제 #8
0
파일: gen.c 프로젝트: descent/ucc-code
void GenerateJump(BBlock dstBB)
{
	IRInst inst;

	ALLOC(inst);
	dstBB->ref++;
	DrawCFGEdge(CurrentBB, dstBB);
	inst->ty = T(VOID);
	inst->opcode = JMP;
	inst->opds[0] = (Symbol)dstBB;
	inst->opds[1] = inst->opds[2] = NULL;
	AppendInst(inst);
}
예제 #9
0
파일: gen.c 프로젝트: descent/ucc-code
void GenerateIndirectMove(Type ty, Symbol dst, Symbol src)
{
	IRInst inst;

	ALLOC(inst);
	dst->ref++;
	src->ref++;
	inst->ty = ty;
	inst->opcode  = IMOV;
	inst->opds[0] = dst;
	inst->opds[1] = src;
	inst->opds[2] = NULL;
	AppendInst(inst);
}
예제 #10
0
/* 
 * ClearInst    -> Clear VarName, constant
 * */
void GenerateClear (Symbol dst, int size)
{
	IRInst inst;

	CALLOC (inst);
	dst->ref++;
	inst->ty      = T(UCHAR);
	inst->opcode  = CLR;
	inst->opds[0] = dst;
	inst->opds[1] = IntConstant (size);
	inst->opds[1]->ref++;
	inst->opds[2] = NULL;
	AppendInst (inst);
}
예제 #11
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate a base instruction.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 */
void GlesGenInstBase(ShaderProgramGenerator *	gen, 
					 Opcode 					op) {
	
	Inst * inst;
	
	GLES_ASSERT(gen);
	
	if (!gen->currentList) {
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstBase));	
	InitInstBase(&inst->base, InstKindBase, op);
	AppendInst(gen->currentList->tail, inst);
}
예제 #12
0
파일: gen.c 프로젝트: descent/ucc-code
void GenerateBranch(Type ty, BBlock dstBB, int opcode, Symbol src1, Symbol src2)
{
	IRInst inst;

	ALLOC(inst);
	dstBB->ref++;
	src1->ref++;
	if (src2) src2->ref++;
	DrawCFGEdge(CurrentBB, dstBB);
	inst->ty = ty;
	inst->opcode  = opcode;
	inst->opds[0] = (Symbol)dstBB;
	inst->opds[1] = src1;
	inst->opds[2] = src2;
	AppendInst(inst);
}
예제 #13
0
파일: gen.c 프로젝트: descent/ucc-code
void GenerateAssign(Type ty, Symbol dst, int opcode, Symbol src1, Symbol src2)
{
	IRInst inst;

	ALLOC(inst);
	dst->ref++;
	src1->ref++;
	if (src2) src2->ref++;
	inst->ty = ty;
	inst->opcode = opcode;
	inst->opds[0] = dst;
	inst->opds[1] = src1;
	inst->opds[2] = src2;
	AppendInst(inst);

	DefineTemp(dst, opcode, src1, src2);
}
예제 #14
0
static 
PCODEBLOCK DuplicateCodeBlock(PINTERMEDIATE_STATE psState, PCODEBLOCK psCodeBlock, PCFG psCfg)
{	
	PINST psCurrInst;
	PCODEBLOCK psDuplicateCodeBlock = AllocateBlock(psState, psCfg);
	if (psCodeBlock->uFlags & USC_CODEBLOCK_CFG)
	{
		psDuplicateCodeBlock->u.sUncond.psCfg = DuplicateCfg(psState, psCfg);
		psDuplicateCodeBlock->uFlags |= USC_CODEBLOCK_CFG;
	}
	for (psCurrInst = psCodeBlock->psBody; psCurrInst != NULL; psCurrInst = psCurrInst->psNext)
	{
		PINST psDuplicateInst = CopyInst(psState, psCurrInst);
		AppendInst(psState, psDuplicateCodeBlock, psDuplicateInst);
	}
	CopyRegLiveSet(psState, &psCodeBlock->sRegistersLiveOut, &psDuplicateCodeBlock->sRegistersLiveOut);
	return psDuplicateCodeBlock;
}
예제 #15
0
파일: gen.c 프로젝트: descent/ucc-code
void GenerateIndirectJump(BBlock *dstBBs, int len, Symbol index)
{
	IRInst inst;
	int i;
	
	ALLOC(inst);
	index->ref++;
	for (i = 0; i < len; ++i)
	{
		dstBBs[i]->ref++;
		DrawCFGEdge(CurrentBB, dstBBs[i]);
	}
	inst->ty = T(VOID);
	inst->opcode = IJMP;
	inst->opds[0] = (Symbol)dstBBs;
	inst->opds[1] = index;
	inst->opds[2] = NULL;
	AppendInst(inst);
}
예제 #16
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate an instruction that takes a vector argument but does not
 * have any result register.
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	src		source operand
 */
void GlesGenInstSrc(struct ShaderProgramGenerator *	gen, 
					Opcode 							op,
					const SrcReg *					src) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	GLES_ASSERT(src);

	gen->instructionCount++;
		
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstSrc));
	InitInstSrc(&inst->src, op, src);
	AppendInst(gen->currentList->tail, inst);
}					  
예제 #17
0
/* 生成赋值指令 */
void GenerateMove (Type ty, Symbol dst, Symbol src)
{
	IRInst inst;

	ALLOC(inst);
	dst->ref++;
	src->ref++;

	inst->ty = ty;
	inst->opcode  = MOV;
	inst->opds[0] = dst;
	inst->opds[1] = src;
	inst->opds[2] = NULL;
	AppendInst (inst);

	if (dst->kind == SK_Variable) {

		TrackValueChange (dst);
	} else if (dst->kind == SK_Temp) {

		DefineTemp (dst, MOV, (Symbol)inst, NULL);
	}
}
예제 #18
0
/* 
 * AssignInst   -> VarName = Expression |
 *              -> VarName = Operand |
 *              -> *VarName = Operand
 * */
void GenerateAssign (Type ty, Symbol dst, int opcode, Symbol src1, Symbol src2)
{
	IRInst inst;

	CALLOC(inst);
    /* 符号被引用一次 */
	dst->ref++;
	src1->ref++;
	if (src2) src2->ref++;

    /* 构造三地址码 */
	inst->ty      = ty;
	inst->opcode  = opcode;
	inst->opds[0] = dst;
	inst->opds[1] = src1;
	inst->opds[2] = src2;

    /* 将三地址码添加到当前基本块中 */
	AppendInst (inst);

    /* 构造表达式值,并添加到dst,src1,src2的uses中 */
	DefineTemp (dst, opcode, src1, src2);
}
예제 #19
0
파일: il.c 프로젝트: mew-cx/Vincent_ES_2.x
/**
 * Generate memory access instruction (only used in low level IL).
 * 
 * @param	gen		reference to code generator object
 * @param	op		instruction opcode
 * @param	dst		destination
 * @param	src		source operand
 * @param	index	index to use, can be NULL
 * @param	offset	constant offset to apply
 */
void GlesGenInstMemory(ShaderProgramGenerator *	gen,
					   Opcode					op,
					   const DstReg *			dst,
					   const SrcReg *			src,
					   const SrcReg *			index,
					   GLsizeiptr				offset) {
	Inst * inst;
	
	GLES_ASSERT(gen);
	GLES_ASSERT(dst);
	
	if (!gen->currentList) {
		/* 
		 * Code generation is currently suppressed; keep track of violation of
		 * constant expressions.
		 */
		gen->constViolation |= gen->constExpression;
		return;
	}
	
	inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstMemory));
	InitInstMemory(&inst->memory, op, dst, src, index, offset);
	AppendInst(gen->currentList->tail, inst);
}
예제 #20
0
/******************************************************************************
 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);
}
예제 #21
0
static
IMG_VOID LayoutCfgFromCtrlDepNode(PINTERMEDIATE_STATE psState, PCTRL_DEP_NODE psCtrlDepNode, PCFG psCfg, PCODEBLOCK* ppsEntryBlock, PCODEBLOCK* ppsExitBlock, PCODEBLOCK psCfgActualExitBlock, IMG_BOOL bDuplicateCodeBlocks)
{
	if (psCtrlDepNode->eCtrlDepType == CTRL_DEP_TYPE_BLOCK)
	{
		if (bDuplicateCodeBlocks == IMG_FALSE)
		{
			IMG_UINT32 uLstNodesCount = GetListNodesCount(&(psCtrlDepNode->u.sBlock.sPredLst));
			if (uLstNodesCount > 1)
			{
				PUSC_LIST_ENTRY	psListEntry = RemoveListHead(&(psCtrlDepNode->u.sBlock.sPredLst));
				PCTRL_DEP_NODE_LISTENTRY psCtrlDepNodeLstEntry;
				psCtrlDepNodeLstEntry = IMG_CONTAINING_RECORD(psListEntry, PCTRL_DEP_NODE_LISTENTRY, sListEntry);		
				UscFree(psState, psCtrlDepNodeLstEntry);			
				//printf("duplication needed\n");				
				bDuplicateCodeBlocks = IMG_TRUE;
			}
		}
		if (psCtrlDepNode->u.sBlock.uNumSucc == 0)
		{
			if (psCtrlDepNode->u.sBlock.psBlock != psCfgActualExitBlock)
			{
				(*ppsExitBlock) = (*ppsEntryBlock) = DuplicateCodeBlockIfNeeded(psState, bDuplicateCodeBlocks, psCtrlDepNode->u.sBlock.psBlock);
			}
			else
			{
				PCODEBLOCK psReturnBlock;
				PINST psReturnInst;
				psReturnBlock = AllocateBlock(psState, psCfg);
				psReturnInst = AllocateInst(psState, NULL);
				SetOpcodeAndDestCount(psState, psReturnInst, IRETURN, 0);				
				AppendInst(psState, psReturnBlock, psReturnInst);
				(*ppsExitBlock) = (*ppsEntryBlock) = psReturnBlock;
			}
		}
		else if (psCtrlDepNode->u.sBlock.uNumSucc == 1)
		{
			PCODEBLOCK psSubCfgEntryBlock;
			PCODEBLOCK psSubCfgExitBlock;
			LayoutCfgFromCtrlDepNode(psState, psCtrlDepNode->u.sBlock.apsSucc[0], psCfg, &psSubCfgEntryBlock, &psSubCfgExitBlock, psCfgActualExitBlock, bDuplicateCodeBlocks);
			{
				PCODEBLOCK psCndExeStBlock = AllocateBlock(psState, psCfg);
				PCODEBLOCK psCndExeEndBlock = AllocateBlock(psState, psCfg);
				PCODEBLOCK psCurrCodeBlock;
				AppendExecPredInst(psState, psCndExeStBlock, ICNDST, psCtrlDepNode->u.sBlock.psBlock->u.sCond.sPredSrc.uNumber, psCtrlDepNode->u.sBlock.auSuccIdx[0] == 0 ? IMG_FALSE : IMG_TRUE /* uCondPredInv */, USC_PREDREG_NONE, 1);
				psCurrCodeBlock = DuplicateCodeBlockIfNeeded(psState, bDuplicateCodeBlocks, psCtrlDepNode->u.sBlock.psBlock);
				SetBlockUnconditional(psState, psCurrCodeBlock, psCndExeStBlock);
				AppendExecPredInst(psState, psCndExeEndBlock, ICNDEND, USC_PREDREG_NONE, IMG_FALSE /* uCondPredInv */, USC_PREDREG_NONE, 1);
				SetBlockConditionalExecPred(psState, psCndExeStBlock, psSubCfgEntryBlock, psCndExeEndBlock, IMG_FALSE);
				SetBlockUnconditional(psState, psSubCfgExitBlock, psCndExeEndBlock);
				(*ppsEntryBlock) = psCurrCodeBlock;
				(*ppsExitBlock) = psCndExeEndBlock;
			}
		}
		else
		{
			PCODEBLOCK psSubCfgEntryBlock;
			PCODEBLOCK psSubCfgExitBlock;
			PCODEBLOCK psCndExeEfBlock;
			LayoutCfgFromCtrlDepNode(psState, psCtrlDepNode->u.sBlock.apsSucc[0], psCfg, &psSubCfgEntryBlock, &psSubCfgExitBlock, psCfgActualExitBlock, bDuplicateCodeBlocks);
			psCndExeEfBlock = AllocateBlock(psState, psCfg);
			{
				PCODEBLOCK psCndExeStBlock = AllocateBlock(psState, psCfg);				
				PCODEBLOCK psCurrCodeBlock;
				AppendExecPredInst(psState, psCndExeStBlock, ICNDST, psCtrlDepNode->u.sBlock.psBlock->u.sCond.sPredSrc.uNumber, psCtrlDepNode->u.sBlock.auSuccIdx[0] == 0 ? IMG_FALSE : IMG_TRUE /* uCondPredInv */, USC_PREDREG_NONE, 1);
				psCurrCodeBlock = DuplicateCodeBlockIfNeeded(psState, bDuplicateCodeBlocks, psCtrlDepNode->u.sBlock.psBlock);
				SetBlockUnconditional(psState, psCurrCodeBlock, psCndExeStBlock);
				AppendExecPredInst(psState, psCndExeEfBlock, ICNDEF, USC_PREDREG_NONE, IMG_TRUE /* uCondPredInv */, USC_PREDREG_NONE, 1);
				SetBlockConditionalExecPred(psState, psCndExeStBlock, psSubCfgEntryBlock, psCndExeEfBlock, IMG_FALSE);
				SetBlockUnconditional(psState, psSubCfgExitBlock, psCndExeEfBlock);
				(*ppsEntryBlock) = psCurrCodeBlock;
			}
			LayoutCfgFromCtrlDepNode(psState, psCtrlDepNode->u.sBlock.apsSucc[1], psCfg, &psSubCfgEntryBlock, &psSubCfgExitBlock, psCfgActualExitBlock, bDuplicateCodeBlocks);
			{
				PCODEBLOCK psCndExeEndBlock = AllocateBlock(psState, psCfg);
				AppendExecPredInst(psState, psCndExeEndBlock, ICNDEND, USC_PREDREG_NONE, IMG_FALSE /* uCondPredInv */, USC_PREDREG_NONE, 1);
				SetBlockConditionalExecPred(psState, psCndExeEfBlock, psSubCfgEntryBlock, psCndExeEndBlock, IMG_FALSE);
				SetBlockUnconditional(psState, psSubCfgExitBlock, psCndExeEndBlock);
				(*ppsExitBlock) = psCndExeEndBlock;								
			}
		}
	}
	else
	{
		PCODEBLOCK psPrevSubCfgExitBlock = NULL;
		PCODEBLOCK psSubCfgEntryBlock;
		PCODEBLOCK psSubCfgExitBlock;
		PUSC_LIST_ENTRY	psListEntry;
		PCTRL_DEP_NODE_LISTENTRY psCtrlDepNodeLstEntry;
		for (psListEntry = psCtrlDepNode->u.sRegion.sSuccLst.psHead; psListEntry != NULL; psListEntry = psListEntry->psNext)
		{
			psCtrlDepNodeLstEntry = IMG_CONTAINING_RECORD(psListEntry, PCTRL_DEP_NODE_LISTENTRY, sListEntry);
			LayoutCfgFromCtrlDepNode(psState, psCtrlDepNodeLstEntry->psCtrlDepNode, psCfg, &psSubCfgEntryBlock, &psSubCfgExitBlock, psCfgActualExitBlock, bDuplicateCodeBlocks);
			if (psPrevSubCfgExitBlock == NULL)
			{
				(*ppsEntryBlock) = psSubCfgEntryBlock;
			}
			else
			{
				SetBlockUnconditional(psState, psPrevSubCfgExitBlock, psSubCfgEntryBlock);
			}
			psPrevSubCfgExitBlock = psSubCfgExitBlock;
		}
		(*ppsExitBlock) = psPrevSubCfgExitBlock;
	}
}