/********************************************************************************
 *																				*
 * This code has been developed by Project Mayo. This software is an			*
 * implementation of a part of one or more MPEG-4 Video tools as				*
 * specified in ISO/IEC 14496-2 standard.  Those intending to use this			*
 * software module in hardware or software products are advised that its		*
 * use may infringe existing patents or copyrights, and any such use			*
 * would be at such party's own risk.  The original developer of this			*
 * software module and his/her company, and subsequent editors and their		*
 * companies (including Project Mayo), will have no liability for use of		*
 * this software or modifications or derivatives thereof.						*
 *																				*
 ********************************************************************************
 *																				*	
 * This program is free software; you can redistribute it and/or modify			*
 * it under the terms of the GNU General Public License as published by			*
 * the Free Software Foundation; either version 2 of the License, or			*
 * (at your option) any later version.											*
 *																				*
 * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html				*
 *																				*
 * Authors:																		*
 *																				*
 *	John Funnell (JF) and														*
 *	Andrea Graziani	(Ag):														*
 *		- Original source code (Open Divx Decoder 0.4a).						*		
 *																				*
 *	Pedro Mateu		(Pm):														*
 *		- Modified and optimized code + MIPS ASM								*
 *																				*
 ********************************************************************************/

// mp4_vld.c //
#include "global.h"
#include "mp4_vld.h"

/**/

 int vldTableB19(int last, int run);
 int vldTableB20(int last, int run);
 int vldTableB21(int last, int level);
 int vldTableB22(int last, int level);

 int vldTableB16(int code);
 int vldTableB17(int code);

/**/

