/*
 * All inter-prediction macroblock kernels 
 * Copyright © <2010>, Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * This file was originally licensed under the following license
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
// Kernel name: AVCMCInter.asm

#ifdef INTERLABEL
#undef INTERLABEL
#endif

#if defined(MBAFF)
//				< MBaff_Motion >
#define INTERLABEL(x)	x##_##MBF
#elif defined(FIELD)
//				< FieldMB_Motion >
#define INTERLABEL(x)	x##_##FLD
#else // FRAME
//				< FrameMB_Motion >
#define INTERLABEL(x)	x##_##FRM
#endif
//
// Decoding an inter-prediction macroblock (conditional compile)
//	-DMBAFF : MBAff picture MB
//	-DFRAME : Frame picture MB
//	-DFIELD : Field picture MB
//	-DMBAFF -DMONO : MBAff mono picture MB
//	-DFRAME -DMONO : Frame mono picture MB
//	-DFIELD -DMONO : Field mono picture MB


//#if !defined(__AVCMCInter__)		// Make sure this is only included once
//#define __AVCMCInter__


// TODO: header files need to be in sync with intra prediction
#include "header.inc"
#include "inter_Header.inc"

// TODO: Kernel names for mono cases
#if defined(MBAFF)
.kernel MBAff_Motion
MBAFF_MB:
#elif defined(FIELD)
.kernel FieldMB_Motion
FIELD_MB:
#else // Frame
.kernel FrameMB_Motion
FRAME_MB:
#endif

#ifdef _DEBUG
// WA for FULSIM so we'll know which kernel is being debugged
#if defined(MBAFF)
mov (1) acc0:ud 0x0aaa55a5:ud
#elif defined(FIELD)
mov (1) acc0:ud 0x0baa55a5:ud
#else // Frame
mov (1) acc0:ud 0x0caa55a5:ud
#endif
#endif


#ifdef SW_SCOREBOARD
    CALL(scoreboard_start_inter,1)
#endif

	mov (8)		gMSGSRC<1>:ud		r0.0<8;8,1>:ud		// Initialize message header payload with R0
	
	and (1)		gwMBTYPE<1>			gMBTYPE:ub						nMBTYPE_MASK:w		// MB type
	shl (2)		gX<1>:w				gORIX<2;2,1>:ub					4:w // Convert MB origin to pixel unit
	
//	#include "process_inter16x16.asm"					// Handle B_L0_16x16 case with zero MVs and weighted pred off.
	// In the case of B_L0_16x16 with zero MVs and weighted pred off, the kernel jumps to INTERLABEL(EXIT_LOOP).
	
INTERLABEL(INIT_MBPARA):
	#include "initialize_MBPara.asm"
	
	
    //========================= BEGIN - LOOP_SUBMB ===========================
	mov (1)		gLOOP_SUBMB:uw		0:uw				// 0, 2, 4, 6
INTERLABEL(LOOP_SUBMB):

	//========================== BEGIN - LOOP_DIR ============================
	// Prediction flag (gPREDFLAG - 0:Pred_L0, 1:Pred_L1, 2:BiPred)
	asr (1)		gPREDFLAG:w			gSUBMB_MODE:ub					gLOOP_SUBMB:uw
	mov (1)		gLOOP_DIR:uw		1:uw				// 1, 0
	and (1)		gPREDFLAG:w			gPREDFLAG:w						0x3:w
INTERLABEL(LOOP_DIR):

	cmp.e.f0.0 (1) null:w			gLOOP_DIR:w						gPREDFLAG:w	
	(f0.0) jmpi	INTERLABEL(LOOP_DIR_CONTINUE)	
	
    // Get binding table index 
    // & reference picture parity (gREFPARITY - 0:top, 0x100:bottom, x:frame)
    // & address of interpolation result
    cmp.e.f0.1 (1) null:w			gLOOP_DIR:w						1:w
    (f0.1) mov (1)		gpINTP:ud			nOFFSET_INTP0:ud						{NoDDClr} //
    (f0.1) and (1)		gBIDX:w				r[pBIDX]:ub						0x7f:w	{NoDDChk} //
    (-f0.1) mov (1)		gpINTP:ud			nOFFSET_INTP1:ud						{NoDDClr} //
	(-f0.1) and (1)		gBIDX:w				r[pBIDX,4]:ub					0x7f:w	{NoDDChk} //
#if defined(MBAFF) || defined(FIELD)
    (f0.1) and (1)		gREFPARITY:w				r[pBIDX]:ub						0x80:w
    (-f0.1) and (1)		gREFPARITY:w				r[pBIDX,4]:ub					0x80:w
    shl (1)		gREFPARITY:w		gREFPARITY<0;1,0>:w				1:w
#endif

	// Sub MB shape
	asr (1)		gSHAPETEMP:w		gSUBMB_SHAPE:ub					gLOOP_SUBMB:w
	
    // Chroma MV adjustment & Set message descriptor for frame/field read
#if defined(MBAFF)
	#include "chromaMVAdjust.asm" 
    and.nz.f0.0 (1) null:uw			gFIELDMBFLAG:ub					nFIELDMB_MASK:uw
    (f0.0) add (1) gD0:ud			gBIDX:uw						nDWBRMSGDSC_SC_TF:ud
    (-f0.0) add (1)	gMSGDSC_R:ud	gBIDX:uw						nDWBRMSGDSC_SC:ud
    (f0.0) add (1) gMSGDSC_R:ud		gD0:ud							gREFPARITY:uw
#elif defined(FIELD)
	#include "chromaMVAdjust.asm" 
    add (1)		gMSGDSC_R:ud		gBIDX:uw						nDWBRMSGDSC_SC_TF:ud
    add (1)		gMSGDSC_R:ud		gMSGDSC_R:ud					gREFPARITY:uw
#else // FRAME
	add (1)		gMSGDSC_R:ud		gBIDX:uw						nDWBRMSGDSC_SC:ud
#endif

	and.nz.f0.1 (1) null:w			gSHAPETEMP:w					3:w	
	(f0.1) jmpi INTERLABEL(PROCESS4x4)
	
	//======================== BEGIN - PROCESS 8x8 ===========================
	
	// Reference block load
	#include "loadRef_Y_16x13.asm"
#ifndef MONO
#if defined(MBAFF) || defined(FIELD)
	add (1)		r[pMV,2]:w			r[pMV,2]:w						gCHRMVADJ:w
#endif
	#include "loadRef_C_10x5.asm"
#endif

	// Interpolation
	//CALL_INTER(INTERLABEL(Interpolate_Y_8x8_Func), 1)
	#include "interpolate_Y_8x8.asm"
#ifndef MONO
	//CALL_INTER(INTERLABEL(Interpolate_C_4x4_Func), 1)
	#include "interpolate_C_4x4.asm"
#endif

	jmpi INTERLABEL(ROUND_SHIFT_C)
	//========================= END - PROCESS 8x8 ============================
	
	//======================== BEGIN - LOOP_SUBMBPT ==========================
INTERLABEL(PROCESS4x4):

	mov (1)		gLOOP_SUBMBPT:uw	4:uw				// 4, 3, 2, 1
INTERLABEL(LOOP_SUBMBPT):

	// Reference block load
	#include "loadRef_Y_16x9.asm"
#ifndef MONO
#if defined(MBAFF) || defined(FIELD)
	add (1)		r[pMV,2]:w			r[pMV,2]:w						gCHRMVADJ:w
#endif
	#include "loadRef_C_6x3.asm"
#endif

	// Interpolation
	#include "interpolate_Y_4x4.asm"
#ifndef MONO
	#include "interpolate_C_2x2.asm"
#endif
	
	cmp.e.f0.0 (1) null:w			gLOOP_SUBMBPT:uw				3:w
	add.z.f0.1 (1) gLOOP_SUBMBPT:uw gLOOP_SUBMBPT:uw				-1:w
	add (1)		pMV:w				pMV:w							8:w	
	(-f0.0) add (1)	gpINTP:ud		gpINTP:ud						0x00080008:ud	// 8 & 8
	(f0.0) add (1) gpINTP:ud		gpINTP:ud						0x00180038:ud	// 24 & 56
	(-f0.1) jmpi INTERLABEL(LOOP_SUBMBPT)
    
    cmp.e.f0.1	null:w				gLOOP_DIR:w						1:w
    add (1)		pMV:w				pMV:w							-32:w
    (f0.1) mov (1) gpINTP:ud		nOFFSET_INTP0:ud
    (-f0.1) mov (1) gpINTP:ud		nOFFSET_INTP1:ud

	mov (1)		pRESULT:uw					gpINTPC:uw
    
	//========================= END - LOOP_SUBMBPT ===========================
    
INTERLABEL(ROUND_SHIFT_C):
    
#ifndef MONO
	#include "roundShift_C_4x4.asm"
#endif

INTERLABEL(LOOP_DIR_CONTINUE):
	
	add.nz.f0.1 (1) gLOOP_DIR:uw	gLOOP_DIR:uw					-1:w
	add (1)		pMV:w				pMV:w							4:w
    (-f0.1) jmpi INTERLABEL(LOOP_DIR)
    //=========================== END - LOOP_DIR =============================

INTERLABEL(Weighted_Prediction):
	#include "weightedPred.asm"
	
	and.z.f0.1 (16)	null<1>:w		gLOOP_SUBMB<0;1,0>:uw			2:w

	#include "recon_Y_8x8.asm"
#ifndef MONO
	#include "recon_C_4x4.asm"

	(-f0.1) add (1)	pERRORC:w		pERRORC:w						48:w
#endif

	cmp.e.f0.1 (1) null:w			gLOOP_SUBMB:uw					6:w
	add (1)		gLOOP_SUBMB:uw		gLOOP_SUBMB:uw					2:w

	add (1)		pWGT_BIDX:ud		pWGT_BIDX:ud					0x00100001:ud	// 12 & 1
	add (1)		pMV:w				pMV:w							gMVSTEP:w

    (-f0.1) jmpi INTERLABEL(LOOP_SUBMB)
    //========================== END - LOOP_SUBMB ============================
    
INTERLABEL(EXIT_LOOP):   
	#include "writeRecon_YC.asm"    

#ifdef SW_SCOREBOARD    
	wait	n0:ud		//	Now wait for scoreboard to response
    #include "Soreboard_update.asm"	// scorboard update function
#else
// Check for write commit first if SW scoreboard is disabled
	mov	(1)	gREG_WRITE_COMMIT_Y<1>:ud	gREG_WRITE_COMMIT_Y<0;1,0>:ud		// Make sure Y write is committed
	mov	(1)	gREG_WRITE_COMMIT_UV<1>:ud	gREG_WRITE_COMMIT_UV<0;1,0>:ud		// Make sure U/V write is committed
#endif

// Terminate the thread
//
    END_THREAD


//#include "Interpolate_Y_8x8_Func.asm"
//#include "Interpolate_C_4x4_Func.asm"
//#include "WeightedPred_Y_Func.asm"	
//#include "WeightedPred_C_Func.asm"	


.end_code

.end_kernel

        
//#endif	// !defined(__AVCMCInter__)
