4701 lines
		
	
	
	
		
			75 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			4701 lines
		
	
	
	
		
			75 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /* lfr ret should little endian */
 | |
| 
 | |
| #define const13(x) ((x) > -4096 && (x) < 4096)
 | |
| #define NULL 0
 | |
| #include "mach_em.h"
 | |
| 
 | |
| define(`RETH_LD',`reg_o1')
 | |
| define(`RETL_LD',`reg_o0')
 | |
| define(`RETH_ST',`reg_i1')
 | |
| define(`RETL_ST',`reg_i0')
 | |
| define(`LIN_NO',`%g6')
 | |
| define(`FIL_NAM',`%g7')
 | |
| 
 | |
| define(`BP_OFFSET',`'WINDOWSIZE)
 | |
| define(`'`EM_BSIZE',EM_BSIZE)
 | |
| define(STACK_CLICK,4)
 | |
| 
 | |
| #if RESOLV_debug
 | |
| define(Comment0)
 | |
| define(Comment)
 | |
| define(Comment2)
 | |
| #else
 | |
| define(Comment0,; `'`)' ; `'`/* */'"	! $1"		; code_combiner`'`(' )
 | |
| define(Comment, ; `'`)' ; `'`/* */'"	! $1 $2"	; code_combiner`'`(' )
 | |
| define(Comment2,; `'`)' ; `'`/* */'"	! $1 $2 $3"	; code_combiner`'`(' )
 | |
| #endif
 | |
| 
 | |
| define(MAX_INT, 0x7fffffff)
 | |
| define(E_EM_CUF, 100)
 | |
| define(E_EM_CFF, 101)
 | |
| define(E_EM_CFI, 102)
 | |
| define(E_EM_CFU, 103)
 | |
| #define MAX_UNROLL	16
 | |
| #undef FAST_LIN_LNI_FIL
 | |
| 
 | |
| 
 | |
| define( narg4,
 | |
| C_$1_narg	==>
 | |
| `	{
 | |
| 		reg_t a;
 | |
| 		int n;
 | |
| 		
 | |
| 		Comment0( $1_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			C_$1 (n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			force_alloc_output();
 | |
| 			"cmp	$a, 4";
 | |
| 			"be	1f";
 | |
| 			"set	EILLINS, $reg_o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			free_output();
 | |
| 		C_$1 (4);
 | |
| 		}
 | |
| 	}.
 | |
| '
 | |
| )
 | |
| 
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*                                                                            */
 | |
| /*			Group 1 : Load instructions			      */
 | |
| /*							 		      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| /*	%fp : frame pointer
 | |
|  *	%sp : stack pointer
 | |
|  *	RETH_XX: High part of return value
 | |
|  *	RETL_XX: Low part of return value
 | |
|  *	LIN_NO : lin_no
 | |
|  *	FIL_NAM: Fil_nam
 | |
|  */
 | |
| 
 | |
| C_loc		==>
 | |
| 			Comment( loc , $1 );
 | |
| 			push_const($1).
 | |
| 
 | |
| 
 | |
| C_lol		==>
 | |
| 		Comment( lol , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 
 | |
| 			if (S1 = find_local($1, NULL)) {
 | |
| 				soft_alloc_reg(S1);
 | |
| 				push_reg(S1);
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				push_const(4);
 | |
| 				C_los(EM_WSIZE);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| 
 | |
| C_loe..		==>
 | |
| 		Comment2( loe.. , $1, $2 );
 | |
| 		{
 | |
| #ifdef FAST_LIN_LNI_FIL
 | |
| 			if ((int*)($1) == (int*)"hol0")
 | |
| 				if ($2 == 0)
 | |
| 					push_reg(reg_lin);
 | |
| 				else if ($2 == 4)
 | |
| 					push_reg(reg_fil);
 | |
| 				else
 | |
| 					arg_error("loe.. hol0+", $2);
 | |
| 			else {
 | |
| #endif
 | |
| 				push_ext($1);
 | |
| 				inc_tos($2);
 | |
| 				push_const(4);
 | |
| 				C_los(EM_WSIZE);
 | |
| #ifdef FAST_LIN_LNI_FIL
 | |
| 			}
 | |
| #endif
 | |
| 		}
 | |
| 		.
 | |
| 
 | |
| C_lil		==>
 | |
| 		Comment( lil , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 			reg_t S2;
 | |
| 
 | |
| 			if (S1 = find_local($1, NULL)) {
 | |
| 				S2 = alloc_reg();
 | |
| 				"ld	[$S1], $S2";
 | |
| 				push_reg(S2);
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				push_const(4);
 | |
| 				C_los(EM_WSIZE);
 | |
| 				push_const(4);
 | |
| 				C_los(EM_WSIZE);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_lof		==>
 | |
| 			Comment( lof , $1 );
 | |
| 			inc_tos($1);
 | |
| 			push_const(4);
 | |
| 			C_los(EM_WSIZE).
 | |
| 
 | |
| C_lal		==>
 | |
| 			Comment( lal , $1 );
 | |
| 			soft_alloc_reg(reg_lb);
 | |
| 			push_reg(reg_lb);
 | |
| 			inc_tos($1).
 | |
| 
 | |
| C_lae..		==>
 | |
| 			Comment2( lae.. , $1, $2 );
 | |
| 			push_ext($1);
 | |
| 			inc_tos($2).
 | |
| 
 | |
| C_lxl
 | |
| 	$1 == 0	==>
 | |
| 			Comment( lxl , $1 );
 | |
| 			soft_alloc_reg(reg_lb);
 | |
| 			push_reg(reg_lb).
 | |
| 	$1 == 1	==>
 | |
| 			Comment( lxl , $1 );
 | |
| 			soft_alloc_reg(reg_lb);
 | |
| 			push_reg(reg_lb);
 | |
| 			inc_tos(EM_BSIZE);
 | |
| 			push_const(4);
 | |
| 			C_los(EM_WSIZE).
 | |
| 	default ==>
 | |
| 			Comment( lxl , $1 );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 				const_str_t n_str;
 | |
| 
 | |
| 				a = alloc_reg();
 | |
| 				b = alloc_reg();
 | |
| 				c = alloc_reg();
 | |
| 				sprint(n_str, "%d", $1);
 | |
| 				"set	$n_str, $a";
 | |
| 				"mov 	$reg_lb, $b";
 | |
| 			"1:	ld	[$b + EM_BSIZE], $c";
 | |
| 				"deccc	$a";
 | |
| 				"bnz	1b";
 | |
| 				"mov	$c, $b";
 | |
| 				push_reg(b);
 | |
| 				free_reg(a);
 | |
| 				free_reg(c);
 | |
| 			}.
 | |
| 
 | |
| C_lxa	==>
 | |
| 	C_lxl($1);
 | |
| 	inc_tos(EM_BSIZE).
 | |
| 
 | |
| C_loi
 | |
| 	( $1 == 1 ) ||
 | |
| 	( $1 == 2 ) ||
 | |
| 	( $1 % 4 == 0 )	==>
 | |
| 			Comment( loi , $1 );
 | |
| 			push_const($1);
 | |
| 			C_los(EM_WSIZE).
 | |
| 
 | |
| 	default		==>
 | |
| 				arg_error( "loi", $1).
 | |
| 
 | |
| C_los
 | |
| 	$1 == 4  ==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		int i;
 | |
| 		char *LD;
 | |
| 		arith size;
 | |
| 		const_str_t n;
 | |
| 		const_str_t size_str;
 | |
| 
 | |
| 		Comment( los, $1);
 | |
| 		if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL) {
 | |
| 			size = pop_const(size_str);
 | |
| 			if (size <= 4) {
 | |
| 				switch (size) {
 | |
| 				case 1: LD = "ldub"; break;
 | |
| 				case 2: LD = "lduh"; break;
 | |
| 				case 4: LD = "ld"; break;
 | |
| 				default: arg_error("C_los", size);
 | |
| 				}
 | |
| 				b = alloc_reg();
 | |
| 				if (type_of_tos() & T_reg2)
 | |
| 				{
 | |
| 					a= pop_reg_reg(&c);
 | |
| 					"$LD	[$a+$c], $b";
 | |
| 					free_reg(a);
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					a = pop_reg_c13(n);
 | |
| 					"$LD	[$a+$n], $b";
 | |
| 					free_reg(a);
 | |
| 				}
 | |
| 				push_reg(b);
 | |
| 			} else if (size <= MAX_UNROLL) {    /* SUB-OPTIMAL */
 | |
| 				inc_tos(size-4);
 | |
| 				for (i = 0; i < size; i += 4) {
 | |
| 					b = alloc_reg();
 | |
| 					if (type_of_tos() & T_reg2)
 | |
| 					{
 | |
| 						a= pop_reg_reg(&c);
 | |
| 						"ld	[$a+$c], $b";
 | |
| 						push_reg(b);
 | |
| 						push_reg(a);
 | |
| 						inc_tos_reg(c);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						a = pop_reg_c13(n);
 | |
| 						"ld	[$a+$n], $b";
 | |
| 						push_reg(b);
 | |
| 						if (n[0] == '-' || isdigit(n[0]))
 | |
| 						{
 | |
| 							push_reg(a);
 | |
| 							inc_tos(atoi(n));
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							b= alloc_reg();
 | |
| 							"add	$a, $n, $b";
 | |
| 							push_reg(b);
 | |
| 							free_reg(a);
 | |
| 						}
 | |
| 					}
 | |
| 					inc_tos(-4);
 | |
| 				}
 | |
| 				pop_nop(1);
 | |
| 			} else
 | |
| 				arg_error ("loi",  size);
 | |
| 		}
 | |
| 		else {
 | |
| 			a = pop_reg();	/* count */
 | |
| 			b = pop_reg();	/* addr */
 | |
| 			c = alloc_reg();
 | |
| 			flush_cache();
 | |
| 			"sub	$reg_sp, $a, $reg_sp"	/* HACK */
 | |
| 		"1:	 deccc	4, $a"
 | |
| 			"ld	[$b+$a], $c"
 | |
| 			"bnz	1b"
 | |
| 			"st	$c, [$reg_sp+$a]"	/* delay */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 		}
 | |
| 	}.
 | |
| 	default ==>
 | |
| 		arg_error("C_los", $1).
 | |
| 
 | |
| 
 | |
| narg4(los)
 | |
| 
 | |
| C_ldl		==>
 | |
| 		Comment( ldl , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 			reg_t S2;
 | |
| 
 | |
| 			if (S1 = find_local($1, &S2)) {
 | |
| 				soft_alloc_reg(S1);
 | |
| 				soft_alloc_reg(S2);
 | |
| 				push_double_reg(S1);
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				push_const(8);
 | |
| 				C_los(EM_WSIZE);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| 
 | |
| C_lde..		==>
 | |
| 			Comment2( lde.. , $1, $2 );
 | |
| 			push_ext($1);
 | |
| 			inc_tos($2);
 | |
| 			push_const(8);
 | |
| 			C_los(EM_WSIZE).
 | |
| 
 | |
| C_ldf		==>
 | |
| 			Comment( ldf , $1 );
 | |
| 			inc_tos($1);
 | |
| 			push_const(8);
 | |
| 			C_los(EM_WSIZE).
 | |
| 
 | |
| C_lpi		==>
 | |
| 			Comment( lpi , $1 );
 | |
| 			push_ext($1).
 | |
| 
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*                                                                            */
 | |
| /*			Group 2 : Store instructions			      */
 | |
| /*							 		      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_stl		==>
 | |
| 		Comment( stl , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 
 | |
| 			if ((S1 = find_local($1, NULL))) {
 | |
| 				pop_reg_as(S1);
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				push_const(4);
 | |
| 				C_sts(EM_WSIZE);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_ste..		==>
 | |
| 			Comment2( ste.. , $1, $2 );
 | |
| 			push_ext($1);
 | |
| 			inc_tos($2);
 | |
| 			push_const(4);
 | |
| 			C_sts(EM_WSIZE).
 | |
| 
 | |
| 
 | |
| C_sil		==>
 | |
| 		Comment( sil , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 			reg_t S2;
 | |
| 
 | |
| 			if (S1 = find_local($1, NULL)) {
 | |
| 				S2 = pop_reg();
 | |
| 				"st	$S2, [$S1]";
 | |
| 				free_reg(S2);
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				push_const(4);
 | |
| 				C_los(EM_WSIZE);
 | |
| 				push_const(4);
 | |
| 				C_sts(EM_WSIZE);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_stf		==>
 | |
| 			Comment( stf , $1 );
 | |
| 			inc_tos($1);
 | |
| 			push_const(4);
 | |
| 			C_sts(EM_WSIZE).
 | |
| 
 | |
| C_sti
 | |
| 	( $1 == 1) ||
 | |
| 	( $1 == 2) ||
 | |
| 	( $1 % 4 == 0 )	==>
 | |
| 			Comment( sti, $1 );
 | |
| 			push_const($1);
 | |
| 			C_sts(EM_WSIZE).
 | |
| 
 | |
| 	default		==>
 | |
| 				arg_error( "sti", $1).
 | |
| 
 | |
| 
 | |
| C_sts
 | |
| 	$1 == 4  ==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 
 | |
| 		arith size;
 | |
| 		const_str_t n;
 | |
| 		const_str_t size_str;
 | |
| 		int i;
 | |
| 		char *ST;
 | |
| 
 | |
| 		Comment( sts, $1);
 | |
| 		if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL) {
 | |
| 
 | |
| 			size = pop_const(size_str);
 | |
| 			if (size <= 4) {
 | |
| 
 | |
| 				switch (size) {
 | |
| 				case 1: ST = "stb"; break;
 | |
| 				case 2: ST = "sth"; break;
 | |
| 				case 4: ST = "st"; break;
 | |
| 				default: arg_error("C_sti", size);
 | |
| 				}
 | |
| 				c= NULL;
 | |
| 				if (type_of_tos() & T_reg2)
 | |
| 					a= pop_reg_reg(&c);
 | |
| 				else
 | |
| 					a = pop_reg_c13(n);
 | |
| 				if (type_of_tos() == T_float) {
 | |
| 					b= pop_float();
 | |
| 					if (size < 4) {
 | |
| 						"st	$b,[%fp+64]";
 | |
| 						free_reg(b);
 | |
| 						b= alloc_reg();
 | |
| 						"ld	[%fp+64],$b";
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 					b = pop_reg();
 | |
| 				if (c)
 | |
| 				{
 | |
| 					"$ST	$b, [$a+$c]";
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 				else
 | |
| 					"$ST	$b, [$a+$n]";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 			} else if (size <= MAX_UNROLL) {
 | |
| 				for (i = 0; i < size; i+=4) {
 | |
| 					c= NULL;
 | |
| 					if (type_of_tos() & T_reg2)
 | |
| 						a= pop_reg_reg(&c);
 | |
| 					else
 | |
| 						a = pop_reg_c13(n);
 | |
| 					if (type_of_tos() == T_float)
 | |
| 						b= pop_float();
 | |
| 					else
 | |
| 						b = pop_reg();
 | |
| 					if (c)
 | |
| 						"st	$b, [$a+$c]";
 | |
| 					else
 | |
| 						"st	$b, [$a+$n]";
 | |
| 					free_reg(b);
 | |
| 					if (c)
 | |
| 					{
 | |
| 						push_reg(a);
 | |
| 						inc_tos_reg(c);
 | |
| 					}
 | |
| 					else if (n[0] == '-' || isdigit(n[0]))
 | |
| 					{
 | |
| 						push_reg(a);
 | |
| 						inc_tos(atoi(n));
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						b= alloc_reg();
 | |
| 						"add	$a, $n, $b";
 | |
| 						push_reg(b);
 | |
| 						free_reg(a);
 | |
| 					}
 | |
| 					inc_tos(4);
 | |
| 				}
 | |
| 				pop_nop(1);
 | |
| 			} else
 | |
| 				arg_error ("sti", size);
 | |
| 		}
 | |
| 		else {
 | |
| 			force_alloc_output();
 | |
| 			d = pop_reg();		/* size */
 | |
| 			a = pop_reg();		/* address */
 | |
| 			flush_cache();
 | |
| 			b = alloc_reg();
 | |
| 			c = alloc_reg();
 | |
| 			"cmp	$d, 4";
 | |
| 			"bg,a	8f";
 | |
| 			"andcc	$d, 3, %g0";	/* delay slot */
 | |
| 			"be,a	4f";
 | |
| 			"ld	[$reg_sp], $b";	/* delay slot */
 | |
| 			"cmp	$d, 1";
 | |
| 			"be,a	1f";
 | |
| 			"ld	[$reg_sp], $b";	/* delay slot */
 | |
| 			"bl	0f";
 | |
| 			"cmp	$d, 2";
 | |
| 			"be	2f";
 | |
| 			"ld	[$reg_sp], $b";	/* delay slot */
 | |
| 		"3:	 set	EILLINS, %o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 			"b	0f";
 | |
| 			"nop";
 | |
| 		"1:";
 | |
| 			"inc	STACK_CLICK, $reg_sp";
 | |
| 			"b	0f";
 | |
| 			"stb	$b, [$a]";	/* delay slot */
 | |
| 		"2:";
 | |
| 			"inc	STACK_CLICK, $reg_sp";
 | |
| 			"b	0f";
 | |
| 			"sth	$b, [$a]";	/* delay slot */
 | |
| 		"4:";
 | |
| 			"inc	STACK_CLICK, $reg_sp";
 | |
| 			"b	0f";
 | |
| 			"st	$b, [$a]";	/* delay slot */
 | |
| 		"8:";
 | |
| 			"bne	3b";
 | |
| 			"nop";
 | |
| 			"mov	$d, $b";
 | |
| 		"9:	 deccc	4, $b";
 | |
| 			"ld	[$reg_sp+$b], $c";
 | |
| 			"bnz	9b";
 | |
| 			"st	$c, [$a+$b]";	/* delay slot */
 | |
| 			"add	$reg_sp, $d, $reg_sp"	/* HACK */
 | |
| 		"0:"
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 			free_output();
 | |
| 		}
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "sts", $1).
 | |
| 
 | |
| narg4(sts)
 | |
| 
 | |
| C_sdl		==>
 | |
| 		Comment( sdl , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 			reg_t S2;
 | |
| 
 | |
| 			S1 = find_local($1, NULL);
 | |
| 			if (S1) 
 | |
| 				pop_double_reg_as(S1);
 | |
| 			else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				push_const(8);
 | |
| 				C_sts(EM_WSIZE);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_sde..		==>
 | |
| 			Comment2( sde.. , $1, $2 );
 | |
| 			push_ext($1);
 | |
| 			inc_tos($2);
 | |
| 			push_const(8);
 | |
| 			C_sts(EM_WSIZE).
 | |
| 
 | |
| C_sdf		==>
 | |
| 			Comment( sdf , $1 );
 | |
| 			inc_tos($1);
 | |
| 			push_const(8);
 | |
| 			C_sts(EM_WSIZE).
 | |
| 
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 3 : Integer arithmetic				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| 
 | |
| C_adi
 | |
| 	$1 == 4	==>
 | |
| 			Comment( adi , $1 );
 | |
| 			if ((type_of_tos()) == T_cst) {
 | |
| 				arith n;
 | |
| 
 | |
| 				n = pop_const(NULL);
 | |
| 				inc_tos(n);
 | |
| 			} else {
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				a = pop_reg();
 | |
| 				inc_tos_reg(a);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 				arg_error( "adi", $1).
 | |
| 
 | |
| narg4(adi)
 | |
| 
 | |
| C_sbi
 | |
| 	$1 == 4	==>
 | |
| 			Comment( sbi , $1 );
 | |
| 			if ((type_of_tos()) == T_cst) {
 | |
| 				arith n;
 | |
| 
 | |
| 				n = pop_const(NULL);
 | |
| 				inc_tos(-n);
 | |
| 			} else {
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				a = pop_reg();
 | |
| 				b = pop_reg();
 | |
| 				c = alloc_reg();
 | |
| 				"sub	$b, $a, $c";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 				arg_error( "sbi", $1).
 | |
| 
 | |
| narg4(sbi)
 | |
| 
 | |
| C_mli
 | |
| 	$1 == 4	==>
 | |
| 	{
 | |
| 		unsigned int n0;
 | |
| 		unsigned int n1;
 | |
| 		reg_t orig;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		unsigned int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment( mli , $1 );
 | |
| 
 | |
| 		if (type_of_tos() == T_cst) {
 | |
| 			n = pop_const(NULL);
 | |
| 			orig = pop_reg();
 | |
| 			c = reg_g0;
 | |
| 			while (n) {
 | |
| 				for (n0 = 0; !(n & 1); n>>=1)
 | |
| 					++n0;
 | |
| 				for (n1 = 0; n & 1; n>>=1)
 | |
| 					++n1;
 | |
| 
 | |
| 				if (n0) {
 | |
| 					a = alloc_reg();
 | |
| 					sprint(n_str, "%d", n0);
 | |
| 					"sll	$orig, $n_str, $a";
 | |
| 					free_reg(orig);
 | |
| 					orig = a;
 | |
| 				}
 | |
| 				if (n1 == 1) {
 | |
| 					if (c == reg_g0) {
 | |
| 						soft_alloc_reg(orig);
 | |
| 						c = orig;
 | |
| 					} else {
 | |
| 						a = alloc_reg();
 | |
| 						"add	$c, $orig, $a";
 | |
| 						free_reg(c);
 | |
| 						c = a;
 | |
| 					}
 | |
| 					n <<= n1;
 | |
| 				} else {
 | |
| 					a = alloc_reg();
 | |
| 					sprint(n_str, "%d", n1);
 | |
| 					"sll	$orig, $n_str, $a";
 | |
| 					b = alloc_reg();
 | |
| 					"sub	$a, $orig, $b";
 | |
| 					free_reg(orig);
 | |
| 					orig = a;
 | |
| 					if (c == reg_g0)
 | |
| 						c = b;
 | |
| 					else {
 | |
| 						a = alloc_reg();
 | |
| 						"add	$c, $b, $a";
 | |
| 						free_reg(b);
 | |
| 						free_reg(c);
 | |
| 						c = a;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			push_reg(c);
 | |
| 			free_reg(orig);
 | |
| 		} else {
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			"call	mli4";
 | |
| 			"nop"			/* delay */
 | |
| 			free_output();
 | |
| 			forced_alloc_reg(reg_o0);
 | |
| 			push_reg(reg_o0);
 | |
| 		}
 | |
| 	}.
 | |
| 	default	==>
 | |
| 			arg_error( "mli", $1).
 | |
| 
 | |
| narg4(mli)
 | |
| 
 | |
| C_dvi
 | |
| 	$1 == 4	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		int n;
 | |
| 		int n_exp;
 | |
| 		const_str_t n_exp_str;
 | |
| 
 | |
| 		Comment( dvi , $1 );
 | |
| #if MATH_DIVIDE
 | |
| 		if (type_of_tos() == T_cst &&
 | |
| 			power_of_2(top_const(), &n_exp))
 | |
| 		{
 | |
| 			sprint (n_exp_str, "%d", n_exp);
 | |
| 			n= pop_const(NULL);
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			"sra	$a, $n_exp_str, $b";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}
 | |
| 		else
 | |
| #endif
 | |
| 		{
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o1);	/* denominator */
 | |
| 			pop_reg_as(reg_o0);	/* numerator */
 | |
| #if MATH_DIVIDE
 | |
| 			"call	mathdvi4";
 | |
| #else
 | |
| 			"call	dvi4";
 | |
| #endif
 | |
| 			"nop"
 | |
| 			free_output();
 | |
| 			forced_alloc_reg(reg_o0);
 | |
| 			push_reg(reg_o0);
 | |
| 		}
 | |
| 	}.
 | |
| 	default	==>
 | |
| 			arg_error( "dvi", $1).
 | |
| 
 | |
| narg4(dvi)
 | |
| 
 | |
| C_rmi
 | |
| 	$1 == 4	==>
 | |
| 			Comment( rmi , $1 );
 | |
| 			{
 | |
| 				force_alloc_output();
 | |
| 				pop_reg_as(reg_o1);	/* denominator */
 | |
| 				pop_reg_as(reg_o0);	/* numerator */
 | |
| #if MATH_DIVIDE
 | |
| 				"call	mathdvi4";
 | |
| #else
 | |
| 				"call	dvi4";
 | |
| #endif
 | |
| 				"nop"
 | |
| 				free_output();
 | |
| 				forced_alloc_reg(reg_o1);
 | |
| 				push_reg(reg_o1);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 			arg_error( "rmi", $1).
 | |
| 
 | |
| narg4(rmi)
 | |
| 
 | |
| C_ngi
 | |
| 	$1 == 4	==>
 | |
| 			Comment( ngi , $1 );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 
 | |
| 				a = pop_reg();
 | |
| 				b = alloc_reg();
 | |
| 				"sub	%g0, $a, $b";
 | |
| 				push_reg(b);
 | |
| 				free_reg(a);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 			arg_error( "ngi", $1).
 | |
| 
 | |
| narg4(ngi)
 | |
| 
 | |
| C_sli
 | |
| 	$1 == 4	==>
 | |
| 			Comment( sli , $1 );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				b = alloc_reg();
 | |
| 				if ((type_of_tos() == T_cst) &&
 | |
| 					(const13(top_const()))) {
 | |
| 					const_str_t n;
 | |
| 
 | |
| 					pop_const(n);
 | |
| 					a = pop_reg();
 | |
| 					"sll	$a, $n, $b";
 | |
| 				} else {
 | |
| 					c = pop_reg();
 | |
| 					a = pop_reg();
 | |
| 					"sll	$a, $c, $b";
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 				free_reg(a);
 | |
| 				push_reg(b);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 			arg_error( "sli", $1).
 | |
| 
 | |
| narg4(sli)
 | |
| 
 | |
| C_sri
 | |
| 	$1 == 4		==>
 | |
| 			Comment( sri , $1 );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				b = alloc_reg();
 | |
| 				if ((type_of_tos() == T_cst) &&
 | |
| 					(const13(top_const()))) {
 | |
| 					const_str_t n;
 | |
| 
 | |
| 					pop_const(n);
 | |
| 					a = pop_reg();
 | |
| 					"sra	$a, $n, $b";
 | |
| 				} else {
 | |
| 					c = pop_reg();
 | |
| 					a = pop_reg();
 | |
| 					"sra	$a, $c, $b";
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 				free_reg(a);
 | |
| 				push_reg(b);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 			arg_error( "sri", $1).
 | |
| 
 | |
| narg4(sri)
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 4 : Unsigned arithmetic 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_adu		==>
 | |
| 			Comment( adu , $1 );
 | |
| 		 	C_adi( w).
 | |
| 
 | |
| narg4(adu)
 | |
| 
 | |
| C_sbu		==>
 | |
| 			Comment( sbu , $1 );
 | |
| 		 	C_sbi( w).
 | |
| 
 | |
| narg4(sbu)
 | |
| 
 | |
| C_mlu
 | |
| 	$1 == 4	==>
 | |
| 		Comment( mlu , $1 );
 | |
| 		C_mli($1).
 | |
| /*
 | |
| 		{
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			"call	mlu4";
 | |
| 			"nop"
 | |
| 			free_output();
 | |
| 			forced_alloc_reg(reg_o0);
 | |
| 			push_reg(reg_o0);
 | |
| 		}.
 | |
| */
 | |
| 	default	==>
 | |
| 			arg_error( "mlu", $1).
 | |
| 
 | |
| narg4(mlu)
 | |
| 
 | |
| C_dvu
 | |
| 	$1 == 4	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		unsigned n;
 | |
| 		int n_exp;
 | |
| 		const_str_t n_exp_str;
 | |
| 
 | |
| 		Comment( dvu , $1 );
 | |
| 		if (type_of_tos() == T_cst &&
 | |
| 			uns_power_of_2(top_const(), &n_exp))
 | |
| 		{
 | |
| 			sprint (n_exp_str, "%d", n_exp);
 | |
| 			n= pop_const(NULL);
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			"srl	$a, $n_exp_str, $b";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o1);	/* denominator */
 | |
| 			pop_reg_as(reg_o0);	/* numerator */
 | |
| 			"call	dvu4";
 | |
| 			"nop"
 | |
| 			free_output();
 | |
| 			forced_alloc_reg(reg_o0);
 | |
| 			push_reg(reg_o0);
 | |
| 		}
 | |
| 	}.
 | |
| 	default	==>
 | |
| 			arg_error( "dvu", $1).
 | |
| 
 | |
| narg4(dvu)
 | |
| 
 | |
| C_rmu
 | |
| 	$1 == 4	==>
 | |
| 		Comment( rmu , $1 );
 | |
| 		{
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			"call	dvu4";
 | |
| 			"nop"
 | |
| 			free_output();
 | |
| 			forced_alloc_reg(reg_o1);
 | |
| 			push_reg(reg_o1);
 | |
| 		}.
 | |
| 	default	==>
 | |
| 			arg_error( "rmu", $1).
 | |
| 
 | |
| narg4(rmu)
 | |
| 
 | |
| C_slu		==>
 | |
| 			Comment( slu , $1 );
 | |
| 			C_sli($1).
 | |
| 
 | |
| narg4(slu)
 | |
| 
 | |
| C_sru
 | |
| 	$1 == 4	==>
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				Comment( sru , $1 );
 | |
| 				b = alloc_reg();
 | |
| 				if ((type_of_tos() == T_cst) &&
 | |
| 					(const13(top_const()))) {
 | |
| 					const_str_t n;
 | |
| 
 | |
| 					pop_const(n);
 | |
| 					a = pop_reg();
 | |
| 					"srl	$a, $n, $b";
 | |
| 				} else {
 | |
| 					c = pop_reg();
 | |
| 					a = pop_reg();
 | |
| 					"srl	$a, $c, $b";
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 				free_reg(a);
 | |
| 				push_reg(b);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 			arg_error( "sru", $1).
 | |
| 
 | |
| narg4(sru)
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 5 : Floating point arithmetic 			      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_adf		==>
 | |
| 	{
 | |
| 		Comment( adf, $1);
 | |
| 		push_const($1);
 | |
| 		C_adf_narg();
 | |
| 	}.
 | |
| 
 | |
| C_adf_narg	==>
 | |
| 	{	
 | |
| 		reg_t f1;
 | |
| 		reg_t f2;
 | |
| 		reg_t f3;
 | |
| 		int n;
 | |
| 
 | |
| 		Comment0( adf_narg);
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				f1= pop_float();
 | |
| 				f2= pop_float();
 | |
| 				f3= alloc_float();
 | |
| 				"fadds	$f2, $f1, $f3";
 | |
| 				free_reg(f1);
 | |
| 				free_reg(f2);
 | |
| 				push_reg(f3);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				f1= pop_double(NULL);
 | |
| 				f2= pop_double(NULL);
 | |
| 				f3= alloc_double(NULL);
 | |
| 				"faddd	$f1, $f2, $f3";
 | |
| 				free_double_reg(f1);
 | |
| 				free_double_reg(f2);
 | |
| 				push_double_reg(f3);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp adf", n);
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("adf_narg");
 | |
| 	}.
 | |
| 
 | |
| C_sbf		==>
 | |
| 	{
 | |
| 		Comment( sbf, $1);
 | |
| 		push_const($1);
 | |
| 		C_sbf_narg();
 | |
| 	}.
 | |
| 
 | |
| C_sbf_narg	==>
 | |
| 	{	
 | |
| 		reg_t f1;
 | |
| 		reg_t f2;
 | |
| 		reg_t f3;
 | |
| 		int n;
 | |
| 
 | |
| 		Comment0( sbf_narg);
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				f1= pop_float();
 | |
| 				f2= pop_float();
 | |
| 				f3= alloc_float();
 | |
| 				"fsubs	$f2, $f1, $f3";
 | |
| 				free_reg(f1);
 | |
| 				free_reg(f2);
 | |
| 				push_reg(f3);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				f1= pop_double(NULL);
 | |
| 				f2= pop_double(NULL);
 | |
| 				f3= alloc_double(NULL);
 | |
| 				"fsubd	$f2, $f1, $f3";
 | |
| 				free_double_reg(f1);
 | |
| 				free_double_reg(f2);
 | |
| 				push_double_reg(f3);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp sbf", n);
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("sbf_narg");
 | |
| 	}.
 | |
| 
 | |
| C_mlf		==>
 | |
| 	{
 | |
| 		Comment( mlf, $1);
 | |
| 		push_const($1);
 | |
| 		C_mlf_narg();
 | |
| 	}.
 | |
| 
 | |
| C_mlf_narg	==>
 | |
| 	{	
 | |
| 		reg_t f1;
 | |
| 		reg_t f2;
 | |
| 		reg_t f3;
 | |
| 		int n;
 | |
| 
 | |
| 		Comment0( mlf_narg);
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				f1= pop_float();
 | |
| 				f2= pop_float();
 | |
| 				f3= alloc_float();
 | |
| 				"fmuls	$f2, $f1, $f3";
 | |
| 				free_reg(f1);
 | |
| 				free_reg(f2);
 | |
| 				push_reg(f3);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				f1= pop_double(NULL);
 | |
| 				f2= pop_double(NULL);
 | |
| 				f3= alloc_double(NULL);
 | |
| 				"fmuld	$f2, $f1, $f3";
 | |
| 				free_double_reg(f1);
 | |
| 				free_double_reg(f2);
 | |
| 				push_double_reg(f3);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp mlf", n);
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("mlf_narg");
 | |
| 	}.
 | |
| 
 | |
| C_dvf		==>
 | |
| 	{
 | |
| 		Comment( dvf, $1);
 | |
| 		push_const($1);
 | |
| 		C_dvf_narg();
 | |
| 	}.
 | |
| 
 | |
| C_dvf_narg	==>
 | |
| 	{	
 | |
| 		reg_t f1;
 | |
| 		reg_t f2;
 | |
| 		reg_t f3;
 | |
| 		int n;
 | |
| 
 | |
| 		Comment0( dvf_narg);
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				f1= pop_float();
 | |
| 				f2= pop_float();
 | |
| 				f3= alloc_float();
 | |
| 				"fdivs	$f2, $f1, $f3";
 | |
| 				free_reg(f1);
 | |
| 				free_reg(f2);
 | |
| 				push_reg(f3);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				f1= pop_double(NULL);
 | |
| 				f2= pop_double(NULL);
 | |
| 				f3= alloc_double(NULL);
 | |
| 				"fdivd	$f2, $f1, $f3";
 | |
| 				free_double_reg(f1);
 | |
| 				free_double_reg(f2);
 | |
| 				push_double_reg(f3);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp dvf", n);
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("dvf_narg");
 | |
| 	}.
 | |
| 
 | |
| C_ngf		==>
 | |
| 	{
 | |
| 		Comment( ngf, $1);
 | |
| 		push_const($1);
 | |
| 		C_ngf_narg();
 | |
| 	}.
 | |
| 
 | |
| C_ngf_narg	==>
 | |
| 	{	
 | |
| 		reg_t f1;
 | |
| 		reg_t f2;
 | |
| 		int n;
 | |
| 
 | |
| 		Comment0( ngf_narg);
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == EM_WSIZE || n == EM_DSIZE)
 | |
| 			{
 | |
| 				f1= pop_float();
 | |
| 				f2= alloc_float();
 | |
| 				"fnegs	$f1, $f2";
 | |
| 				free_reg(f1);
 | |
| 				push_reg(f2);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp ngf", n);
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("ngf_narg");
 | |
| 	}.
 | |
| 
 | |
| C_fif		==>
 | |
| 	Comment( fif, $1);
 | |
| 	push_const($1);
 | |
| 	C_fif_narg().
 | |
| 
 | |
| C_fif_narg	==>
 | |
| 	{
 | |
| 		int n;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 
 | |
| 		Comment0( fif_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 
 | |
| 			if (n==4)
 | |
| 			{
 | |
| 				"! unimplemented fif 4";
 | |
| 				"st	%g0, [%g0]"; /* unimp */
 | |
| 			}
 | |
| 			else if (n==8)
 | |
| 			{
 | |
| 				flush_cache();
 | |
| 				"call	fif8";
 | |
| 				"nop";
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("fif", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= alloc_reg();
 | |
| 			flush_cache();
 | |
| 			force_alloc_output();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= pop_reg();
 | |
| 			"cmp	8, $d";
 | |
| 			"be	8f";
 | |
| 			"nop";
 | |
| 			"cmp	4, $d";
 | |
| 			"bne	0f";
 | |
| 			"nop";
 | |
| 		"4:";
 | |
| 			"! unimplemented fif 4";
 | |
| 			"st	%g0, [%g0]";
 | |
| 			"b	1f";
 | |
| 		"0:";
 | |
| 			"set	EILLINS, $reg_o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 			"b	1f";
 | |
| 		"8:";
 | |
| 			"call	fif8";
 | |
| 			"nop";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 			free_output();
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 
 | |
| C_fef		==>
 | |
| 	Comment( fef, $1);
 | |
| 	push_const($1);
 | |
| 	C_fef_narg().
 | |
| 
 | |
| C_fef_narg	==>
 | |
| 	{
 | |
| 		int n;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		reg_t e;
 | |
| 
 | |
| 		Comment0( fef_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 
 | |
| 			if (n==4)
 | |
| 			{
 | |
| 				"! unimplemented fef 4";
 | |
| 				"st	%g0, [%g0]"; /* unimp */
 | |
| 			}
 | |
| 			else if (n==8)
 | |
| 			{
 | |
| 				flush_cache();
 | |
| 				"call	fef8";
 | |
| 				"nop";
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("fef", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= alloc_reg();
 | |
| 			flush_cache();
 | |
| 			force_alloc_output();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= pop_reg();
 | |
| 			"cmp	8, $d";
 | |
| 			"be	8f";
 | |
| 			"nop";
 | |
| 			"cmp	4, $d";
 | |
| 			"bne	0f";
 | |
| 			"nop";
 | |
| 		"4:";
 | |
| 			"! unimplemented fef 4";
 | |
| 			"st	%g0, [%g0]";
 | |
| 			"b	1f";
 | |
| 		"0:";
 | |
| 			"set	EILLINS, $reg_o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 			"b	1f";
 | |
| 		"8:";
 | |
| 			"call	fef8";
 | |
| 			"nop";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 			free_output();
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 6 : Pointer arithmetic 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_adp		==>
 | |
| 			Comment( adp , $1 );
 | |
| 			inc_tos($1).
 | |
| 
 | |
| C_ads
 | |
| 	$1 == 4	==>
 | |
| 			Comment( ads , $1 );
 | |
| 			if ((type_of_tos()) == T_cst) {
 | |
| 				arith n;
 | |
| 
 | |
| 				n = pop_const(NULL);
 | |
| 				inc_tos(n);
 | |
| 			} else {
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				a = pop_reg();
 | |
| 				inc_tos_reg(a);
 | |
| 			}.
 | |
| 	default		==>
 | |
| 				arg_error( "ads", $1).
 | |
| 
 | |
| narg4(ads)
 | |
| 
 | |
| C_sbs
 | |
| 	$1 == 4	==>
 | |
| 			Comment( sbs , $1 );
 | |
| 
 | |
| 			if ((type_of_tos()) == T_cst) {
 | |
| 				arith n;
 | |
| 
 | |
| 				n = pop_const(NULL);
 | |
| 				inc_tos(-n);
 | |
| 			} else {
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				a = pop_reg();
 | |
| 				b = pop_reg();
 | |
| 				c = alloc_reg();
 | |
| 				"sub	$b, $a, $c";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}.
 | |
| 	default	==>
 | |
| 			arg_error( "sbs", $1).
 | |
| 
 | |
| narg4(sbs)
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 7 : Increment/decrement/zero			      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_inc		==>
 | |
| 			Comment0( inc  );
 | |
| 			inc_tos(1).
 | |
| 
 | |
| C_inl		==>
 | |
| 		Comment( inl , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 
 | |
| 			if (S1 = find_local($1, NULL)) {
 | |
| 				change_reg(S1);
 | |
| 				"inc	1, $S1";
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				C_loi(4);
 | |
| 				C_inc();
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				C_sti(4);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_ine..		==>
 | |
| 		{ 
 | |
| 			char *ename;
 | |
| 			const_str_t evalue;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			Comment2( ine.. , $1, $2 );
 | |
| 			a= alloc_reg();
 | |
| 			b= alloc_reg();
 | |
| 
 | |
| 			ename= $1;
 | |
| 			sprint(evalue, "%d", $2);
 | |
| 			"sethi	%hi($ename+$evalue), $a";
 | |
| 			"ld	[$a+%lo($ename+$evalue)], $b";
 | |
| 			"inc	$b";
 | |
| 			"st	$b, [$a+%lo($ename+$evalue)]"
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| 
 | |
| C_dec		==>
 | |
| 			Comment0( dec );
 | |
| 			inc_tos(-1).
 | |
| 
 | |
| C_del		==>
 | |
| 		Comment( del , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 
 | |
| 			if (S1 = find_local($1, NULL)) {
 | |
| 				change_reg(S1);
 | |
| 				"dec	1, $S1";
 | |
| 			} else {
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				C_loi(4);
 | |
| 				C_dec();
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				C_sti(4);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_dee..		==>
 | |
| 		{ 
 | |
| 			char *ename;
 | |
| 			const_str_t evalue;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			Comment2( dee.. , $1, $2 );
 | |
| 			a= alloc_reg();
 | |
| 			b= alloc_reg();
 | |
| 
 | |
| 			ename= $1;
 | |
| 			sprint(evalue, "%d", $2);
 | |
| 			"sethi	%hi($ename+$evalue), $a";
 | |
| 			"ld	[$a+%lo($ename+$evalue)], $b";
 | |
| 			"dec	$b";
 | |
| 			"st	$b, [$a+%lo($ename+$evalue)]"
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_zrl		==>
 | |
| 		Comment( zrl , $1 );
 | |
| 		{
 | |
| 			reg_t S1;
 | |
| 
 | |
| 			if (S1 = find_local($1, NULL)) {
 | |
| 				change_reg(S1);
 | |
| 				"mov	0, $S1";
 | |
| 			} else {
 | |
| 				push_const(0);
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb);
 | |
| 				inc_tos($1);
 | |
| 				C_sti(4);
 | |
| 			}
 | |
| 		}.
 | |
| 
 | |
| C_zre..		==>
 | |
| 		{ 
 | |
| 			char *ename;
 | |
| 			const_str_t evalue;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			Comment2( zre.. , $1, $2 );
 | |
| 			a= alloc_reg();
 | |
| 
 | |
| 			ename= $1;
 | |
| 			sprint(evalue, "%d", $2);
 | |
| 			"sethi	%hi($ename+$evalue), $a";
 | |
| 			"st	%g0, [$a+%lo($ename+$evalue)]"
 | |
| 			free_reg(a);
 | |
| 		}.
 | |
| 
 | |
| C_zrf 		==>
 | |
| 			Comment( zrf , $1 );
 | |
| 			push_const($1);
 | |
| 			C_zrf_narg().
 | |
| 
 | |
| C_zrf_narg	==>
 | |
| 			Comment0( zrf_narg );
 | |
| 			C_zer_narg().
 | |
| 
 | |
| 
 | |
| C_zer		==>
 | |
| 			Comment( zer, $1);
 | |
| 			push_const($1);
 | |
| 			C_zer_narg().
 | |
| 
 | |
| C_zer_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0( zer_narg);
 | |
| 
 | |
| 		if (type_of_tos() == T_cst && top_const() <= 8)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == 4)
 | |
| 				push_const(0);
 | |
| 			else if (n == 8)
 | |
| 			{
 | |
| 				push_const(0);
 | |
| 				push_const(0);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("zer", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			flush_cache();
 | |
| 			"sub	$reg_sp, $a, $reg_sp";
 | |
| 		"1:"
 | |
| 			"deccc	4, $a";		/* hack */
 | |
| 			"st	%g0, [$reg_sp+$a]";
 | |
| 			"bne	1b";
 | |
| 			"nop";
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 8 : Convert 					      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| /* cii, ciu, cuu, cui are assumed to be called with legal arguments only */
 | |
| 
 | |
| C_cii		==>
 | |
| 	{
 | |
| 		reg_t a;	/* target obj size */
 | |
| 		reg_t b;	/* src obj size */
 | |
| 		int n1;		/* target obj size */
 | |
| 		int n2; 	/* src obj size */
 | |
| 		const_str_t n1_str;
 | |
| 
 | |
| 		Comment0( cii );
 | |
| 		a= NULL;
 | |
| 		b= NULL;
 | |
| 
 | |
| 		if (type_of_tos() != T_cst)
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			n1= pop_const(n1_str);
 | |
| 			if (type_of_tos() != T_cst)
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				"set	$n1_str, $a";
 | |
| 				b= pop_reg();
 | |
| 			}
 | |
| 			else
 | |
| 				n2= pop_const(NULL);
 | |
| 		}
 | |
| 
 | |
| 		if (!a)
 | |
| 		{
 | |
| 			a = pop_reg();
 | |
| 			if (n1 > EM_WSIZE)
 | |
| 				arg_error ("unimp cii", n1);
 | |
| 			if (n2 > EM_WSIZE)
 | |
| 				arg_error ("unimp cii", n2);
 | |
| 			if (n2 < EM_WSIZE) {
 | |
| 				b = alloc_reg();
 | |
| 				if (n2 == 1)
 | |
| 				{
 | |
| 					"sll	$a, 24, $b";
 | |
| 					"sra	$b, 24, $b";
 | |
| 				}
 | |
| 				else if (n2 == 2)
 | |
| 				{
 | |
| 					"sll	$a, 16, $b";
 | |
| 					"sra	$b, 16, $b";
 | |
| 				}
 | |
| 				free_reg(a);
 | |
| 				push_reg(b);
 | |
| 			}
 | |
| 			else
 | |
| 				push_reg(a);
 | |
| 		} else {
 | |
| 			flush_cache();
 | |
| 			"cmp	$a, $b";
 | |
| 			"ble	4f";
 | |
| 			"nop";			/* delay slot */
 | |
| 			"cmp	$b, 1";
 | |
| 			"bne	2f";
 | |
| 			"nop";			/* delay slot */
 | |
| 		"1:";
 | |
| 			"b	3f";
 | |
| 			"ldsb	[$reg_sp+3], $a";	/* delay slot */
 | |
| 		"2:"
 | |
| 			"ldsh	[$reg_sp+2], $a";
 | |
| 		"3:";
 | |
| 			"st	$a, [$reg_sp]";
 | |
| 		"4:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 
 | |
| C_cuu		==>
 | |
| 			Comment0( cuu  );
 | |
| 		 	pop_nop(2).
 | |
| 
 | |
| C_ciu		==>
 | |
| 			Comment0( ciu );
 | |
| 		 	pop_nop(2).
 | |
| 
 | |
| C_cui		==>
 | |
| 			Comment0( cui );
 | |
| 		 	pop_nop(2).
 | |
| 
 | |
| C_cfi		==>
 | |
| 	{
 | |
| 		reg_t a;	/* target (int) size */
 | |
| 		reg_t b;	/* src (float) size */
 | |
| 		reg_t s1;
 | |
| 		reg_t s2;
 | |
| 		reg_t d1;
 | |
| 		reg_t d2;
 | |
| 		int n1;		/* target (int) size */
 | |
| 		int n2;		/* src (float) size */
 | |
| 		const_str_t n1_str;
 | |
| 
 | |
| 		Comment0( cfi );
 | |
| 		a= NULL;
 | |
| 		b= NULL;
 | |
| 		if (type_of_tos() != T_cst)
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			n1= pop_const (n1_str);
 | |
| 			if (type_of_tos() != T_cst)
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				"set	$n1_str, $a";
 | |
| 				b= pop_reg();
 | |
| 			}
 | |
| 			else
 | |
| 				n2= pop_const(NULL);
 | |
| 		}
 | |
| 
 | |
| 		if (!a)
 | |
| 		{
 | |
| 			if (n1 != EM_WSIZE)
 | |
| 				arg_error ("unimp cfi", n1);
 | |
| 			if (n2 == EM_WSIZE)
 | |
| 			{
 | |
| 				s1= pop_float();
 | |
| 				d1= alloc_float();
 | |
| 				"fstoi	$s1, $d1";
 | |
| 				free_reg(s1);
 | |
| 				push_reg(d1);
 | |
| 			}
 | |
| 			else if (n2 == EM_DSIZE)
 | |
| 			{
 | |
| 				s1= pop_double(NULL);
 | |
| 				d1= alloc_float();
 | |
| 				"fdtoi	$s1, $d1";
 | |
| 				free_double_reg(s1);
 | |
| 				push_reg(d1);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp cfi", n2);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 
 | |
| 			d1= alloc_float();
 | |
| 			flush_cache();
 | |
| 			force_alloc_output();
 | |
| 			"cmp	$a, 4";
 | |
| 			"bne	0f";
 | |
| 			"nop";
 | |
| 			"cmp	$b, 4";
 | |
| 			"be	4f";
 | |
| 			"nop";
 | |
| 			"cmp	$b, 8";
 | |
| 			"bne	0f";
 | |
| 			"nop";
 | |
| 		"8:";
 | |
| 			"ld	[$reg_sp], %f0";
 | |
| 			"ld	[$reg_sp+STACK_CLICK], %f1";
 | |
| 			"fdtoi	%f0, $d1";
 | |
| 			"b	1f";
 | |
| 			"inc	2*STACK_CLICK, $reg_sp"; /* delay slot */
 | |
| 		"4:";
 | |
| 			"ld	[$reg_sp+2*STACK_CLICK], %f0";
 | |
| 			"fstoi	%f0, $d1";
 | |
| 			"b	1f";
 | |
| 			"inc	STACK_CLICK, $reg_sp"; /* delay slot */
 | |
| 		"0:";
 | |
| 			"set	E_EM_CFI, %o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			push_reg(d1);
 | |
| 			free_output();
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_cfu		==>
 | |
| 	{
 | |
| 		reg_t a;	/* target (int) size */
 | |
| 		reg_t b;	/* src (float) size */
 | |
| 		int n1;		/* target (int) size */
 | |
| 		int n2;		/* src (float) size */
 | |
| 		const_str_t n1_str;
 | |
| 
 | |
| 		Comment0( cfu );
 | |
| 		a= NULL;
 | |
| 		b= NULL;
 | |
| 		if (type_of_tos() != T_cst)
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			n1= pop_const (n1_str);
 | |
| 			if (type_of_tos() != T_cst)
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				"set	$n1_str, $a";
 | |
| 				b= pop_reg();
 | |
| 			}
 | |
| 			else
 | |
| 				n2= pop_const(NULL);
 | |
| 		}
 | |
| 
 | |
| 		if (!a)
 | |
| 		{
 | |
| 			if (n1 != EM_WSIZE)
 | |
| 				arg_error ("unimp cfu", n1);
 | |
| 			force_alloc_output();
 | |
| 			flush_cache();
 | |
| 			if (n2 == EM_WSIZE)
 | |
| 			{
 | |
| 				"call cfu4";
 | |
| 				"nop";
 | |
| 			}
 | |
| 			else if (n2 == EM_DSIZE)
 | |
| 			{
 | |
| 				"call cfu8";
 | |
| 				"nop";
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp cfu", n2);
 | |
| 			soft_alloc_reg(reg_o0);
 | |
| 			free_output();
 | |
| 			push_reg(reg_o0);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			flush_cache();
 | |
| 			force_alloc_output();
 | |
| 			"cmp	$a, 4";
 | |
| 			"bne	0f";
 | |
| 			"nop";
 | |
| 			"cmp	$b, 4";
 | |
| 			"be	4f";
 | |
| 			"nop";
 | |
| 			"cmp	$b, 8";
 | |
| 			"bne	0f";
 | |
| 			"nop";
 | |
| 		"8:";
 | |
| 			"call	cfu8";
 | |
| 			"nop";
 | |
| 			"b	1f";
 | |
| 		"4:";
 | |
| 			"call	cfu4";
 | |
| 			"nop";
 | |
| 			"b	1f";
 | |
| 		"0:";
 | |
| 			"set	E_EM_CFU, %o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			soft_alloc_reg(reg_o0);
 | |
| 			free_output();
 | |
| 			push_reg(reg_o0);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_cff		==>
 | |
| 	{
 | |
| 		reg_t a;	/* target (int) size */
 | |
| 		reg_t b;	/* src (float) size */
 | |
| 		int n1;		/* target (int) size */
 | |
| 		int n2;		/* src (float) size */
 | |
| 		const_str_t n1_str;
 | |
| 
 | |
| 		Comment0( cff );
 | |
| 		a= NULL;
 | |
| 		b= NULL;
 | |
| 		if (type_of_tos() != T_cst)
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			n1= pop_const (n1_str);
 | |
| 			if (type_of_tos() != T_cst)
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				"set	$n1_str, $a";
 | |
| 				b= pop_reg();
 | |
| 			}
 | |
| 			else
 | |
| 				n2= pop_const(NULL);
 | |
| 		}
 | |
| 
 | |
| 		if (!a)
 | |
| 		{
 | |
| 			if (n1 == EM_WSIZE)
 | |
| 			{
 | |
| 				if (n2 == EM_DSIZE)
 | |
| 				{
 | |
| 					a= pop_double(NULL);
 | |
| 					b= alloc_float();
 | |
| 					"fdtos	$a, $b";
 | |
| 					free_double_reg(a);
 | |
| 					push_reg(b);
 | |
| 				} else if (n2 != EM_WSIZE)
 | |
| 					arg_error ("unimp cff", n2);
 | |
| 			}
 | |
| 			else if (n1 == EM_DSIZE)
 | |
| 			{
 | |
| 				if (n2 == EM_WSIZE)
 | |
| 				{
 | |
| 					a= pop_float();
 | |
| 					b= alloc_double(NULL);
 | |
| 					"fstod	$a, $b";
 | |
| 					free_reg(a);
 | |
| 					push_double_reg(b);
 | |
| 				} else if (n2 != EM_DSIZE)
 | |
| 					arg_error ("unimp cff", n2);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp cff", n1);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 
 | |
| 			flush_cache();
 | |
| 			force_alloc_output();
 | |
| 			"cmp	$b, $a";
 | |
| 			"be	1f";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"cmp	$b, 4";
 | |
| 			"be	4f";
 | |
| 			"nop";
 | |
| 			"cmp	$b, 8";
 | |
| 			"be	8f";
 | |
| 			"nop";
 | |
| 		"0:"
 | |
| 			"set	E_EM_CFF, %o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 		"4:";
 | |
| 			"cmp	$a, 8";
 | |
| 			"bne	0b";
 | |
| 			"nop";
 | |
| 			"ld	[$reg_sp], %f0";
 | |
| 			"fstod	%f0, %f2";
 | |
| 			"dec	STACK_CLICK, $reg_sp";
 | |
| 			"st	%f2, [$reg_sp]";
 | |
| 			"st	%f3, [$reg_sp+STACK_CLICK]";
 | |
| 			"b	1f";
 | |
| 			"nop";
 | |
| 		"8:";
 | |
| 			"cmp	$a, 4";
 | |
| 			"bne	0b";
 | |
| 			"nop";
 | |
| 			"ld	[$reg_sp], %f0";
 | |
| 			"ld	[$reg_sp+STACK_CLICK], %f1";
 | |
| 			"fdtos	%f0, %f2";
 | |
| 			"inc	STACK_CLICK, $reg_sp";
 | |
| 			"st	%f2, [$reg_sp]";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_output();
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_cif		==>
 | |
| 	{
 | |
| 		reg_t a;	/* target (float) size */
 | |
| 		reg_t b;	/* src (int) size */
 | |
| 		int n1;		/* target (float) size */
 | |
| 		int n2;		/* src (int) size */
 | |
| 		reg_t r1;
 | |
| 		reg_t f1;
 | |
| 		const_str_t n1_str;
 | |
| 
 | |
| 		Comment0( cif );
 | |
| 		a= NULL;
 | |
| 		b= NULL;
 | |
| 		if (type_of_tos() != T_cst)
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			n1= pop_const (n1_str);
 | |
| 			if (type_of_tos() != T_cst)
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				"set	$n1_str, $a";
 | |
| 				b= pop_reg();
 | |
| 			}
 | |
| 			else
 | |
| 				n2= pop_const(NULL);
 | |
| 		}
 | |
| 
 | |
| 		if (!a)
 | |
| 		{
 | |
| 			if (n2 != EM_WSIZE)
 | |
| 				arg_error ("unimp cif", n2);
 | |
| 			else
 | |
| 			{
 | |
| 				if (n1 == EM_WSIZE)
 | |
| 				{
 | |
| 					r1= pop_float();
 | |
| 					f1= alloc_float();
 | |
| 					"fitos	$r1, $f1";
 | |
| 					free_reg(r1);
 | |
| 					push_reg(f1);
 | |
| 
 | |
| 				}
 | |
| 				else if (n1 == EM_DSIZE)
 | |
| 				{
 | |
| 					r1= pop_float();
 | |
| 					f1= alloc_double(NULL);
 | |
| 					"fitod	$r1, $f1";
 | |
| 					free_reg(r1);
 | |
| 					push_double_reg(f1);
 | |
| 				}
 | |
| 				else
 | |
| 					arg_error ("unimp cif", n1);
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			flush_cache();
 | |
| 			force_alloc_output();
 | |
| 			"cmp	$a, 4";
 | |
| 			"be	4f";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"cmp	$a, 8";
 | |
| 			"be	8f";
 | |
| 			"nop";		/* delay slot */
 | |
| 		"1:"
 | |
| 			"set	E_EM_CUF, %o0";
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 		"4:";
 | |
| 			"cmp	$b, 4";
 | |
| 			"bne	1b";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"ld	[$reg_sp], %f0";
 | |
| 			"fitos	%f0, %f1";
 | |
| 			"b	0f";
 | |
| 			"st	%f1, [$reg_sp]";	/* delay slot */
 | |
| 		"8:";
 | |
| 			"dec	STACK_CLICK, $reg_sp";
 | |
| 			"cmp	$b, 4";
 | |
| 			"bne	1b";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"ld	[$reg_sp+STACK_CLICK], %f0";
 | |
| 			"fitod	%f0, %f2";
 | |
| 			"st	%f2, [$reg_sp]";
 | |
| 			"b	0f";
 | |
| 			"st	%f3, [$reg_sp+STACK_CLICK]"; /* delay slot */
 | |
| 		"0:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_output();
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 
 | |
| C_cuf		==>
 | |
| 	{
 | |
| 		reg_t a;	/* target (float) size */
 | |
| 		reg_t b;	/* src (int) size */
 | |
| 		reg_t c;
 | |
| 		reg_t fs1;
 | |
| 		reg_t fs2;
 | |
| 		reg_t fd1;
 | |
| 		reg_t fd2;
 | |
| 		int n1;		/* target (float) size */
 | |
| 		int n2;		/* src (int) size */
 | |
| 		const_str_t n1_str;
 | |
| 
 | |
| 		Comment0( cuf );
 | |
| 		a= NULL;
 | |
| 		b= NULL;
 | |
| 		if (type_of_tos() != T_cst)
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			n1= pop_const (n1_str);
 | |
| 			if (type_of_tos() != T_cst)
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				"set	$n1_str, $a";
 | |
| 				b= pop_reg();
 | |
| 			}
 | |
| 			else
 | |
| 				n2= pop_const(NULL);
 | |
| 		}
 | |
| 
 | |
| 		if (!a)
 | |
| 		{
 | |
| 			if (n2 != EM_WSIZE)
 | |
| 				arg_error ("unimp cuf", n2);
 | |
| 			else
 | |
| 			{
 | |
| 				if (n1 == EM_WSIZE)
 | |
| 				{
 | |
| 					fs1= pop_float();
 | |
| 					fs2= alloc_float();
 | |
| 					a= alloc_reg();
 | |
| 					"fitos	$fs1, $fs2";
 | |
| 					"sethi	%hi(Fs0), $a";
 | |
| 					"ld	[$a+%lo(Fs0)], $fs1";
 | |
| 					"fcmpes	$fs2, $fs1";
 | |
| 					"nop";
 | |
| 					"fbge	0f";
 | |
| 					"nop";
 | |
| 					"sethi	%hi(Fs80000000), $a";
 | |
| 					"ld	[$a+%lo(Fs80000000)], $fs1";
 | |
| 					"fadds	$fs1, $fs2, $fs2";
 | |
| 				"0:";
 | |
| 					push_reg(fs2);
 | |
| 					free_reg(fs1);
 | |
| 					free_reg(a);
 | |
| 				}
 | |
| 				else if (n1 == EM_DSIZE)
 | |
| 				{
 | |
| 					fs1= pop_float();
 | |
| 					fd1= alloc_double(NULL);
 | |
| 					fd2= alloc_double(NULL);
 | |
| 					a= alloc_reg();
 | |
| 					"fitod	$fs1, $fd2";
 | |
| 					"sethi	%hi(Fd0), $a";
 | |
| 					"ldd	[$a+%lo(Fd0)], $fd1";
 | |
| 					"fcmped	$fd2, $fd1";
 | |
| 					"nop";
 | |
| 					"fbge	0f";
 | |
| 					"nop";
 | |
| 					"sethi	%hi(Fd80000000), $a";
 | |
| 					"ldd	[$a+%lo(Fd80000000)], $fd1";
 | |
| 					"faddd	$fd1, $fd2, $fd2";
 | |
| 				"0:";
 | |
| 					free_reg(fs1);
 | |
| 					free_double_reg(fd1);
 | |
| 					push_double_reg(fd2);
 | |
| 					free_reg(a);
 | |
| 				}
 | |
| 				else
 | |
| 					arg_error ("unimp cuf", n1);
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| #if 0
 | |
| 			flush_cache();
 | |
| 
 | |
| 			"cmp	$a, 4";
 | |
| 			"be	4f";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"cmp	$a, 8";
 | |
| 			"be	8f";
 | |
| 			"nop";		/* delay slot */
 | |
| 		"1:"
 | |
| 			"set	E_EM_CUF, %o0";
 | |
| 			"set	fatal, %g1";
 | |
| 			"jmp	%g1";
 | |
| 			"nop";
 | |
| 		"4:";
 | |
| 			"cmp	$b, 4";
 | |
| 			"bne	1b";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"ld	[$reg_sp], $c";
 | |
| 			"tst	$c";
 | |
| 			"bl	5f";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"ld	[$reg_sp], %f0";
 | |
| 			"fitos	%f0, %f1";
 | |
| 			"b	0f";
 | |
| 			"st	%f1, [$reg_sp]";	/* delay slot */
 | |
| 		"5:";
 | |
| 			"set	MAX_INT, $b";
 | |
| 			"sub	$c, $b, $a";
 | |
| 			"st	$a, [$reg_sp]";
 | |
| 			"ld	[$reg_sp], %f0";
 | |
| 			"st	$b, [$reg_sp]";
 | |
| 			"ld	[$reg_sp], %f1";
 | |
| 			"fitos	%f0, %f2";
 | |
| 			"fitos	%f1, %f3";
 | |
| 			"fadds	%f2, %f3, %f0";
 | |
| 			"b	0f";
 | |
| 			"st	%f0, [$reg_sp]";		/* delay slot */
 | |
| 		"8:";
 | |
| 			"dec	STACK_CLICK, $reg_sp";
 | |
| 			"cmp	$b, 4";
 | |
| 			"bne	1b";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"ld	[$reg_sp+STACK_CLICK], $c";
 | |
| 			"tst	$c";
 | |
| 			"bl	9f";
 | |
| 			"nop";		/* delay slot */
 | |
| 			"ld	[$reg_sp+STACK_CLICK], %f0";
 | |
| 			"fitod	%f0, %f2";
 | |
| 			"st	%f2, [$reg_sp]";
 | |
| 			"b	0f";
 | |
| 			"st	%f3, [$reg_sp+STACK_CLICK]";	/* delay slot */
 | |
| 		"9:";
 | |
| 			"set	MAX_INT, $b";
 | |
| 			"sub	$c, $b, $a";
 | |
| 			"st	$a, [$reg_sp+STACK_CLICK]";
 | |
| 			"ld	[$reg_sp+STACK_CLICK], %f0";
 | |
| 			"st	$b, [$reg_sp+STACK_CLICK]";
 | |
| 			"ld	[$reg_sp+STACK_CLICK], %f1";
 | |
| 			"fitod	%f0, %f2";
 | |
| 			"fitod	%f1, %f4";
 | |
| 			"fadds	%f2, %f4, %f0";
 | |
| 			"st	%f0, [$reg_sp]";
 | |
| 			"b	0f";
 | |
| 			"st	%f1, [$reg_sp+STACK_CLICK]";	/* delay slot */
 | |
| 		"0:";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| #else
 | |
| 	not_implemented ("cuf");
 | |
| #endif
 | |
| 		}
 | |
| 	}.
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 9 : Logical 	 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_and		==>
 | |
| 	Comment( and, $1);
 | |
| 	push_const($1);
 | |
| 	C_and_narg().
 | |
| 
 | |
| C_and_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		reg_t e;
 | |
| 		reg_t f;
 | |
| 		const_str_t a_cst_str;
 | |
| 		const_str_t b_cst_str;
 | |
| 		const_str_t c_cst_str;
 | |
| 		const_str_t d_cst_str;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0( and_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					a= NULL;
 | |
| 					pop_const (a_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					a= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					b= NULL;
 | |
| 					pop_const (b_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					b= pop_reg();
 | |
| 				if (!a && !b)
 | |
| 				{
 | |
| 					a= alloc_reg();
 | |
| 					"mov	$a_cst_str, $a";	
 | |
| 				}
 | |
| 				c= alloc_reg();
 | |
| 				if (a)
 | |
| 					if (b)
 | |
| 						"and	$a, $b, $c";
 | |
| 					else
 | |
| 						"and	$a, $b_cst_str, $c";
 | |
| 				else
 | |
| 					"and	$b, $a_cst_str, $c";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					a= NULL;
 | |
| 					pop_const (a_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					a= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					b= NULL;
 | |
| 					pop_const (b_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					b= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					c= NULL;
 | |
| 					pop_const (c_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					c= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					d= NULL;
 | |
| 					pop_const (d_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					d= pop_reg();
 | |
| 				if (!b && !d)
 | |
| 				{
 | |
| 					b= alloc_reg();
 | |
| 					"mov	$b_cst_str, $b";	
 | |
| 				}
 | |
| 				e= alloc_reg();
 | |
| 				if (b)
 | |
| 					if (d)
 | |
| 						"and	$b, $d, $e";
 | |
| 					else
 | |
| 						"and	$b, $d_cst_str, $e";
 | |
| 				else
 | |
| 					"and	$d, $b_cst_str, $e";
 | |
| 				free_reg(b);
 | |
| 				free_reg(d);
 | |
| 				push_reg(e);
 | |
| 				if (!a && !c)
 | |
| 				{
 | |
| 					a= alloc_reg();
 | |
| 					"mov	$a_cst_str, $a";	
 | |
| 				}
 | |
| 				e= alloc_reg();
 | |
| 				if (a)
 | |
| 					if (c)
 | |
| 						"and	$a, $c, $e";
 | |
| 					else
 | |
| 						"and	$a, $c_cst_str, $e";
 | |
| 				else
 | |
| 					"and	$c, $a_cst_str, $e";
 | |
| 				free_reg(a);
 | |
| 				free_reg(c);
 | |
| 				push_reg(e);
 | |
| 			}
 | |
| 			else if (!(n % EM_WSIZE))
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				b= alloc_reg();
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				e= alloc_reg();
 | |
| 				f= alloc_reg();
 | |
| 				flush_cache();
 | |
| 
 | |
| 				"set	$n_str, $a";
 | |
| 				"add	$reg_sp, $a, $b";
 | |
| 				"mov	$a, $c";
 | |
| 			"1:";
 | |
| 				"deccc	4, $c";
 | |
| 				"ld	[$reg_sp+$c], $d";
 | |
| 				"ld	[$b+$c], $e";
 | |
| 				"and	$d, $e, $f";
 | |
| 				"bnz	1b";
 | |
| 				"st	$f, [$b+$c]";	/* delay slot */
 | |
| 				"add	$reg_sp, $a, $reg_sp";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				free_reg(c);
 | |
| 				free_reg(d);
 | |
| 				free_reg(e);
 | |
| 				free_reg(f);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp and", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			e= alloc_reg();
 | |
| 			f= alloc_reg();
 | |
| 			flush_cache();
 | |
| 
 | |
| 			"add	$reg_sp, $a, $b";
 | |
| 			"mov	$a, $c";
 | |
| 		"1:";
 | |
| 			"deccc	4, $c";
 | |
| 			"ld	[$reg_sp+$c], $d";
 | |
| 			"ld	[$b+$c], $e";
 | |
| 			"and	$d, $e, $f";
 | |
| 			"bnz	1b";
 | |
| 			"st	$f, [$b+$c]";	/* delay slot */
 | |
| 			"add	$reg_sp, $a, $reg_sp";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 			free_reg(e);
 | |
| 			free_reg(f);
 | |
| 			
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_ior		==>
 | |
| 	Comment( ior, $1);
 | |
| 	push_const($1);
 | |
| 	C_ior_narg().
 | |
| 
 | |
| C_ior_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		reg_t e;
 | |
| 		reg_t f;
 | |
| 		const_str_t a_cst_str;
 | |
| 		const_str_t b_cst_str;
 | |
| 		const_str_t c_cst_str;
 | |
| 		const_str_t d_cst_str;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0( ior_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					a= NULL;
 | |
| 					pop_const (a_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					a= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					b= NULL;
 | |
| 					pop_const (b_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					b= pop_reg();
 | |
| 				if (!a && !b)
 | |
| 				{
 | |
| 					a= alloc_reg();
 | |
| 					"mov	$a_cst_str, $a";	
 | |
| 				}
 | |
| 				c= alloc_reg();
 | |
| 				if (a)
 | |
| 					if (b)
 | |
| 						"or	$a, $b, $c";
 | |
| 					else
 | |
| 						"or	$a, $b_cst_str, $c";
 | |
| 				else
 | |
| 					"or	$b, $a_cst_str, $c";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					a= NULL;
 | |
| 					pop_const (a_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					a= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					b= NULL;
 | |
| 					pop_const (b_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					b= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					c= NULL;
 | |
| 					pop_const (c_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					c= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					d= NULL;
 | |
| 					pop_const (d_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					d= pop_reg();
 | |
| 				if (!b && !d)
 | |
| 				{
 | |
| 					b= alloc_reg();
 | |
| 					"mov	$b_cst_str, $b";	
 | |
| 				}
 | |
| 				e= alloc_reg();
 | |
| 				if (b)
 | |
| 					if (d)
 | |
| 						"or	$b, $d, $e";
 | |
| 					else
 | |
| 						"or	$b, $d_cst_str, $e";
 | |
| 				else
 | |
| 					"or	$d, $b_cst_str, $e";
 | |
| 				free_reg(b);
 | |
| 				free_reg(d);
 | |
| 				push_reg(e);
 | |
| 				if (!a && !c)
 | |
| 				{
 | |
| 					a= alloc_reg();
 | |
| 					"mov	$a_cst_str, $a";	
 | |
| 				}
 | |
| 				e= alloc_reg();
 | |
| 				if (a)
 | |
| 					if (c)
 | |
| 						"or	$a, $c, $e";
 | |
| 					else
 | |
| 						"or	$a, $c_cst_str, $e";
 | |
| 				else
 | |
| 					"or	$c, $a_cst_str, $e";
 | |
| 				free_reg(a);
 | |
| 				free_reg(c);
 | |
| 				push_reg(e);
 | |
| 			}
 | |
| 			else if (!(n % EM_WSIZE))
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				b= alloc_reg();
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				e= alloc_reg();
 | |
| 				f= alloc_reg();
 | |
| 				flush_cache();
 | |
| 
 | |
| 				"set	$n_str, $a";
 | |
| 				"add	$reg_sp, $a, $b";
 | |
| 				"mov	$a, $c";
 | |
| 			"1:";
 | |
| 				"deccc	4, $c";
 | |
| 				"ld	[$reg_sp+$c], $d";
 | |
| 				"ld	[$b+$c], $e";
 | |
| 				"or	$d, $e, $f";
 | |
| 				"bnz	1b";
 | |
| 				"st	$f, [$b+$c]";	/* delay slot */
 | |
| 				"add	$reg_sp, $a, $reg_sp";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				free_reg(c);
 | |
| 				free_reg(d);
 | |
| 				free_reg(e);
 | |
| 				free_reg(f);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp ior", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			e= alloc_reg();
 | |
| 			f= alloc_reg();
 | |
| 			flush_cache();
 | |
| 
 | |
| 			"add	$reg_sp, $a, $b";
 | |
| 			"mov	$a, $c";
 | |
| 		"1:";
 | |
| 			"deccc	4, $c";
 | |
| 			"ld	[$reg_sp+$c], $d";
 | |
| 			"ld	[$b+$c], $e";
 | |
| 			"or	$d, $e, $f";
 | |
| 			"bnz	1b";
 | |
| 			"st	$f, [$b+$c]";	/* delay slot */
 | |
| 			"add	$reg_sp, $a, $reg_sp";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 			free_reg(e);
 | |
| 			free_reg(f);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 
 | |
| 
 | |
| C_xor		==>
 | |
| 	Comment( xor, $1);
 | |
| 	push_const($1);
 | |
| 	C_xor_narg().
 | |
| 
 | |
| C_xor_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		reg_t e;
 | |
| 		reg_t f;
 | |
| 		const_str_t a_cst_str;
 | |
| 		const_str_t b_cst_str;
 | |
| 		const_str_t c_cst_str;
 | |
| 		const_str_t d_cst_str;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0( xor_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					a= NULL;
 | |
| 					pop_const (a_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					a= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					b= NULL;
 | |
| 					pop_const (b_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					b= pop_reg();
 | |
| 				if (!a && !b)
 | |
| 				{
 | |
| 					a= alloc_reg();
 | |
| 					"mov	$a_cst_str, $a";	
 | |
| 				}
 | |
| 				c= alloc_reg();
 | |
| 				if (a)
 | |
| 					if (b)
 | |
| 						"xor	$a, $b, $c";
 | |
| 					else
 | |
| 						"xor	$a, $b_cst_str, $c";
 | |
| 				else
 | |
| 					"xor	$b, $a_cst_str, $c";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					a= NULL;
 | |
| 					pop_const (a_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					a= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					b= NULL;
 | |
| 					pop_const (b_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					b= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					c= NULL;
 | |
| 					pop_const (c_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					c= pop_reg();
 | |
| 				if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 				{
 | |
| 					d= NULL;
 | |
| 					pop_const (d_cst_str);
 | |
| 				}
 | |
| 				else
 | |
| 					d= pop_reg();
 | |
| 				if (!b && !d)
 | |
| 				{
 | |
| 					b= alloc_reg();
 | |
| 					"mov	$b_cst_str, $b";	
 | |
| 				}
 | |
| 				e= alloc_reg();
 | |
| 				if (b)
 | |
| 					if (d)
 | |
| 						"xor	$b, $d, $e";
 | |
| 					else
 | |
| 						"xor	$b, $d_cst_str, $e";
 | |
| 				else
 | |
| 					"xor	$d, $b_cst_str, $e";
 | |
| 				free_reg(b);
 | |
| 				free_reg(d);
 | |
| 				push_reg(e);
 | |
| 				if (!a && !c)
 | |
| 				{
 | |
| 					a= alloc_reg();
 | |
| 					"mov	$a_cst_str, $a";	
 | |
| 				}
 | |
| 				e= alloc_reg();
 | |
| 				if (a)
 | |
| 					if (c)
 | |
| 						"xor	$a, $c, $e";
 | |
| 					else
 | |
| 						"xor	$a, $c_cst_str, $e";
 | |
| 				else
 | |
| 					"xor	$c, $a_cst_str, $e";
 | |
| 				free_reg(a);
 | |
| 				free_reg(c);
 | |
| 				push_reg(e);
 | |
| 			}
 | |
| 			else if (!(n % EM_WSIZE))
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				b= alloc_reg();
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				e= alloc_reg();
 | |
| 				f= alloc_reg();
 | |
| 				flush_cache();
 | |
| 
 | |
| 				"set	$n_str, $a";
 | |
| 				"add	$reg_sp, $a, $b";
 | |
| 				"mov	$a, $c";
 | |
| 			"1:";
 | |
| 				"deccc	4, $c";
 | |
| 				"ld	[$reg_sp+$c], $d";
 | |
| 				"ld	[$b+$c], $e";
 | |
| 				"xor	$d, $e, $f";
 | |
| 				"bnz	1b";
 | |
| 				"st	$f, [$b+$c]";	/* delay slot */
 | |
| 				"add	$reg_sp, $a, $reg_sp";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				free_reg(c);
 | |
| 				free_reg(d);
 | |
| 				free_reg(e);
 | |
| 				free_reg(f);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("unimp xor", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			e= alloc_reg();
 | |
| 			f= alloc_reg();
 | |
| 			flush_cache();
 | |
| 
 | |
| 			"add	$reg_sp, $a, $b";
 | |
| 			"mov	$a, $c";
 | |
| 		"1:";
 | |
| 			"deccc	4, $c";
 | |
| 			"ld	[$reg_sp+$c], $d";
 | |
| 			"ld	[$b+$c], $e";
 | |
| 			"xor	$d, $e, $f";
 | |
| 			"bnz	1b";
 | |
| 			"st	$f, [$b+$c]";	/* delay slot */
 | |
| 			"add	$reg_sp, $a, $reg_sp";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 			free_reg(e);
 | |
| 			free_reg(f);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 
 | |
| 
 | |
| C_com		==>
 | |
| 	Comment( com, $1);
 | |
| 	push_const($1);
 | |
| 	C_com_narg().
 | |
| 
 | |
| C_com_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		int n;
 | |
| 		int i;
 | |
| 		const_str_t i_str;
 | |
| 
 | |
| 		Comment0( com_narg );
 | |
| 		if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == 4)
 | |
| 			{
 | |
| 				a= pop_reg();
 | |
| 				b= alloc_reg();
 | |
| 				"not	$a, $b";
 | |
| 				free_reg(a);
 | |
| 				push_reg(b);
 | |
| 			}
 | |
| 			else if (n == 8)
 | |
| 			{
 | |
| 				a= pop_reg();
 | |
| 				b= pop_reg();
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				"not	$a, $c";
 | |
| 				"not	$b, $d";
 | |
| 				push_reg(d);
 | |
| 				push_reg(c);
 | |
| 				free_reg(b);
 | |
| 				free_reg(a);
 | |
| 			}
 | |
| 			else if (n>0 && !(n % 4))
 | |
| 			{
 | |
| 				flush_cache();
 | |
| 				a= alloc_reg();
 | |
| 				b= alloc_reg();
 | |
| 				for (i= 0; i< n; i += 4)
 | |
| 				{
 | |
| 					sprint(i_str, "%d", i);
 | |
| 					"ld	[$reg_sp+$i_str], $a";
 | |
| 					"not	$a, $b";
 | |
| 					"st	$b, [$reg_sp+$i_str]";
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("com", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			flush_cache();
 | |
| 		"1:";
 | |
| 			"deccc	4, $a";
 | |
| 			"ld	[$reg_sp+$a], $b";
 | |
| 			"not	$a, $c";
 | |
| 			"bnz	1b";
 | |
| 			"st	$c, [$reg_sp+$a";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_rol
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment( rol, $1);
 | |
| 
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n<0)
 | |
| 				arg_error("rol 4:", n);
 | |
| 			else
 | |
| 			{
 | |
| 				n= n % 32;
 | |
| 				if (n)
 | |
| 				{
 | |
| 					a= pop_reg();
 | |
| 					b= alloc_reg();
 | |
| 					c= alloc_reg();
 | |
| 					sprint(n_str, "%d", n);
 | |
| 					"sll	$a, $n_str, $b";
 | |
| 					sprint(n_str, "%d", 32-n);
 | |
| 					"srl	$a, $n_str, $c";
 | |
| 					"or	$b, $c, $a";
 | |
| 					push_reg(a);
 | |
| 					free_reg(b);
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			"and	$a, 31, $c";
 | |
| 			"mov	32, $a";
 | |
| 			"sub	$a, $c, $d";
 | |
| 			"sll	$b, $c, $a";
 | |
| 			"srl	$b, $d, $c";
 | |
| 			"or	$a, $c, $b";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 		}
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "rol", $1).
 | |
| 
 | |
| narg4(rol)
 | |
| 
 | |
| C_ror
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment( ror, $1);
 | |
| 
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n<0)
 | |
| 				arg_error("ror 4:", n);
 | |
| 			else
 | |
| 			{
 | |
| 				n= n % 32;
 | |
| 				if (n)
 | |
| 				{
 | |
| 					a= pop_reg();
 | |
| 					b= alloc_reg();
 | |
| 					c= alloc_reg();
 | |
| 					sprint(n_str, "%d", n);
 | |
| 					"srl	$a, $n_str, $b";
 | |
| 					sprint(n_str, "%d", 32-n);
 | |
| 					"sll	$a, $n_str, $c";
 | |
| 					"or	$b, $c, $a";
 | |
| 					push_reg(a);
 | |
| 					free_reg(b);
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			"and	$a, 31, $c";
 | |
| 			"mov	32, $a";
 | |
| 			"sub	$a, $c, $d";
 | |
| 			"srl	$b, $c, $a";
 | |
| 			"sll	$b, $d, $c";
 | |
| 			"or	$a, $c, $b";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 		}
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "ror", $1).
 | |
| 
 | |
| narg4(ror)
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 10 : Sets 	 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_inn		==>
 | |
| 	Comment( inn, $1);
 | |
| 	push_const($1);
 | |
| 	C_inn_narg().
 | |
| 
 | |
| C_inn_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		int i;
 | |
| 		int n;
 | |
| 		const_str_t i_str;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0(inn_narg);
 | |
| 		if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst)
 | |
| 				{
 | |
| 					i= pop_const (i_str);
 | |
| 					if (i >= n*8)
 | |
| 						push_const(0);
 | |
| 					else
 | |
| 					{
 | |
| 						a= pop_reg();
 | |
| 						b= alloc_reg();
 | |
| 						c= alloc_reg();
 | |
| 						"srl	$a, $i_str, $b";
 | |
| 						"and	$b, 1, $c";
 | |
| 						free_reg(a);
 | |
| 						free_reg(b);
 | |
| 						push_reg(c);
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					a= pop_reg();
 | |
| 					b= pop_reg();
 | |
| 					c= alloc_reg();
 | |
| 					"srl	$b, $a, $c";
 | |
| 					"and	$c, 1, $a";
 | |
| 					push_reg(a);
 | |
| 					free_reg(b);
 | |
| 					free_reg(c);
 | |
| 				}
 | |
| 			}
 | |
| 			else if (n == 2*EM_WSIZE)
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst)
 | |
| 				{
 | |
| 					i= pop_const (i_str);
 | |
| 					if (i >= n*8)
 | |
| 						push_const(0);
 | |
| 					else
 | |
| 					{
 | |
| 						if (i>= EM_WSIZE*8)
 | |
| 						{
 | |
| 							i -= EM_WSIZE*8;
 | |
| 							pop_nop(1);
 | |
| 							a= pop_reg();
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							a= pop_reg();
 | |
| 							pop_nop(1);
 | |
| 						}
 | |
| 						b= alloc_reg();
 | |
| 						c= alloc_reg();
 | |
| 						"srl	$a, $i_str, $b";
 | |
| 						"and	$b, 1, $c";
 | |
| 						free_reg(a);
 | |
| 						free_reg(b);
 | |
| 						push_reg(c);
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					a= pop_reg();
 | |
| 					flush_cache();
 | |
| 					b= alloc_reg();
 | |
| 					c= alloc_reg();
 | |
| 					d= alloc_reg();
 | |
| 					flush_cache();
 | |
| 					"andn	$a, 31, $b";
 | |
| 					"and	$a, 31, $c";
 | |
| 					"srl	$b, 3, $d";
 | |
| 					"ld	[$reg_sp+$d], $b";
 | |
| 					"inc	$n_str, $reg_sp";
 | |
| 					"srl	$b, $c, $d";
 | |
| 					"and	$d, 1, $b";
 | |
| 					free_reg(a);
 | |
| 					push_reg(b);
 | |
| 					free_reg(c);
 | |
| 					free_reg(d);
 | |
| 				}
 | |
| 			}
 | |
| 			else if (n % EM_WSIZE)
 | |
| 				arg_error ("inn", n);
 | |
| 			else
 | |
| 			{
 | |
| 				a= pop_reg();
 | |
| 				flush_cache();
 | |
| 				b= alloc_reg();
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				flush_cache();
 | |
| 				"andn	$a, 31, $b";
 | |
| 				"and	$a, 31, $c";
 | |
| 				"srl	$b, 3, $d";
 | |
| 				"ld	[$reg_sp+$d], $b";
 | |
| 				"inc	$n_str, $reg_sp";
 | |
| 				"srl	$b, $c, $d";
 | |
| 				"and	$d, 1, $b";
 | |
| 				free_reg(a);
 | |
| 				push_reg(b);
 | |
| 				free_reg(c);
 | |
| 				free_reg(d);
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("inn_narg");
 | |
| 	}.
 | |
| 
 | |
| C_set	==>	Comment( set, $1);
 | |
| 		push_const($1);
 | |
| 		C_set_narg().
 | |
| 
 | |
| C_set_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0( set_narg );
 | |
| 
 | |
| 		if (type_of_tos() == T_cst) {
 | |
| 			n = pop_const(n_str);
 | |
| 			if (n == EM_WSIZE) {
 | |
| 				b = alloc_reg();
 | |
| 				c = alloc_reg();
 | |
| 				a = pop_reg();
 | |
| 				"set	1, $c";
 | |
| 				"sll	$c, $a, $b";
 | |
| 				free_reg(a);
 | |
| 				free_reg(c);
 | |
| 				push_reg(b);
 | |
| 			} else {
 | |
| 				a= alloc_reg();
 | |
| 				b= pop_reg();
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				flush_cache();
 | |
| 				sprint(n_str, "%d", n);
 | |
| 				"set	$n_str, $a";
 | |
| 				"sub	$reg_sp, $a, $reg_sp";
 | |
| 			"1:";
 | |
| 				"deccc	4, $a";
 | |
| 				"bnz	1b";
 | |
| 				"st	%g0, [$reg_sp+$a]";	/* HACK delay */
 | |
| 				"andn	$b, 31, $c";
 | |
| 				"and	$b, 31, $b";
 | |
| 				"srl	$c, 3, $c";
 | |
| 				"set	1, $a";
 | |
| 				"sll	$a, $b, $d";
 | |
| 				"st	$d, [$reg_sp+$c]";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				free_reg(c);
 | |
| 				free_reg(d);
 | |
| 			}
 | |
| 		} else {
 | |
| 			a= pop_reg();
 | |
| 			b= pop_reg();
 | |
| 			flush_cache();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			"sub	$reg_sp, $a, $reg_sp";
 | |
| 		"1:";
 | |
| 			"deccc	4, $a";
 | |
| 			"bnz	1b";
 | |
| 			"st	%g0, [$reg_sp+$a]";	/* HACK delay */
 | |
| 			"andn	$b, 31, $c";
 | |
| 			"and	$b, 31, $b";
 | |
| 			"srl	$c, 3, $c";
 | |
| 			"set	1, $a";
 | |
| 			"sll	$a, $b, $d";
 | |
| 			"st	$d, [$reg_sp+$c]";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 11 : Array 	 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_lar
 | |
| 	($1 == 4) ==>
 | |
| 			Comment(lar, $1);
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			pop_reg_as(reg_o2);
 | |
| 			flush_cache();
 | |
| 			"call lar";
 | |
| 			"nop";
 | |
| 			free_output().
 | |
| 	default ==>
 | |
| 			arg_error ("arg error lar", $1).
 | |
| 
 | |
| narg4(lar)
 | |
| 
 | |
| C_sar
 | |
| 	($1 == 4) ==>
 | |
| 			Comment( sar , $1 );
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			pop_reg_as(reg_o2);
 | |
| 			flush_cache();
 | |
| 			"call	sar";
 | |
| 			"nop"
 | |
| 			free_output().
 | |
| 	default ==>
 | |
| 			arg_error ("arg error sar", $1).
 | |
| 
 | |
| narg4(sar)
 | |
| 
 | |
| C_aar
 | |
| 	($1 == 4) ==>
 | |
| 			Comment(aar, $1);
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			pop_reg_as(reg_o2);
 | |
| 			flush_cache();
 | |
| 			"call	aar";
 | |
| 			"nop";
 | |
| 			soft_alloc_reg(reg_o0);
 | |
| 			free_output();
 | |
| 			push_reg(reg_o0).
 | |
| 	default ==>
 | |
| 			arg_error ("arg error aar", $1).
 | |
| 
 | |
| narg4(aar)
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 12 : Compare 	 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_cmi
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		const_str_t d;
 | |
| 
 | |
| 		Comment( cmi, $1 );
 | |
| 
 | |
| 		if (type_of_tos() == T_cst && const13(top_const()))
 | |
| 		{
 | |
| 			pop_const(d);
 | |
| 			a= pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			"cmp	$a, $d";
 | |
| 			"be,a	1f";
 | |
| 			"mov	0, $b"; /* delay slot */
 | |
| 			"bg,a	1f";
 | |
| 			"mov	1, $b"; /* delay slot */
 | |
| 			"mov	-1, $b";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			b= NULL;
 | |
| 			c= alloc_reg();
 | |
| 			if (type_of_tos() == T_cst)
 | |
| 			{
 | |
| 				pop_const(d);
 | |
| 				"cmp	$a, $d";
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				b= pop_reg();
 | |
| 				"cmp	$a, $b";
 | |
| 			}
 | |
| 			"be,a	1f";
 | |
| 			"mov	0, $c"; /* delay slot */
 | |
| 			"bg,a	1f";
 | |
| 			"mov	-1, $c"; /* delay slot */
 | |
| 			"mov	1, $c";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			if (b)
 | |
| 				free_reg(b);
 | |
| 			push_reg(c);
 | |
| 		}
 | |
| 	}.
 | |
| 	default		==>
 | |
| 		arg_error ("unimp cmi", $1).
 | |
| 
 | |
| narg4(cmi)
 | |
| 
 | |
| C_cmu	==>
 | |
| 		Comment( cmu, $1 );
 | |
| 		push_const($1);
 | |
| 		C_cmu_narg().
 | |
| 
 | |
| C_cmu_narg	==>
 | |
| 	{
 | |
| 		int n;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		const_str_t d;
 | |
| 
 | |
| 		Comment0( cmu_narg );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n != EM_WSIZE)
 | |
| 				arg_error ("unimp cmu", n);
 | |
| 			else
 | |
| 			{
 | |
| 				if (type_of_tos() == T_cst &&
 | |
| 					const13(top_const()))
 | |
| 				{
 | |
| 					pop_const(d);
 | |
| 					a= pop_reg();
 | |
| 					b= alloc_reg();
 | |
| 					"cmp	$a, $d";
 | |
| 					"be,a	1f";
 | |
| 					"mov	0, $b"; /* delay slot */
 | |
| 					"bgu,a	1f";
 | |
| 					"mov	1, $b"; /* delay slot */
 | |
| 					"mov	-1, $b";
 | |
| 				"1:";
 | |
| 					free_reg(a);
 | |
| 					push_reg(b);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					a= pop_reg();
 | |
| 					b= NULL;
 | |
| 					c= alloc_reg();
 | |
| 					if (type_of_tos() == T_cst &&
 | |
| 						const13(top_const()))
 | |
| 					{
 | |
| 						pop_const(d);
 | |
| 						"cmp	$a, $d";
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						b= pop_reg();
 | |
| 						"cmp	$a, $b";
 | |
| 					}
 | |
| 					"be,a	1f";
 | |
| 					"mov	0, $c"; /* delay slot */
 | |
| 					"bgu,a	1f";
 | |
| 					"mov	-1, $c"; /* delay slot */
 | |
| 					"mov	1, $c";
 | |
| 				"1:";
 | |
| 					free_reg(a);
 | |
| 					if (b)
 | |
| 						free_reg(b);
 | |
| 					push_reg(c);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("cmu_narg");
 | |
| 	}.
 | |
| 
 | |
| C_cms	==>
 | |
| 		Comment( cms, $1 );
 | |
| 		push_const($1);
 | |
| 		C_cms_narg().
 | |
| 
 | |
| C_cms_narg	==>
 | |
| 	{
 | |
| 		int n;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		reg_t e;
 | |
| 		const_str_t b_str;
 | |
| 		const_str_t n_str;
 | |
| 
 | |
| 		Comment0( cms_narg );
 | |
| 		if (type_of_tos() == T_cst && top_const() <= EM_WSIZE)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == EM_WSIZE)
 | |
| 			{
 | |
| 				b= NULL;
 | |
| 				c= alloc_reg();
 | |
| 				if (type_of_tos() == T_cst &&
 | |
| 				    const13(top_const()))
 | |
| 				{
 | |
| 					pop_const(b_str);
 | |
| 					a= pop_reg();
 | |
| 					"cmp	$a, $b_str";
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					a= pop_reg();
 | |
| 					b= pop_reg();
 | |
| 					"cmp	$a, $b";
 | |
| 				}
 | |
| 				"be,a	1f";
 | |
| 				"mov	0, $c";
 | |
| 				"mov	1, $c";
 | |
| 			"1:";
 | |
| 				free_reg(a);
 | |
| 				if (b)
 | |
| 					free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else if (n % EM_WSIZE)
 | |
| 				arg_error ("unimp cms", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			flush_cache();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 
 | |
| 			"add	$reg_sp, $a, $b";
 | |
| 			"dec	4, $b";
 | |
| 		"1:";
 | |
| 			"ld	[$b], $c";
 | |
| 			"ld	[$b+$a], $d";
 | |
| 			"cmp	$d, $c";
 | |
| 			"bne,a	2f";
 | |
| 			"mov	1, $b";	/* delay slot */
 | |
| 			"cmp	$b, $reg_sp";
 | |
| 			"bg	1b";
 | |
| 			"dec	4, $b";	/* delay slot */
 | |
| 			"mov	0, $b";
 | |
| 		"2:";
 | |
| 			"add	$reg_sp, $a, $reg_sp";
 | |
| 			"add	$reg_sp, $a, $reg_sp";
 | |
| 
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_cmp		==>
 | |
| 			Comment0( cmp );
 | |
| 			C_cmu( (arith)4).
 | |
| 
 | |
| C_tlt	==>
 | |
| 		Comment0( tlt );
 | |
| 		{
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			"	tst	$a";
 | |
| 			"	bl,a	1f";
 | |
| 			"	mov	1, $b";		/* delay slot */
 | |
| 			"	set	0, $b";
 | |
| 			"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_tle	==>
 | |
| 		Comment0( tle );
 | |
| 		{
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			b= alloc_reg();
 | |
| 			"tst	$a";
 | |
| 			"ble,a	1f";
 | |
| 			"mov	1, $b";		/* delay slot */
 | |
| 			"set	0, $b";
 | |
| 		"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_tge	==>
 | |
| 		Comment0( tge );
 | |
| 		{
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			b = alloc_reg();
 | |
| 			"	tst	$a";
 | |
| 			"	bge,a	1f";
 | |
| 			"	mov	1, $b";		/* delay slot */
 | |
| 			"	set	0, $b";
 | |
| 			"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_tgt	==>
 | |
| 		Comment0( tgt );
 | |
| 		{
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			b = alloc_reg();
 | |
| 			"	tst	$a";
 | |
| 			"	bg,a	1f";
 | |
| 			"	mov	1, $b";		/* delay slot */
 | |
| 			"	set	0, $b";
 | |
| 			"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_tne	==>
 | |
| 		Comment0( tne );
 | |
| 		{
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			b = alloc_reg();
 | |
| 			"	tst	$a";
 | |
| 			"	bne,a	1f";
 | |
| 			"	mov	1, $b";		/* delay slot */
 | |
| 			"	set	0, $b";		/* sup optimal */
 | |
| 			"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_teq	==>
 | |
| 		Comment0( teq );
 | |
| 		{
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			b = alloc_reg();
 | |
| 			"	tst	$a";
 | |
| 			"	be,a	1f";
 | |
| 			"	mov	1, $b";		/* delay slot */
 | |
| 			"	set	0, $b";
 | |
| 			"1:";
 | |
| 			free_reg(a);
 | |
| 			push_reg(b);
 | |
| 		}.
 | |
| C_cmf		==>
 | |
| 	Comment( cmf, $1);
 | |
| 	push_const($1);
 | |
| 	C_cmf_narg().
 | |
| 
 | |
| C_cmf_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		int n;
 | |
| 
 | |
| 		Comment0( cmf_narg);
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n == EM_FSIZE)
 | |
| 			{
 | |
| 				a= pop_float();
 | |
| 				b= pop_float();
 | |
| 				c= alloc_reg();
 | |
| 				"fcmpes	$b, $a";
 | |
| 				"nop";
 | |
| 				"fbe,a	1f";
 | |
| 				"mov	0, $c";
 | |
| 				"fbl,a	1f";
 | |
| 				"mov	-1, $c";
 | |
| 				"mov	1, $c";
 | |
| 			"1:";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else if (n == EM_DSIZE)
 | |
| 			{
 | |
| 				a= pop_double(NULL);
 | |
| 				b= pop_double(NULL);
 | |
| 				c= alloc_reg();
 | |
| 				"fcmped	$b, $a";
 | |
| 				"nop";
 | |
| 				"fbe,a	1f";
 | |
| 				"mov	0, $c";
 | |
| 				"fbl,a	1f";
 | |
| 				"mov	-1, $c";
 | |
| 				"mov	1, $c";
 | |
| 			"1:";
 | |
| 				free_double_reg(a);
 | |
| 				free_double_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("cmf", n);
 | |
| 		}
 | |
| 		else
 | |
| 			not_implemented ("cmf_narg");
 | |
| 	}.
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*									      */
 | |
| /*		Group 13 : Branch 	 				      */
 | |
| /*									      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_bra		==>
 | |
| 			Comment( bra , $1 );
 | |
| 			{
 | |
| 				char *lbl;
 | |
| 
 | |
| 				flush_cache();
 | |
| 				lbl = $1;
 | |
| 				"b	$lbl";
 | |
| 				"nop";		/* delay slot */
 | |
| 			}.
 | |
| 
 | |
| C_bge	==>
 | |
| 		Comment( bge , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 			const_str_t n_str;
 | |
| 
 | |
| 			a= NULL;
 | |
| 			if (type_of_tos() == T_cst &&
 | |
| 				const13(top_const()))
 | |
| 				pop_const(n_str);
 | |
| 			else
 | |
| 				a = pop_reg();
 | |
| 			b = pop_reg();
 | |
| 			flush_cache();
 | |
| 			if (a)
 | |
| 				"cmp	$b, $a";
 | |
| 			else
 | |
| 				"cmp	$b, $n_str";
 | |
| 			"bge	$lbl";
 | |
| 			"nop"		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_bne	==>
 | |
| 		Comment( bne , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 			const_str_t n_str;
 | |
| 
 | |
| 			a= NULL;
 | |
| 			if (type_of_tos() == T_cst &&
 | |
| 				const13(top_const()))
 | |
| 				pop_const(n_str);
 | |
| 			else
 | |
| 				a = pop_reg();
 | |
| 			b = pop_reg();
 | |
| 			flush_cache();
 | |
| 			if (a)
 | |
| 				"cmp	$b, $a";
 | |
| 			else
 | |
| 				"cmp	$b, $n_str";
 | |
| 			"bne	$lbl";
 | |
| 			"nop"		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_beq	==>
 | |
| 		Comment( beq , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 			const_str_t n_str;
 | |
| 
 | |
| 			a= NULL;
 | |
| 			if (type_of_tos() == T_cst &&
 | |
| 				const13(top_const()))
 | |
| 				pop_const(n_str);
 | |
| 			else
 | |
| 				a = pop_reg();
 | |
| 			b = pop_reg();
 | |
| 			flush_cache();
 | |
| 			if (a)
 | |
| 				"cmp	$b, $a";
 | |
| 			else
 | |
| 				"cmp	$b, $n_str";
 | |
| 			"beq	$lbl";
 | |
| 			"nop"		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_ble	==>
 | |
| 		Comment( ble , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 			const_str_t n_str;
 | |
| 
 | |
| 			a= NULL;
 | |
| 			if (type_of_tos() == T_cst &&
 | |
| 				const13(top_const()))
 | |
| 				pop_const(n_str);
 | |
| 			else
 | |
| 				a = pop_reg();
 | |
| 			b = pop_reg();
 | |
| 			flush_cache();
 | |
| 			if (a)
 | |
| 				"cmp	$b, $a";
 | |
| 			else
 | |
| 				"cmp	$b, $n_str";
 | |
| 			"ble	$lbl";
 | |
| 			"nop"		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_blt	==>
 | |
| 		Comment( blt , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 			const_str_t n_str;
 | |
| 
 | |
| 			a= NULL;
 | |
| 			if (type_of_tos() == T_cst &&
 | |
| 				const13(top_const()))
 | |
| 				pop_const(n_str);
 | |
| 			else
 | |
| 				a = pop_reg();
 | |
| 			b = pop_reg();
 | |
| 			flush_cache();
 | |
| 			if (a)
 | |
| 				"cmp	$b, $a";
 | |
| 			else
 | |
| 				"cmp	$b, $n_str";
 | |
| 			"bl	$lbl";
 | |
| 			"nop"		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_bgt	==>
 | |
| 		Comment( bgt , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 			reg_t b;
 | |
| 			const_str_t n_str;
 | |
| 
 | |
| 			a= NULL;
 | |
| 			if (type_of_tos() == T_cst &&
 | |
| 				const13(top_const()))
 | |
| 				pop_const(n_str);
 | |
| 			else
 | |
| 				a = pop_reg();
 | |
| 			b = pop_reg();
 | |
| 			flush_cache();
 | |
| 			if (a)
 | |
| 				"cmp	$b, $a";
 | |
| 			else
 | |
| 				"cmp	$b, $n_str";
 | |
| 			"bg	$lbl";
 | |
| 			"nop"		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 		}.
 | |
| 
 | |
| C_zlt	==>
 | |
| 		Comment( zlt , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			flush_cache();
 | |
| 			"tst	$a";
 | |
| 			"bl	$lbl";
 | |
| 			"nop";		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 		.
 | |
| 
 | |
| C_zle	==>
 | |
| 		Comment( zle , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			flush_cache();
 | |
| 			"tst	$a";
 | |
| 			"ble	$lbl";
 | |
| 			"nop";		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 		.
 | |
| 
 | |
| C_zeq	==>
 | |
| 		Comment( zeq , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			flush_cache();
 | |
| 			"tst	$a";
 | |
| 			"be	$lbl";
 | |
| 			"nop";		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 		.
 | |
| 
 | |
| C_zne	==>
 | |
| 		Comment( zne , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			flush_cache();
 | |
| 			"tst	$a";
 | |
| 			"bne	$lbl";
 | |
| 			"nop";		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 		.
 | |
| 
 | |
| C_zge	==>
 | |
| 		Comment( zge , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			flush_cache();
 | |
| 			"tst	$a";
 | |
| 			"bge	$lbl";
 | |
| 			"nop";		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 		.
 | |
| 
 | |
| C_zgt	==>
 | |
| 		Comment( zgt , $1 );
 | |
| 		{
 | |
| 			char *lbl = $1;
 | |
| 			reg_t a;
 | |
| 
 | |
| 			a = pop_reg();
 | |
| 			flush_cache();
 | |
| 			"tst	$a";
 | |
| 			"bg	$lbl";
 | |
| 			"nop";		/* delay slot */
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 		.
 | |
| /******************************************************************************/
 | |
| /*                                                                            */
 | |
| /*			Group 14 : Procedure call instructions		      */
 | |
| /*							 		      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_cai		==>
 | |
| 			Comment0( cai );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 
 | |
| 				a= pop_reg();
 | |
| 				flush_cache();
 | |
| 				"call	$a";
 | |
| 				"nop";		/* delay slot */
 | |
| 				free_reg(a);
 | |
| 			}.
 | |
| 
 | |
| C_cal		==>
 | |
| 			Comment( cal , $1 );
 | |
| 			{
 | |
| 				char *lbl = $1;
 | |
| 				flush_cache();
 | |
| 				"call	$lbl";
 | |
| 				"nop";		/* delay slot */
 | |
| 			}.
 | |
| 
 | |
| C_lfr
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		Comment( lfr , $1 );
 | |
| 		forced_alloc_reg(RETL_LD);
 | |
| 		push_reg(RETL_LD);
 | |
| 	}.
 | |
| 	$1 == 8		==>
 | |
| 	{
 | |
| 		Comment( lfr , $1 );
 | |
| 		forced_alloc_reg(RETL_LD);
 | |
| 		forced_alloc_reg(RETH_LD);
 | |
| 		push_reg(RETH_LD);
 | |
| 		push_reg(RETL_LD);
 | |
| 	}.
 | |
| 	default		==>
 | |
| 		arg_error( "lfr", $1).
 | |
| 
 | |
| C_ret
 | |
| 	$1 == 0		==>
 | |
| 	{
 | |
| 		Comment( ret , $1 );
 | |
| 		load_float_regs();
 | |
| 		if (debug)
 | |
| 			free_all_reg_vars();
 | |
| 		"restore";
 | |
| 		"retl";
 | |
| 		"add	%sp, $reg_gap, %sp";
 | |
| 		if (debug)
 | |
| 			alloc_all_reg_vars();
 | |
| 	}.
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		Comment( ret , $1 );
 | |
| 		soft_alloc_reg(RETL_ST);
 | |
| 		pop_reg_as(RETL_ST);
 | |
| 		free_reg(RETL_ST);
 | |
| 		load_float_regs();
 | |
| 		if (debug)
 | |
| 			free_all_reg_vars();
 | |
| 		"restore";
 | |
| 		"retl";
 | |
| 		"add	%sp, $reg_gap, %sp";
 | |
| 		if (debug)
 | |
| 			alloc_all_reg_vars();
 | |
| 	}.
 | |
| 	$1 == 8		==>
 | |
| 	{
 | |
| 		Comment( ret , $1 );
 | |
| 		soft_alloc_reg(RETL_ST);
 | |
| 		soft_alloc_reg(RETH_ST);
 | |
| 		pop_reg_as(RETL_ST);
 | |
| 		pop_reg_as(RETH_ST);
 | |
| 		free_reg(RETL_ST);
 | |
| 		free_reg(RETH_ST);
 | |
| 		load_float_regs();
 | |
| 		if (debug)
 | |
| 			free_all_reg_vars();
 | |
| 		"restore";
 | |
| 		"retl";
 | |
| 		"add	%sp, $reg_gap, %sp";
 | |
| 		if (debug)
 | |
| 			alloc_all_reg_vars();
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "ret", $1).
 | |
| 
 | |
| /******************************************************************************/
 | |
| /*                                                                            */
 | |
| /*			Group 15 : Miscellaneous instructions		      */
 | |
| /*							 		      */
 | |
| /******************************************************************************/
 | |
| 
 | |
| C_asp		==>
 | |
| 	Comment( asp , $1 );
 | |
| 	push_const($1);
 | |
| 	C_ass(EM_WSIZE).
 | |
| 
 | |
| 
 | |
| C_ass
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		int n;
 | |
| 		const_str_t n_str;
 | |
| 		reg_t a;
 | |
| 
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n % EM_WSIZE)
 | |
| 				arg_error ("asp", n);
 | |
| 			else
 | |
| 				if (n>=0)
 | |
| 					pop_nop (n/4);
 | |
| 				else
 | |
| 				{
 | |
| 					flush_cache();
 | |
| 					if (const13(n))
 | |
| 						"inc	$n_str, $reg_sp";
 | |
| 					else
 | |
| 					{
 | |
| 						a= alloc_reg();
 | |
| 						"set	$n_str, $a"
 | |
| 						"add	$reg_sp, $a, $reg_sp";
 | |
| 						free_reg(a);
 | |
| 					}
 | |
| 				}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			flush_cache();
 | |
| 			"add	$reg_sp, $a, $reg_sp";
 | |
| 			free_reg(a);
 | |
| 		}
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "ass", $1).
 | |
| 
 | |
| 
 | |
| narg4(ass)
 | |
| 
 | |
| C_blm		==>
 | |
| 	Comment( blm, $1);
 | |
| 	push_const($1);
 | |
| 	C_bls (EM_WSIZE).
 | |
| 
 | |
| C_bls
 | |
| 	$1 == 4	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		reg_t ao_reg;
 | |
| 		reg_t bo_reg;
 | |
| 		int n;
 | |
| 		int i;
 | |
| 		const_str_t n_str;
 | |
| 		const_str_t ac_str;
 | |
| 		const_str_t bc_str;
 | |
| 		
 | |
| 		Comment( bls , $1 );
 | |
| 		if (type_of_tos() == T_cst)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n % EM_WSIZE)
 | |
| 				arg_error ("blm", n);
 | |
| 			else if (n <= MAX_UNROLL)
 | |
| 			{
 | |
| 				c= alloc_reg();
 | |
| 				for (i=0; i<n; i += EM_WSIZE)
 | |
| 				{
 | |
| 					if (type_of_tos() & T_reg2) /* dest */
 | |
| 						a= pop_reg_reg (&ao_reg);
 | |
| 					else
 | |
| 					{
 | |
| 						ao_reg= NULL;
 | |
| 						a= pop_reg_c13(ac_str);
 | |
| 					}
 | |
| 					if (type_of_tos() & T_reg2) /* src */
 | |
| 						b= pop_reg_reg (&bo_reg);
 | |
| 					else
 | |
| 					{
 | |
| 						bo_reg= NULL;
 | |
| 						b= pop_reg_c13(bc_str);
 | |
| 					}
 | |
| 					if (bo_reg)
 | |
| 						"ld	[$b+$bo_reg], $c";
 | |
| 					else
 | |
| 						"ld	[$b+$bc_str], $c";
 | |
| 					if (ao_reg)
 | |
| 						"st	$c, [$a+$ao_reg]";
 | |
| 					else
 | |
| 						"st	$c, [$a+$ac_str]";
 | |
| 					if (bo_reg)
 | |
| 					{
 | |
| 						push_reg(b);
 | |
| 						inc_tos_reg(bo_reg);
 | |
| 					}
 | |
| 					else if (bc_str[0] == '-' ||
 | |
| 						isdigit(bc_str[0]))
 | |
| 					{
 | |
| 						push_reg(b);
 | |
| 						inc_tos(atoi(bc_str));
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						"add	$b, $bc_str, $c";
 | |
| 						push_reg(c);
 | |
| 						free_reg(b);
 | |
| 						c= alloc_reg();
 | |
| 					}
 | |
| 					inc_tos(4);
 | |
| 					if (ao_reg)
 | |
| 					{
 | |
| 						push_reg(a);
 | |
| 						inc_tos_reg(ao_reg);
 | |
| 					}
 | |
| 					else if (ac_str[0] == '-' ||
 | |
| 						isdigit(ac_str[0]))
 | |
| 					{
 | |
| 						push_reg(a);
 | |
| 						inc_tos(atoi(ac_str));
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						"add	$a, $ac_str, $c";
 | |
| 						push_reg(c);
 | |
| 						free_reg(a);
 | |
| 						c= alloc_reg();
 | |
| 					}
 | |
| 					inc_tos(4);
 | |
| 				}
 | |
| 				pop_nop(2);
 | |
| 				free_reg(c);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				a= pop_reg();	/* dest */
 | |
| 				b= pop_reg();	/* src */
 | |
| 				c= alloc_reg();
 | |
| 				d= alloc_reg();
 | |
| 				"set	$n_str, $c";
 | |
| 			"1:";
 | |
| 				"deccc	4, $c";
 | |
| 				"ld	[$b+$c], $d";
 | |
| 				"bnz	1b";
 | |
| 				"st	$d, [$a+$c]";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				free_reg(c);
 | |
| 				free_reg(d);
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 
 | |
| 			c= pop_reg();	/* size */
 | |
| 			a= pop_reg();	/* dest */
 | |
| 			b= pop_reg();	/* src */
 | |
| 			d= alloc_reg();
 | |
| 		"1:";
 | |
| 			"deccc	4, $c";
 | |
| 			"ld	[$b+$c], $d";
 | |
| 			"bnz	1b";
 | |
| 			"st	$d, [$a+$c]";
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| 	default		==>
 | |
| 				arg_error( "bls", $1).
 | |
| 
 | |
| narg4(bls)
 | |
| 
 | |
| C_csa
 | |
| 	$1 == 4	==>
 | |
| 		Comment( csa , $1 );
 | |
| 		{
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			pop_reg_as(reg_o1);
 | |
| 			flush_cache();
 | |
| 			free_output();
 | |
| 			"set	csa, $reg_tmp";
 | |
| 			"jmp	$reg_tmp";
 | |
| 			"nop";
 | |
| 		}.
 | |
| 	default	==>
 | |
| 		arg_error( "csa", $1).
 | |
| 
 | |
| narg4(csa)
 | |
| 
 | |
| C_csb
 | |
| 	$1 == 4		==>
 | |
| 			Comment( csb , $1 );
 | |
| 			{
 | |
| 				force_alloc_output();
 | |
| 				pop_reg_as(reg_o0);
 | |
| 				pop_reg_as(reg_o1);
 | |
| 				flush_cache();
 | |
| 				free_output();
 | |
| 				"set	csb, $reg_tmp";
 | |
| 				"jmp	$reg_tmp";
 | |
| 				"nop";
 | |
| 			}.
 | |
| 	default		==>
 | |
| 				arg_error( "csb", $1).
 | |
| 
 | |
| narg4(csb)
 | |
| 
 | |
| C_dch		==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 
 | |
| 		Comment0( dch );
 | |
| 		a= pop_reg();		/* some LB */
 | |
| 		b= alloc_reg();
 | |
| 		c= alloc_reg();
 | |
| 		"ta	3";		/* flush register windows */
 | |
| 		"add	$a, 7, $b";
 | |
| 		"andn	$b, 7, $c";	/* and it's %fp */
 | |
| 		"ld	[$c+4], $b";	/* the previous LB */
 | |
| 		free_reg(a);
 | |
| 		push_reg(b);
 | |
| 		free_reg(c);
 | |
| 	}.
 | |
| 
 | |
| C_dup	==>
 | |
| 		Comment( dup, $1);
 | |
| 		push_const($1);
 | |
| 		C_dus(EM_WSIZE).
 | |
| 
 | |
| C_dus
 | |
| 	$1 == 4 ==>
 | |
| 	{
 | |
| 		int n;
 | |
| 		int i;
 | |
| 		const_str_t n_str;
 | |
| 		const_str_t i_str;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 
 | |
| 		Comment( dus, $1);
 | |
| 
 | |
| 		if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
 | |
| 		{
 | |
| 			n= pop_const(n_str);
 | |
| 			if (n == 4 || n == 8 || n<=32)
 | |
| 				dup_tos(n/4);
 | |
| 			else if (n<0 || n % 4)
 | |
| 				arg_error ("dup", n);
 | |
| 			else
 | |
| 			{
 | |
| 				flush_cache();
 | |
| 				a= alloc_reg();
 | |
| 				"sub	$reg_sp, $n_str, $reg_sp";
 | |
| 				for (i=0; i<n; i += 4)
 | |
| 				{
 | |
| 					sprint(i_str, "%d", i);
 | |
| 					"ld	[$reg_sp+$i_str+$n_str], $a";
 | |
| 					"st	$a, [$reg_sp+$i_str]";
 | |
| 				}
 | |
| 				free_reg(a);
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			flush_cache();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			"mov	$a, $b";
 | |
| 		"1:";
 | |
| 			"dec	STACK_CLICK, $reg_sp";
 | |
| 			"ld	[$reg_sp+ $a], $c";
 | |
| 			"deccc	4, $b";
 | |
| 			"bne	1b";
 | |
| 			"st	$c, [$reg_sp+ $a]"; /* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 		}
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "dus", $1).
 | |
| 
 | |
| narg4(dus)
 | |
| 
 | |
| C_exg		==>
 | |
| 	Comment( exg, $1 );
 | |
| 	push_const($1);
 | |
| 	C_exg_narg().
 | |
| 
 | |
| C_exg_narg	==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 		int n;
 | |
| 		int i;
 | |
| 		const_str_t i_str;
 | |
| 		const_str_t in_str;
 | |
| 
 | |
| 		Comment0( exg_narg );
 | |
| 		if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
 | |
| 		{
 | |
| 			n= pop_const(NULL);
 | |
| 			if (n==4)
 | |
| 			{
 | |
| 					a= pop_reg();
 | |
| 					b= pop_reg();
 | |
| 					push_reg(a);
 | |
| 					push_reg(b);
 | |
| 			}
 | |
| 			else if (n==8)
 | |
| 			{
 | |
| 				a= pop_reg();
 | |
| 				b= pop_reg();
 | |
| 				c= pop_reg();
 | |
| 				d= pop_reg();
 | |
| 				push_reg(b);
 | |
| 				push_reg(a);
 | |
| 				push_reg(d);
 | |
| 				push_reg(c);
 | |
| 			}
 | |
| 			else if (n>0 && !(n % 4))
 | |
| 			{
 | |
| 				a= alloc_reg();
 | |
| 				b= alloc_reg();
 | |
| 				flush_cache();
 | |
| 				for (i=0; i<n; i += 4)
 | |
| 				{
 | |
| 					sprint(i_str, "%d", i);
 | |
| 					sprint(in_str, "%d", i+n);
 | |
| 					"ld	[$reg_sp+$i_str], $a";
 | |
| 					"ld	[$reg_sp+$in_str], $b";
 | |
| 					"st	$b, [$reg_sp+$i_str]";
 | |
| 					"st	$a, [$reg_sp+$in_str]";
 | |
| 				}
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 			}
 | |
| 			else
 | |
| 				arg_error ("exg", n);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			a= pop_reg();
 | |
| 			flush_cache();
 | |
| 			b= alloc_reg();
 | |
| 			c= alloc_reg();
 | |
| 			d= alloc_reg();
 | |
| 			"add	$reg_sp, $a, $b";
 | |
| 		"1:";
 | |
| 			"dec	4, $b";
 | |
| 			"cmp	$reg_sp, $b";
 | |
| 			"ld	[$b], $c";
 | |
| 			"ld	[$b+$a], $d";
 | |
| 			"st	$d, [$b]";
 | |
| 			"bne	1b";
 | |
| 			"st	$c, [$b+$a]";	/* delay slot */
 | |
| 			free_reg(a);
 | |
| 			free_reg(b);
 | |
| 			free_reg(c);
 | |
| 			free_reg(d);
 | |
| 		}
 | |
| 	}.
 | |
| 
 | |
| C_fil..		==>
 | |
| 			Comment2( fil , $1 , $2);
 | |
| #ifdef FAST_LIN_LNI_FIL
 | |
| 			{
 | |
| 				char *lbl = $1;
 | |
| 				int n = $2;
 | |
| 
 | |
| 				"set	$lbl+$n, $reg_fil"
 | |
| 			}.
 | |
| #else
 | |
| 			push_ext($1);
 | |
| 			inc_tos($2);
 | |
| 			push_ext("filn");
 | |
| 			push_const(4);
 | |
| 			C_sts(EM_WSIZE).
 | |
| #endif
 | |
| 
 | |
| 
 | |
| C_gto..		==>
 | |
| 	{
 | |
| 		char *ext;
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 		reg_t d;
 | |
| 
 | |
| 		Comment2( gto , $1 , $2 );
 | |
| 
 | |
| 		flush_cache();
 | |
| 		a= reg_g1;
 | |
| 		b= reg_g2;
 | |
| 		c= reg_g3;
 | |
| 		d= reg_g5;
 | |
| 		forced_alloc_reg(a);
 | |
| 		forced_alloc_reg(b);
 | |
| 		forced_alloc_reg(c);
 | |
| 		forced_alloc_reg(d);
 | |
| 		ext= $1;
 | |
| 		push_ext(ext);
 | |
| 		inc_tos($2);
 | |
| 		pop_reg_as(a);
 | |
| 		"ld	[$a+8], $b";
 | |
| 		"mov	$reg_o0, $c";
 | |
| 		"mov	$reg_o1, $d";
 | |
| 	"1:";
 | |
| 		"cmp	$b, $reg_lb";
 | |
| 		"bne,a	1b";
 | |
| 		"restore";
 | |
| 		"ld	[$a+4], $reg_sp";
 | |
| 		"ld	[$a], $b";
 | |
| 		"mov	$c, $reg_o0";
 | |
| 		"jmp	$b";
 | |
| 		"mov	$d, $reg_o1";	/* delay slot */
 | |
| 		free_reg(a);
 | |
| 		free_reg(b);
 | |
| 		free_reg(c);
 | |
| 		free_reg(d);
 | |
| 	}.
 | |
| 
 | |
| C_lim		==>
 | |
| 			Comment0( lim  );
 | |
| 			push_ext("trpim");
 | |
| 			C_loi(4).
 | |
| 
 | |
| C_lin		==>
 | |
| 			Comment( lin , $1 );
 | |
| #ifdef FAST_LIN_LNI_FIL
 | |
| 			{
 | |
| 				const_str_t n_str;
 | |
| 				sprint(n_str, "%d", $1);
 | |
| 				"set	$n_str, $reg_fil";
 | |
| 			}.
 | |
| #else
 | |
| 			push_const($1);
 | |
| 			push_ext("lino");
 | |
| 			push_const(4);
 | |
| 			C_sts(EM_WSIZE).
 | |
| #endif
 | |
| 
 | |
| C_lni		==>
 | |
| #ifdef FAST_LIN_LNI_FIL
 | |
| 			Comment0( lni );
 | |
| 		 	"inc	$reg_fil".
 | |
| #else
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 
 | |
| 				Comment0( lni );
 | |
| 				a = alloc_reg();
 | |
| 				b = alloc_reg();
 | |
| 				"sethi	%hi(lino), $a";
 | |
| 				"ld	[$a+%lo(lino)], $b";
 | |
| 				"inc	$b";
 | |
| 				"st	$b, [$a+%lo(lino)]"
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 			}.
 | |
| #endif
 | |
| 
 | |
| 
 | |
| C_lor
 | |
| 	$1 == 0		==>
 | |
| 				Comment( lor , $1 );
 | |
| 				soft_alloc_reg(reg_lb);
 | |
| 				push_reg(reg_lb).
 | |
| 	$1 == 1		==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 
 | |
| 		Comment( lor , $1 );
 | |
| 		a= alloc_reg();
 | |
| 		flush_cache();
 | |
| 		"mov	$reg_sp, $a";
 | |
| 		push_reg(a);
 | |
| 	}.
 | |
| 	$1 == 2		==>
 | |
| 				Comment( lor , $1 );
 | |
| 				{
 | |
| 					reg_t a;
 | |
| 					reg_t b;
 | |
| 
 | |
| 					a= alloc_reg();
 | |
| 					b= alloc_reg();
 | |
| 					"set	reghp, $a";
 | |
| 					"ld	[$a], $b";
 | |
| 					push_reg(b);
 | |
| 					free_reg(a);
 | |
| 				}.
 | |
| 
 | |
| 	default		==>
 | |
| 				arg_error( "lor", $1).
 | |
| 
 | |
| 
 | |
| C_lpb		==>
 | |
| 			Comment0( lpb );
 | |
| 			C_adp( (arith)EM_BSIZE).
 | |
| 
 | |
| 
 | |
| C_mon		==>
 | |
| 			Comment0( mon );
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			"call mon";
 | |
| 			"nop";
 | |
| 			free_output().
 | |
| 
 | |
| C_nop	==>
 | |
| 			Comment0( nop );
 | |
| 			flush_cache();
 | |
| 			.
 | |
| 
 | |
| 
 | |
| C_rck
 | |
| 	$1 == 4		==>
 | |
| 	{
 | |
| 		reg_t a;
 | |
| 		reg_t b;
 | |
| 		reg_t c;
 | |
| 
 | |
| 		Comment( rck , $1 );
 | |
| 		force_alloc_output();
 | |
| 		a= pop_reg();
 | |
| 		b= pop_reg();
 | |
| 		soft_alloc_reg(b);
 | |
| 		push_reg(b);
 | |
| 		c= alloc_reg();
 | |
| 		"ld	[$a], $c";
 | |
| 		"cmp	$b, $c";
 | |
| 		"bl	1f";
 | |
| 		"ld	[$a+4], $c";
 | |
| 		"cmp	$b, $c";
 | |
| 		"ble	2f";
 | |
| 		"nop";
 | |
| 	"1:";
 | |
| 		"set	ERANGE, $reg_o0";
 | |
| 		"call	trp";
 | |
| 		"nop";
 | |
| 	"2:";
 | |
| 		free_reg(a);
 | |
| 		free_reg(b);
 | |
| 		free_reg(c);
 | |
| 		free_output();
 | |
| 	}.
 | |
| 	default		==>
 | |
| 		arg_error( "rck", $1).
 | |
| 
 | |
| narg4(rck)
 | |
| 
 | |
| C_rtt		==>
 | |
| 			Comment0( rtt );
 | |
| 			C_ret( (arith)0).
 | |
| 
 | |
| 
 | |
| C_sig		==>
 | |
| 			Comment0( sig );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 				reg_t c;
 | |
| 
 | |
| 				a= pop_reg();
 | |
| 				b= alloc_reg();
 | |
| 				c= alloc_reg();
 | |
| 				"set	trppc, $b";
 | |
| 				"ld	[$b], $c";
 | |
| 				"st	$a, [$b]";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 				push_reg(c);
 | |
| 			}.
 | |
| 
 | |
| 
 | |
| C_sim		==>
 | |
| 			Comment0( sim );
 | |
| 			{
 | |
| 				reg_t a;
 | |
| 				reg_t b;
 | |
| 
 | |
| 				a= pop_reg();
 | |
| 				b= alloc_reg();
 | |
| 				"set	trpim, $b";
 | |
| 				"st	$a, [$b]";
 | |
| 				free_reg(a);
 | |
| 				free_reg(b);
 | |
| 			}.
 | |
| 
 | |
| 
 | |
| C_str
 | |
| 	$1 == 0		==>
 | |
| 				Comment( str , $1 );
 | |
| 				flush_cache();
 | |
| 				"ld	[$reg_sp], $reg_lb";
 | |
| 				"add	$reg_lb, 4, %fp";
 | |
| 				"and	%fp, -8, %fp";
 | |
| 				"inc	STACK_CLICK, $reg_sp"
 | |
| 				.
 | |
| 	$1 == 1		==>
 | |
| 	{
 | |
| 		Comment( str , $1 );
 | |
| 		flush_cache();
 | |
| 		"ld [$reg_sp], $reg_sp";
 | |
| 	}.
 | |
| 	$1 == 2		==>
 | |
| 	{
 | |
| 		Comment( str , $1 );
 | |
| 		force_alloc_output();
 | |
| 		pop_reg_as(reg_o0);
 | |
| 		"call	strhp";
 | |
| 		"nop";
 | |
| 		free_output();
 | |
| 	}.
 | |
| 	default		==>
 | |
| 				arg_error( "str", $1).
 | |
| 
 | |
| 
 | |
| C_trp		==>
 | |
| 			Comment0( trp );
 | |
| 			force_alloc_output();
 | |
| 			pop_reg_as(reg_o0);
 | |
| 			flush_cache();
 | |
| 			"call	trp";
 | |
| 			"nop";
 | |
| 			free_output().
 | |
| 
 | |
| /*****************************************************************************/
 | |
| 
 | |
| ..icon
 | |
| 	$2 == 1  	==>
 | |
| 				Comment( ..icon , $1 );
 | |
| 				gen1( (ONE_BYTE) atoi( $1)).
 | |
| 	$2 == 2  	==>
 | |
| 				Comment( ..icon , $1 );
 | |
| 				gen2( (TWO_BYTES) atoi( $1)).
 | |
| 	$2 == 4  	==>
 | |
| 				Comment( ..icon , $1 );
 | |
| 				gen4( (FOUR_BYTES) atol( $1)).
 | |
| 	default     	==>
 | |
| 				arg_error( "icon", $2).
 | |
| 
 | |
| ..ucon
 | |
| 	$2 == 1  	==>
 | |
| 				Comment( ..ucon , $1 );
 | |
| 				gen1( (ONE_BYTE) atoi( $1)).
 | |
| 	$2 == 2  	==>
 | |
| 				Comment( ..ucon , $1 );
 | |
| 				gen2( (TWO_BYTES) atoi( $1)).
 | |
| 	$2 == 4  	==>
 | |
| 				Comment( ..ucon , $1 );
 | |
| 				gen4( (FOUR_BYTES) atol( $1)).
 | |
| 	default     	==>
 | |
| 				arg_error( "icon", $2).
 | |
| 
 | |
| ..fcon			==>
 | |
| 				Comment( ..fcon , $1 );
 | |
| 				con_float($1, $2).
 | |
| 
 | |
| /*****************************************************************************/
 | |
| 
 | |
| C_prolog		==>
 | |
| 	Comment0( prolog );
 | |
| 	init_cache();
 | |
| 	"sub	$reg_sp, (EM_BSIZE-4), %g1";
 | |
| 	"and	%g1, -8, %sp";
 | |
| 	"mov	$reg_sp, %g1";
 | |
| 	"save	%sp, $reg_gap, %sp";
 | |
| 	"st	%g0, [%sp+BP_OFFSET]";
 | |
| 	"sub	%g1, EM_BSIZE, $reg_lb";
 | |
| 	init_reg_man();
 | |
| 	forced_alloc_reg(reg_sp);
 | |
| 	forced_alloc_reg(reg_lb);
 | |
| 	forced_alloc_reg(reg_gap);
 | |
| #ifdef FAST_LIN_LNI_FIL
 | |
| 	reg_lin = alloc_reg();
 | |
| 	reg_fil = alloc_reg();
 | |
| #endif
 | |
| 	.
 | |
| C_jump	 		==>
 | |
| 	{
 | |
| 		char *l;
 | |
| 
 | |
| 		Comment( jump , $1 );
 | |
| 		l= $1;
 | |
| 		"b	$l";
 | |
| 		"nop";	/* delay slot */
 | |
| 	}.
 | |
| 
 | |
| C_locals		==>
 | |
| 	{
 | |
| 		Comment( locals , $1 );
 | |
| 
 | |
| 		soft_alloc_reg(reg_lb);
 | |
| 		push_reg(reg_lb);
 | |
| 		inc_tos(-($1));
 | |
| 		pop_reg_as(reg_sp);
 | |
| 	}.
 |