int vld_intra_dct() 
{
#ifdef MIPS_ASM
	__asm("li	$4,12;"
		  "jal	showbits;"
		  "move	$4,$2;"
		  "jal	vldTableB16;"
		  "li	$8,7167;"
		  "beq	$2,$8,INTRA_ESCAPE_MODE;"
  		  "beq	$2,$0,INTRA_ERROR;"
		  "sra	$5,$2,6;" //run=tab>>6...
		  "andi	$5,$5,63;"//...&63
		  "andi	$6,$2,63;"//level=tab&63
		  "sra	$7,$2,12;"//last= tab>>12...
		  "andi	$7,$7,1;"//...&1
		  );
__asm(	  "jal	getbits1;"
		  "beq	$2,$0,INTRA_POS1;"
		  "neg	$6;" // -level
		  "INTRA_POS1:sll	$6,$6,16;" //level <<16
		  "sll	$7,$7,8;" //last << 8
		  "or	$2,$6,$7;" 
		  "or	$2,$2,$5;"
		  "b	INTRA_FIN;");
		  
__asm(	  "INTRA_ESCAPE_MODE:li	$4,2;"
		  "jal	showbits;" //showbits (2)
		  
		  "li	$8,2;" // !0x1, !0x0?
		  "beq	$8,$2,INTRA_02;"
		  "li	$8,3;" // !0x1, !0x0?
		  "beq	$8,$2,INTRA_03;"

		  "li	$4,1;"
		  "jal	flushbits;"//flushbits (1)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB16;"
		  "beq	$2,$0,INTRA_ERROR;"
		  "sra	$5,$2,6;" //run=tab>>6...
		  "andi	$5,$5,63;"//...&63
		  "andi	$6,$2,63;"//level=tab&63
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB19;"
		  "add	$6,$6,$2;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTRA_POS2;"
		  "neg	$6;" // -level
		  "INTRA_POS2:sll	$6,$6,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$6;" 
		  "or	$2,$2,$5;"
		  "b	INTRA_FIN;");
		 
__asm(	  "INTRA_02:li	$4,2;"
		  "jal	flushbits;"//flushbits (2)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB16;"
		  "beq	$2,$0,INTRA_ERROR;"
		  "sra	$6,$2,6;" //run=tab>>6...
		  "andi	$6,$6,63;"//...&63
		  "andi	$5,$2,63;"//level=tab&63
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB21;"
		  "add	$6,$6,$2;"
		  "addi	$6,$6,1;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTRA_POS3;"
		  "neg	$5;" // -level
		  "INTRA_POS3:sll	$5,$5,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$5;" 
		  "or	$2,$2,$6;"
		  "b	INTRA_FIN;");

__asm(	  "INTRA_03:"
		  "li	$4,23;"
		  "jal	getbits;"		//getbits (23)
		  "srl	$2,$2,1;"				 
		  "andi	$7,$2,4095;"	//level=tab&4095
		  "srl	$2,$2,13;"		
		  "andi	$6,$2,63;"		//run=tab&63
		  "srl	$2,$2,6;"		
		  "andi	$5,$2,1;"		//last=tab&1
		  "andi	$8,$7,0x800;"
		  "beq	$8,$0,INTRA_POS4;"
		  "li	$9,-1;"
		  "xori	$9,$9,0xfff;"
		  "or	$7,$7,$9;"
		  "INTRA_POS4:"
		  "sll	$7,$7,16;" //level <<16
		  "sll	$5,$5,8;" //last << 8
		  "or	$2,$5,$7;" 
		  "or	$2,$2,$6;"
		  "b	INTRA_FIN;"
		  "INTRA_ERROR:li	$2,-1;"
		  "INTRA_FIN:" );
#else
	
	int run,level,last;
	int tab = 0;
	int lmax, rmax;

	tab = vldTableB16(showbits(12));
	if (!tab) return -1;
	if (tab != ESCAPE) {
		run   = (tab >>  6) & 63;
		level =  tab        & 63;
		last  = (tab >> 12) &  1;
		level = getbits1() ? -level : level;
	} else {
		/* this value is escaped - see para 7.4.1.3 */
		/* assuming short_video_header == 0 */
		switch (showbits(2)) {
			case 0x0 :  /* Type 1 */
			case 0x1 :  /* Type 1 */
				flushbits(1);
				tab = vldTableB16(showbits(12));  /* use table B-16 */
				if (!tab) return -1;
				run   = (tab >>  6) & 63;
				level =  tab        & 63;
				last  = (tab >> 12) &  1;
				lmax = vldTableB19(last, run);  /* use table B-19 */
				level += lmax;
				level =  getbits1() ? -level : level;
				break;
			case 0x2 :  /* Type 2 */
				flushbits(2);
				tab = vldTableB16(showbits(12));  /* use table B-16 */
				if (!tab) return -1;
				run   = (tab >>  6) & 63;
				level =  tab        & 63;
				last  = (tab >> 12) &  1;
				rmax = vldTableB21(last, level);  /* use table B-21 */
				run = run + rmax + 1;
				level = getbits1() ? -level : level;
				break;
			default: //case 0x3 :  /* Type 3  - fixed length codes */
				tab = getbits(23)>>1;
				level = tab&4095; // table B-18 
				tab	>>=	13;
				run   = tab&63;  // table B-18  
				tab >>=	6;
				last  = tab&1;
				// sign extend level... 
				level = (level & 0x800) ? (level | (-1 ^ 0xfff)) : level;
				break;
					 
					 /*	flushbits(2);
				last  = getbits1();
				run   = getbits(6);  // table B-18  
				flushbits(1); // marker bit 
				level = getbits(12); // table B-18 
				// sign extend level... 
				level = (level & 0x800) ? (level | (-1 ^ 0xfff)) : level;
				flushbits(1); // marker bit 
				break;*/
		}
	}

	return (level<<16)|(last<<8)|(run);
#endif
}

/**/

int vld_inter_dct() 
{
#ifdef MIPS_ASM
	__asm("li	$4,12;"
		  "jal	showbits;"
		  "move	$4,$2;"
		  "jal	vldTableB17;"
		  "beq	$2,$0,INTER_ERROR;"
		  "li	$8,7167;"
		  "beq	$2,$8,INTER_ESCAPE_MODE;"
		  "sra	$5,$2,4;" //run=tab>>4...
		  "andi	$5,$5,255;"//...&255
		  "andi	$6,$2,15;"//level=tab&15
		  "sra	$7,$2,12;"//last= tab>>12...
		  "andi	$7,$7,1;"//...&1
		  );
__asm(	  "jal	getbits1;"
		  "beq	$2,$0,INTER_POS1;"
		  "neg	$6;" // -level
		  "INTER_POS1:sll	$6,$6,16;" //level <<16
		  "sll	$7,$7,8;" //last << 8
		  "or	$2,$6,$7;" 
		  "or	$2,$2,$5;"
		  "b	INTER_FIN;");
		  
__asm(	  "INTER_ESCAPE_MODE:li	$4,2;"
		  "jal	showbits;" //showbits (2)
		  
		  "li	$8,2;" // !0x1, !0x0?
		  "beq	$8,$2,INTER_02;"
		  "li	$8,3;" // !0x1, !0x0?
		  "beq	$8,$2,INTER_03;"

		  "li	$4,1;"
		  "jal	flushbits;"//flushbits (1)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB17;"
		  "beq	$2,$0,INTER_ERROR;"
		  "sra	$5,$2,4;" //run=tab>>4...
		  "andi	$5,$5,255;"//...&255
		  "andi	$6,$2,15;"//level=tab&15
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB20;"
		  "add	$6,$6,$2;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTER_POS2;"
		  "neg	$6;" // -level
		  "INTER_POS2:sll	$6,$6,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$6;" 
		  "or	$2,$2,$5;"
		  "b	INTER_FIN;");
		 
__asm(	  "INTER_02:li	$4,2;"
		  "jal	flushbits;"//flushbits (2)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB17;"
		  "beq	$2,$0,INTER_ERROR;"
		  "sra	$6,$2,4;" //run=tab>>6...
		  "andi	$6,$6,255;"//...&255
		  "andi	$5,$2,15;"//level=tab&15
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB22;"
		  "add	$6,$6,$2;"
		  "addi	$6,$6,1;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTER_POS3;"
		  "neg	$5;" // -level
		  "INTER_POS3:sll	$5,$5,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$5;" 
		  "or	$2,$2,$6;"
		  "b	INTER_FIN;");

__asm(	  "INTER_03:"
		  "li	$4,23;"
		  "jal	getbits;"		//getbits (23)
		  "srl	$2,$2,1;"				 
		  "andi	$7,$2,4095;"	//level=tab&4095
		  "srl	$2,$2,13;"		
		  "andi	$6,$2,63;"		//run=tab&63
		  "srl	$2,$2,6;"		
		  "andi	$5,$2,1;"		//last=tab&1
		  "andi	$8,$7,0x800;"
		  "beq	$8,$0,INTER_POS4;"
		  "li	$9,-1;"
		  "xori	$9,$9,0xfff;"
		  "or	$7,$7,$9;"
		  "INTER_POS4:"
		  "sll	$7,$7,16;" //level <<16
		  "sll	$5,$5,8;" //last << 8
		  "or	$2,$5,$7;" 
		  "or	$2,$2,$6;"
		  "b	INTER_FIN;"
		  "INTER_ERROR:li	$2,-1;"
		  "INTER_FIN:" );
#else

	int run, level,last;
	int tab =0;
	int lmax, rmax;

	tab = vldTableB17(showbits(12));
	if (!tab) return -1;
	if (tab != ESCAPE) {
		run   = (tab >>  4) & 255;
		level =  tab        & 15;
		last  = (tab >> 12) &  1;
		level = getbits1() ? -level : level;
		return (level<<16)|(last<<8)|(run);
	} else {
		/* this value is escaped - see para 7.4.1.3 */
		/* assuming short_video_header == 0 */
		int mode = showbits(2);
		switch (mode) {
			case 0x0 :  /* Type 1 */
			case 0x1 :  /* Type 1 */
				flushbits(1);
				tab = vldTableB17(showbits(12));  /* use table B-17 */
				if (!tab) return -1;
				run   = (tab >>  4) & 255;
				level =  tab        & 15;
				last  = (tab >> 12) &  1;
				lmax = vldTableB20(last, run);  /* use table B-20 */
				level += lmax;
				level = getbits1() ? -level : level;
				break;
			case 0x2 :  /* Type 2 */
				flushbits(2);
				tab = vldTableB17(showbits(12));  /* use table B-16 */
				if (!tab) return -1;
				run   = (tab >>  4) & 255;
				level =  tab        & 15;
				last  = (tab >> 12) &  1;
				rmax = vldTableB22(last, level);  /* use table B-22 */
				run = run + rmax + 1;
				level = getbits1() ? -level : level;
				break;
			default: //case 0x3 :  /* Type 3  - fixed length codes */
				tab = getbits(23)>>1;
				level = tab&4095; // table B-18 
				tab	>>=	13;
				run   = tab&63;  // table B-18  
				tab >>=	6;
				last  = tab&1;
				// sign extend level... 
				level = (level & 0x800) ? (level | (-1 ^ 0xfff)) : level;
				break;
		}
	}

	return (level<<16)|(last<<8)|(run);

#endif
}

// Table B-19 -- ESCL(a), LMAX values of intra macroblocks 

 int vldTableB19(int last, int run) {
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"bne	$4,$0,LAST_19;"
		"li		$8,0;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,27;"
	
		"li		$8,1;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,10;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,5;"

		"li		$8,3;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,4;"

		"slti	$8,$5,8;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,3;"

		"slti	$8,$5,10;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,2;"

		"slti	$8,$5,15;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,1;"
		
		"jr		$31;"
		"li		$2,0;"
		
		"LAST_19:beq	$8,$5,FINAL_B19;"
		"li		$2,8;"
	
		"li		$8,1;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,3;"
	
		"slti	$8,$5,7;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,2;"

		"slti	$8,$5,21;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,1;"

		"li		$2,0;"

		"FINAL_B19:;"
		".set reorder;"
		);

#else

	if (!last){ /* LAST == 0 */
		if (run ==  0) return 27;
		else if (run ==  1) return 10;
		else if (run ==  2) return  5;
		else if (run ==  3) return  4;
		else if (run <=  7) return  3;
		else if (run <=  9) return  2;
		else if (run <= 14) return  1;
		else return  0; 
	} else {    /* LAST == 1 */
		if (run ==  0) return  8;
		else if (run ==  1) return  3;
		else if (run <=  6) return  2;
		else if (run <= 20) return  1;
		else return  0; 
	}
#endif
}

/**/

// Table B-20 -- ESCL(b), LMAX values of inter macroblocks 

 int vldTableB20(int last, int run) {
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"bne	$4,$0,LAST_0;"
		"li		$8,0;"
		"beq	$8,$5,FINAL_B20;"
		"li		$2,12;"
	
		"li		$8,1;"
		"beq	$8,$5,FINAL_B20;"
		"li		$2,6;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B20;"
		"li		$2,4;"

		"slti	$8,$5,7;"
		"bne	$8,$0,FINAL_B20;"
		"li		$2,3;"


		"slti	$8,$5,11;"
		"bne	$8,$0,FINAL_B20;"
		"li		$2,2;"

		"slti	$8,$5,27;"
		"bne	$8,$0,FINAL_B20;"
		"li		$2,1;"
		"jr		$31;"
		"li		$2,0;"
		
		"LAST_0:beq	$8,$5,FINAL_B20;"
		"li		$2,3;"
	
		"li		$8,1;"
		"beq	$8,$5,FINAL_B20;"
		"li		$2,2;"
	
		"slti	$8,$5,41;"
		"bne	$8,$0,FINAL_B20;"
		"li		$2,1;"

		"li		$2,0;"

		"FINAL_B20:;"
		".set reorder;"
		);


#else
	if (!last){ /* LAST == 0 */
		if (run ==  0) return 12;
		else if (run ==  1) return  6;
		else if (run ==  2) return  4;
		else if (run <=  6) return  3;
		else if (run <= 10) return  2;
		else if (run <= 26) return  1;
		else return  0; 
	} else {    /* LAST == 1 */
		if (run ==  0) return  3;
		else if (run ==  1) return  2;
		else if (run <= 40) return  1;
		return  0; 
	}
#endif
}

/**/

// Table B-21 -- ESCR(a), RMAX values of intra macroblocks 

 int vldTableB21(int last, int level) {
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"bne	$4,$0,LAST_1;"
		"li		$8,1;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,14;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,9;"
	
		"li		$8,3;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,7;"

		"li		$8,4;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,3;"

		"li		$8,5;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,2;"

		"slti	$8,$5,11;"
		"bne	$8,$0,FINAL_B21;"
		"li		$2,1;"
		"jr		$31;"
		"li		$2,0;"
		
		"LAST_1:beq	$8,$5,FINAL_B21;"
		"li		$2,20;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,6;"
	
		"li		$8,3;"
		"beq	$8,$5,FINAL_B21;"
		"li		$2,1;"

		"li		$2,0;"

		"FINAL_B21:;"
		".set reorder;"
		);


#else
	if (!last){ /* LAST == 0 */
		if (level ==  1) return 14;
		else if (level ==  2) return  9;
		else if (level ==  3) return  7;
		else if (level ==  4) return  3;
		else if (level ==  5) return  2;
		else if (level <= 10) return  1;
		else return  0; 
	} else {    /* LAST == 1 */
		if (level ==  1) return  20;
		else if (level ==  2) return  6;
		else if (level ==  3) return  1;
		else return  0;
	}
#endif
}

/**/

// Table B-22 -- ESCR(b), RMAX values of inter macroblocks 

 int vldTableB22(int last, int level) {
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"bne	$4,$0,LAST_1_B22;"
		"li		$8,1;"
		"beq	$8,$5,FINAL_B22;"
		"li		$2,26;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B22;"
		"li		$2,10;"
	
		"li		$8,3;"
		"beq	$8,$5,FINAL_B22;"
		"li		$2,6;"

		"li		$8,4;"
		"beq	$8,$5,FINAL_B22;"
		"li		$2,2;"

		"slti	$8,$5,7;"
		"bne	$8,$0,FINAL_B22;"
		"li		$2,1;"
		"jr		$31;"
		"li		$2,0;"
		
		"LAST_1_B22:beq	$8,$5,FINAL_B22;"
		"li		$2,40;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B22;"
		"li		$2,1;"
	
		"li		$2,0;"

		"FINAL_B22:;"
		".set reorder;"
		);


#else

	if (!last){ /* LAST == 0 */
		if (level ==  1) return 26;
		else if (level ==  2) return 10;
		else if (level ==  3) return  6;
		else if (level ==  4) return  2;
		else if (level <=  6) return  1;
		else return  0;
	} else {    /* LAST == 1 */
		if (level ==  1) return  40;
		else if (level ==  2) return  1;
		else return  0;
	}
#endif
}

 int tableB1x_1_length(int code);
 int tableB1x_2_length(int code);
 int tableB1x_3_length(int code);

 int vldTableB16(int code) {
	int value,length;
	if (code >= 512) {
		code = (code >> 5) - 16;
		value = tableB16_1[code];
		length = tableB1x_1_length(code);
	} else if (code >= 128) {
		code = (code >> 2) - 32;
		value = tableB16_2[code];
		length = tableB1x_2_length(code);
	} else if (code >= 8) {
		code = code - 8;
		value = tableB16_3[code];
		length = tableB1x_3_length(code);
	} else {
		/* invalid Huffman code */
		return 0;
	}
	flushbits(length);
	return value;
}

/**/

 int vldTableB17(int code) {
	int value,length;
	if (code >= 512) {
		code = (code >> 5) - 16;
		value = tableB17_1[code];
		length = tableB1x_1_length(code);
	} else if (code >= 128) {
		code = (code >> 2) - 32;
		value = tableB17_2[code];
		length = tableB1x_2_length(code);
	} else if (code >= 8) {
		code = code - 8;
		value = tableB17_3[code];
		length = tableB1x_3_length(code);
	} else {
		/* invalid Huffman code */
		return 0;
	}
	flushbits(length);
	return value;
}


 int tableB1x_2_length(int code){
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"slti	$8,$4,44;"
		"beq	$8,$0,FINAL_B1x_2;"
		"li		$2,8;"
	
		"slti	$8,$4,2;"
		"beq	$8,$0,FINAL_B1x_2;"
		"li		$2,9;"
		
		"li		$2,10;"
		
		"FINAL_B1x_2:;"

		".set reorder;"
		);
#else
	
	if (code>43) return 8;
	else if (code>1) return 9;
	else return 10;

#endif
}

 int tableB1x_1_length(int code){
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"slti	$8,$4,96;"
		"beq	$8,$0,FINAL_B1x_1;"
		"li		$2,4;"
	
		"slti	$8,$4,80;"
		"beq	$8,$0,FINAL_B1x_1;"
		"li		$2,3;"
		
		"slti	$8,$4,48;"
		"beq	$8,$0,FINAL_B1x_1;"
		"li		$2,2;"

		"slti	$8,$4,40;"
		"beq	$8,$0,FINAL_B1x_1;"
		"li		$2,4;"

		"slti	$8,$4,28;"
		"beq	$8,$0,FINAL_B1x_1;"
		"li		$2,5;"
	
		"slti	$8,$4,8;"
		"beq	$8,$0,FINAL_B1x_1;"
		"li		$2,6;"		
		
		"li		$2,7;"
		
		"FINAL_B1x_1:;"

		".set reorder;"
		);
#else

	if (code>95) return 4;
	else if (code>79) return 3;
	else if (code>47) return 2;
	else if (code>39) return 4;
	else if (code>27) return 5;
	else if (code>7) return 6;
	else return 7;

#endif
}

 int tableB1x_3_length(int code){
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"slti	$8,$4,88;"
		"beq	$8,$0,FINAL_B1x_3;"
		"li		$2,7;"
	
		"slti	$8,$4,72;"
		"beq	$8,$0,FINAL_B1x_3;"
		"li		$2,12;"
		
		"slti	$8,$4,56;"
		"beq	$8,$0,FINAL_B1x_3;"
		"li		$2,11;"

		"slti	$8,$4,8;"
		"beq	$8,$0,FINAL_B1x_3;"
		"li		$2,10;"
		
		"li		$2,11;"
		
		"FINAL_B1x_3:;"

		".set reorder;"
		);
#else
	
	if (code>87) return 7;
	else if (code>71) return 12;
	else if (code>55) return 11;
	else if (code>7) return 10;
	else return 11;

#endif
}