ceriel 33 years ago
parent
commit
2220c3b6fb
100 changed files with 7719 additions and 0 deletions
  1. 15 0
      mach/sparc/ce/.distr
  2. 4631 0
      mach/sparc/ce/EM_table.x
  3. 13 0
      mach/sparc/ce/Makefile
  4. 9 0
      mach/sparc/ce/back.src/.distr
  5. 101 0
      mach/sparc/ce/back.src/Makefile
  6. 69 0
      mach/sparc/ce/back.src/back.h
  7. 8 0
      mach/sparc/ce/back.src/con_str.c
  8. 2 0
      mach/sparc/ce/back.src/const.h
  9. 11 0
      mach/sparc/ce/back.src/do_open.c
  10. 27 0
      mach/sparc/ce/back.src/gen_str.c
  11. 4 0
      mach/sparc/ce/back.src/header.h
  12. 8 0
      mach/sparc/ce/back.src/rom_str.c
  13. 9 0
      mach/sparc/ce/back.src/symboldef.c
  14. 1287 0
      mach/sparc/ce/cache.c.x
  15. 7 0
      mach/sparc/ce/ce.src/.distr
  16. 14 0
      mach/sparc/ce/ce.src/C_con_scon.c
  17. 8 0
      mach/sparc/ce/ce.src/C_cst.c
  18. 8 0
      mach/sparc/ce/ce.src/C_mes_begin.c
  19. 7 0
      mach/sparc/ce/ce.src/C_mes_end.c
  20. 14 0
      mach/sparc/ce/ce.src/C_rom_scon.c
  21. 54 0
      mach/sparc/ce/ce.src/misc.c
  22. 338 0
      mach/sparc/ce/ce.src/ms_reg.c
  23. 30 0
      mach/sparc/ce/cegpp
  24. 35 0
      mach/sparc/ce/mach.c
  25. 20 0
      mach/sparc/ce/mach.h
  26. 59 0
      mach/sparc/ce/mach_em.h
  27. 11 0
      mach/sparc/ce/misc.h
  28. 10 0
      mach/sparc/ce/ms_reg.h
  29. 37 0
      mach/sparc/ce/proto.make
  30. 89 0
      mach/sparc/ce/push_pop.h
  31. 5 0
      mach/sparc/libsys/.distr
  32. 180 0
      mach/sparc/libsys/LIST
  33. 147 0
      mach/sparc/libsys/SYS.h
  34. 13 0
      mach/sparc/libsys/_alarm.c
  35. 46 0
      mach/sparc/libsys/_brk.s
  36. 3 0
      mach/sparc/libsys/_close.s
  37. 3 0
      mach/sparc/libsys/_creat.s
  38. 3 0
      mach/sparc/libsys/_dup.s
  39. 3 0
      mach/sparc/libsys/_dup2.s
  40. 8 0
      mach/sparc/libsys/_execl.c
  41. 3 0
      mach/sparc/libsys/_execve.s
  42. 7 0
      mach/sparc/libsys/_exit.s
  43. 3 0
      mach/sparc/libsys/_fork.s
  44. 3 0
      mach/sparc/libsys/_fstat.s
  45. 15 0
      mach/sparc/libsys/_ftime.c
  46. 3 0
      mach/sparc/libsys/_getpid.s
  47. 3 0
      mach/sparc/libsys/_getrusage.s
  48. 3 0
      mach/sparc/libsys/_gettimday.s
  49. 8 0
      mach/sparc/libsys/_gtty.c
  50. 3 0
      mach/sparc/libsys/_ioctl.s
  51. 3 0
      mach/sparc/libsys/_kill.s
  52. 3 0
      mach/sparc/libsys/_link.s
  53. 3 0
      mach/sparc/libsys/_lseek.s
  54. 3 0
      mach/sparc/libsys/_open.s
  55. 3 0
      mach/sparc/libsys/_pause.c
  56. 3 0
      mach/sparc/libsys/_pipe.s
  57. 3 0
      mach/sparc/libsys/_read.s
  58. 4 0
      mach/sparc/libsys/_setitimer.s
  59. 3 0
      mach/sparc/libsys/_sigblock.s
  60. 3 0
      mach/sparc/libsys/_sigpause.s
  61. 3 0
      mach/sparc/libsys/_sigsetmask.s
  62. 36 0
      mach/sparc/libsys/_sigvec.c
  63. 5 0
      mach/sparc/libsys/_sigvecscall.s
  64. 16 0
      mach/sparc/libsys/_times.c
  65. 3 0
      mach/sparc/libsys/_unlink.s
  66. 19 0
      mach/sparc/libsys/_wait4.s
  67. 3 0
      mach/sparc/libsys/_write.s
  68. 3 0
      mach/sparc/libsys/accept.s
  69. 4 0
      mach/sparc/libsys/access.s
  70. 3 0
      mach/sparc/libsys/acct.s
  71. 3 0
      mach/sparc/libsys/adjtime.s
  72. 13 0
      mach/sparc/libsys/alarm.c
  73. 4 0
      mach/sparc/libsys/bind.s
  74. 6 0
      mach/sparc/libsys/brk.s
  75. 14 0
      mach/sparc/libsys/cerror.s
  76. 3 0
      mach/sparc/libsys/chdir.s
  77. 3 0
      mach/sparc/libsys/chmod.s
  78. 3 0
      mach/sparc/libsys/chown.s
  79. 3 0
      mach/sparc/libsys/chroot.s
  80. 1 0
      mach/sparc/libsys/cleanup.c
  81. 3 0
      mach/sparc/libsys/close.s
  82. 4 0
      mach/sparc/libsys/connect.s
  83. 3 0
      mach/sparc/libsys/creat.s
  84. 3 0
      mach/sparc/libsys/dup.s
  85. 3 0
      mach/sparc/libsys/dup2.s
  86. 8 0
      mach/sparc/libsys/execl.c
  87. 9 0
      mach/sparc/libsys/execle.c
  88. 7 0
      mach/sparc/libsys/execv.c
  89. 3 0
      mach/sparc/libsys/execve.s
  90. 5 0
      mach/sparc/libsys/exit.c
  91. 3 0
      mach/sparc/libsys/fchdir.s
  92. 3 0
      mach/sparc/libsys/fchmod.s
  93. 3 0
      mach/sparc/libsys/fchown.s
  94. 3 0
      mach/sparc/libsys/fchroot.s
  95. 4 0
      mach/sparc/libsys/fcntl.s
  96. 67 0
      mach/sparc/libsys/fif.s
  97. 3 0
      mach/sparc/libsys/flock.s
  98. 3 0
      mach/sparc/libsys/fork.s
  99. 3 0
      mach/sparc/libsys/fstat.s
  100. 3 0
      mach/sparc/libsys/fstatfs.s

+ 15 - 0
mach/sparc/ce/.distr

@@ -0,0 +1,15 @@
+EM_table
+EM_table.x
+Makefile
+back.src
+cache.c
+cache.c.x
+ce.src
+cegpp
+mach.c
+mach.h
+mach_em.h
+misc.h
+ms_reg.h
+proto.make
+push_pop.h

+ 4631 - 0
mach/sparc/ce/EM_table.x

@@ -0,0 +1,4631 @@
+/* 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(O0, reg_o0)
+define(O1, reg_o1)
+define(O2, reg_o2)
+define(O3, reg_o3)
+
+define(`BP_OFFSET',`'WINDOWSIZE)
+define(`'`EM_BSIZE',EM_BSIZE)
+define(STACK_CLICK,4)
+
+#if RESOLVE_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();
+				sprintf(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( "loi", $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();
+				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();
+					sprintf(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();
+					sprintf(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(O0);
+			push_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))
+		{
+			sprintf (n_exp_str, "%d", n_exp);
+			n= pop_const(NULL);
+			a= pop_reg();
+			if (n <0)
+			{
+				b= alloc_reg();
+				"neg	$a, $b";
+				free_reg(a);
+				a= b;
+			}
+			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	dvi4";
+			"nop"
+			free_output();
+			forced_alloc_reg(reg_o0);
+			push_reg(reg_o0);
+		}
+#else
+		not_implemented("dvi");
+#endif /* MATH_DIVIDE */
+	}.
+	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 */
+				"call	dvi4";
+				"nop"
+				free_output();
+				forced_alloc_reg(O1);
+				push_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(O0);
+			push_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))
+		{
+			sprintf (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(O1);
+			push_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();
+				inc_tos_reg(f1);
+			}
+			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)
+			{
+				a= pop_reg();
+				b= alloc_reg();
+				c= alloc_reg();
+				d= alloc_reg();
+				e= alloc_reg();
+				"srl	$a, 20, $b";
+				"and	$b, 0x7ff, $c";
+				"dec	0x3fe, $c";
+				"set	0x7ff00000, $b";
+				"andn	$a, $b, $d";
+				"set	0x3fe00000, $b";
+				"or	$d, $b, $e";
+				push_reg(e);
+				push_reg(c);
+				free_reg(a);
+				free_reg(b);
+				free_reg(d);
+			}
+			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:";
+			"ld	[$reg_sp], $a";
+			"srl	$a, 20, $b";
+			"and	$b, 0x7ff, $c";
+			"dec	0x3fe, $c";
+			"dec	STACK_CLICK, $reg_sp";
+			"st	$c, [$reg_sp]";
+			"set	0x7ff00000, $c";
+			"andn	$a, $c, $a";
+			"set	0x3fe00000, $c";
+			"or	$a, $c, $a";
+			"st	$a, [$reg_sp+STACK_CLICK]";
+		"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;
+			sprintf(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;
+			sprintf(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;
+			sprintf(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		==>
+			Comment0( cfu );
+			C_cfi().
+
+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)
+				{
+					sprintf(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();
+					sprintf(n_str, "%d", n);
+					"sll	$a, $n_str, $b";
+					sprintf(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();
+					sprintf(n_str, "%d", n);
+					"srl	$a, $n_str, $b";
+					sprintf(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
+			arg_error ("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();
+				sprintf(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)
+				{
+					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)
+				{
+					sprintf(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)
+				{
+					sprintf(i_str, "%d", i);
+					sprintf(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;
+				sprintf(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 );
+				"ld	[$reg_sp], $reg_lb";
+				"inc	STACK_CLICK, $reg_sp"
+				.
+	$1 == 1		==>
+	{
+		Comment( str , $1 );
+		pop_reg_as(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_sp);
+		push_reg(reg_lb);
+		inc_tos(-($1));
+		pop_reg_as(reg_sp);
+	}.

+ 13 - 0
mach/sparc/ce/Makefile

@@ -0,0 +1,13 @@
+SED = sed
+M4 = m4
+CPP = /lib/cpp
+
+all:	EM_table cache.c
+
+distr:	all
+
+EM_table:	EM_table.x cegpp
+	$(CPP) < EM_table.x -P | $(M4) | $(SED) -f cegpp > $@
+	
+cache.c:	cache.c.x cegpp
+	$(SED) -f cegpp cache.c.x > $@

+ 9 - 0
mach/sparc/ce/back.src/.distr

@@ -0,0 +1,9 @@
+Makefile
+back.h
+con_str.c
+const.h
+do_open.c
+gen_str.c
+header.h
+rom_str.c
+symboldef.c

+ 101 - 0
mach/sparc/ce/back.src/Makefile

@@ -0,0 +1,101 @@
+# $Header$
+
+# requires a definition for TARGET_HOME, SRC_DIR, CFLAGS, CC
+
+CEG=$(TARGET_HOME)/lib.bin/ceg
+SOURCE=$(CEG)/ce_back/as_back
+
+IDIRS=-I.\
+      -I$(SRC_DIR)\
+      -I..\
+      -I$(TARGET_HOME)/h\
+      -I$(TARGET_HOME)/modules/h
+
+all : bottom.o con1.o con2.o con4.o end_back.o gen1.o gen2.o\
+      gen4.o init_back.o reloc1.o reloc2.o reloc4.o bss.o\
+      rom1.o rom2.o rom4.o set_global.o set_local.o switchseg.o symboldef.o \
+      do_open.o do_close.o text1.o text2.o text4.o con_str.o gen_str.o rom_str.o
+
+bottom.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/bottom.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/bottom.c
+
+bss.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/bss.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/bss.c
+
+text1.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/text1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/text1.c
+
+text2.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/text2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/text2.c
+
+text4.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/text4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/text4.c
+
+con1.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/con1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con1.c
+
+con2.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/con2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con2.c
+
+con4.o : $(SRC_DIR)/mach.h back.h header.h $(SOURCE)/con4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con4.c
+
+do_open.o : back.h header.h $(SRC_DIR)/mach.h do_open.c
+	$(CC) $(CFLAGS) -c $(IDIRS) do_open.c
+
+do_close.o :  back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/do_close.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/do_close.c
+
+gen1.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/gen1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen1.c
+
+gen2.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/gen2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen2.c
+
+gen4.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/gen4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen4.c
+
+init_back.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/init_back.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/init_back.c
+
+end_back.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/end_back.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/end_back.c
+
+reloc1.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/reloc1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc1.c
+
+reloc2.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/reloc2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc2.c
+
+reloc4.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/reloc4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc4.c
+
+rom1.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/rom1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom1.c
+
+rom2.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/rom2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom2.c
+
+rom4.o : back.h header.h $(SRC_DIR)/mach.h $(SOURCE)/rom4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom4.c
+
+set_global.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/set_global.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/set_global.c
+
+set_local.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/set_local.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/set_local.c
+
+switchseg.o : header.h back.h $(SRC_DIR)/mach.h $(SOURCE)/switchseg.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/switchseg.c
+
+symboldef.o : header.h back.h $(SRC_DIR)/mach.h symboldef.c
+	$(CC) $(CFLAGS) -c $(IDIRS) symboldef.c
+
+con_str.o : header.h back.h $(SRC_DIR)/mach.h con_str.c
+	$(CC) $(CFLAGS) -c $(IDIRS) con_str.c
+
+gen_str.o : header.h back.h $(SRC_DIR)/mach.h gen_str.c
+	$(CC) $(CFLAGS) -c $(IDIRS) gen_str.c
+
+rom_str.o : header.h back.h $(SRC_DIR)/mach.h rom_str.c
+	$(CC) $(CFLAGS) -c $(IDIRS) rom_str.c

+ 69 - 0
mach/sparc/ce/back.src/back.h

@@ -0,0 +1,69 @@
+#include <em.h>
+#include <system.h>
+
+#define codefile	B_codefile
+#define cur_seg		B_cur_seg
+#define saved		B_saved
+#define labeltje	B_labeltje
+#define name		B_name
+#define output_back	B_output_back
+
+/* Macros to change interface names */
+
+#define common		B_common
+#define con1		B_con1
+#define con2		B_con2
+#define con4		B_con4
+#define con_str		B_con_str
+#define rom1		B_rom1
+#define rom2		B_rom2
+#define rom4		B_rom4
+#define rom_str		B_rom_str
+#define text1		B_txt1
+#define text2		B_txt2
+#define text4		B_txt4
+#define close_back	B_close_back
+#define open_back	B_open_back
+#define end_back	B_end_back
+#define init_back	B_init_back
+#define extnd_pro	B_ex_pro
+#define extnd_start	B_ex_start
+#define extnd_name	B_ex_name
+#define extnd_dnam	B_ex_dnam
+#define extnd_dlb	B_ex_dlb
+#define extnd_ilb	B_ex_ilb
+#define extnd_hol	B_ex_hol
+#define extnd_part	B_ex_part
+#define extnd_cont	B_ex_cont
+#define extnd_main	B_ex_main
+#define gen1		B_gen1
+#define gen2		B_gen2
+#define gen4		B_gen4
+#define gen_str		B_gen_str
+#define save_label	B_save_label
+#define dump_label	B_dump_label
+#define align_word	B_align_word
+#define reloc1		B_rlc1
+#define reloc2		B_rlc2
+#define reloc4		B_rlc4
+#define set_global_visible	B_stglobvis
+#define set_local_visible	B_stlocvis
+#define symbol_definition	B_symdef
+#define switchseg		B_switchseg
+
+extern File *codefile;
+
+extern char *extnd_name(), *extnd_dnam(), *extnd_dlb(), *extnd_ilb(),
+	    *extnd_hol(), *extnd_ext(), *extnd_pro(), *extnd_start(),
+	    *extnd_part(), *extnd_cont(), *extnd_main();
+
+#define 	swtxt() 	switchseg( SEGTXT)
+#define		bss(n)		fprint(codefile, BSS_FMT, (long)(n))
+
+#define 	SEGTXT		0
+#define 	SEGROM		1
+#define 	SEGCON		2
+#define 	SEGBSS		3
+#define 	SEGHOL		-1	/* Does not exist */
+
+#define 	ABSOLUTE	1

+ 8 - 0
mach/sparc/ce/back.src/con_str.c

@@ -0,0 +1,8 @@
+#include "header.h"
+
+con_str(s,n)
+char *s;
+int n;
+{
+	gen_str( s,n);
+}

+ 2 - 0
mach/sparc/ce/back.src/const.h

@@ -0,0 +1,2 @@
+#define TRUE	1
+#define FALSE 	0

+ 11 - 0
mach/sparc/ce/back.src/do_open.c

@@ -0,0 +1,11 @@
+#include "header.h"
+
+open_back( filename)
+char *filename;
+{
+	if ( filename == (char *) 0)
+		codefile= STDOUT;
+	else
+		return( sys_open( filename, OP_WRITE, &codefile));
+	return 1;
+}

+ 27 - 0
mach/sparc/ce/back.src/gen_str.c

@@ -0,0 +1,27 @@
+#include "header.h"
+
+gen_str( s,n)
+char *s;
+int n;
+{
+	unsigned char c;
+	switch ( cur_seg) {
+	  case SEGTXT :
+	  case SEGCON :
+	  case SEGROM :
+			fprint( codefile, "%s\"", STR_FMT);
+			while (n--)
+			{
+				c= *s++;
+				if (isprint(c) && c != '"')
+					fprint(codefile, "%c", c);
+				else
+					fprint(codefile, "\\%03o", c);
+			}
+			fprint( codefile, "\"\n");
+			break;
+	  case SEGBSS : bss( (arith) 1);
+			break;
+	  default : fprint( STDERR, "gen1 unkown seg %d\n", cur_seg);
+	}
+}

+ 4 - 0
mach/sparc/ce/back.src/header.h

@@ -0,0 +1,4 @@
+#include "mach.h"
+#include "back.h"
+
+extern int cur_seg;

+ 8 - 0
mach/sparc/ce/back.src/rom_str.c

@@ -0,0 +1,8 @@
+#include "header.h"
+
+rom_str( s,n)
+char *s;
+int n;
+{
+	gen_str( s,n);
+}

+ 9 - 0
mach/sparc/ce/back.src/symboldef.c

@@ -0,0 +1,9 @@
+#include "header.h"
+
+symbol_definition( s)
+char *s;
+{
+	if (cur_seg == SEGTXT)
+		flush_cache();	/* EXTRA */
+	fprint( codefile, SYMBOL_DEF_FMT, s);
+}

+ 1287 - 0
mach/sparc/ce/cache.c.x

@@ -0,0 +1,1287 @@
+/* cache.c */
+
+#include <stdio.h>
+#include </usr/include/assert.h>
+#include <malloc.h>
+#include <string.h>
+#include <strings.h>
+#include "mach.h"
+
+#define free_reg_num(i) if (1) { assert(reg[i].inuse > 0); reg[i].inuse--; if (debug) fprintf(stderr,"free_reg(%s)\n", regnam[i]); } else
+
+#define POP1 cache_need(1);
+#define POP2 { --tos; assert(c_count); --c_count; }
+
+int indent_count = 0;
+
+#define enter(x) indent_count++;
+#define indent() { int i = indent_count; while (i--) putc('\t', stderr); }
+#define leave(x) indent_count--;
+
+/* procedures:
+		const13(int)		boolean proc
+		init_cache()		mandatory
+		free_reg(reg_t)
+		forced_alloc_reg(reg_t)
+		soft_alloc_reg(reg_t)
+		change_reg(reg_t)	used when reg on stack has changed
+		type_of_tos()		bit-field representation of ext/reg/cst
+		inc_tos(int)		tos->cst += n
+		push_const(int)
+		push_reg(reg_t)
+		push_ext(char *)
+		flush_cache()		after branches and labels
+		cache_read(int)		read-ahead. optimization only
+		dump_cache(FILE *)	debug info: show current stack
+		pop_nop()		remove element from cache
+
+		reg_t alloc_reg()
+		reg_t pop_reg()
+		reg_t pop_reg_c13(char*)
+
+		arith pop_const(char *)
+		arith top_const()
+
+		alloc_float, alloc_double, free_double,
+		pop_float, pop_double, push_float, push_double
+
+*/
+
+typedef struct regdat_t {
+		int	inuse;		/* free == 0, otherwise #owners */
+} regdat_t;
+/*
+typedef struct cache_elt {
+	reg_t	reg, reg2;
+	char	*ext;
+	arith	cst;
+} cache_elt;
+*/
+char regnam[][8] = {
+/*x*/	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
+/*x*/	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%i6", "%i7",
+/*x*/	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
+/*x*/	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o6", "%o7",
+/*x*/	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+/*x*/	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
+/*x*/	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
+/*x*/	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31"
+};
+
+reg_t reg_g0, reg_g1, reg_g2, reg_g3, reg_g4, reg_g5, reg_g6, reg_g7;
+reg_t reg_i0, reg_i1, reg_i2, reg_i3, reg_i4, reg_i5, reg_i6, reg_i7;
+reg_t reg_l0, reg_l1, reg_l2, reg_l3, reg_l4, reg_l5, reg_l6, reg_l7;
+reg_t reg_o0, reg_o1, reg_o2, reg_o3, reg_o4, reg_o5, reg_o6, reg_o7;
+reg_t reg_f0;
+reg_t reg_sp, reg_lb, reg_gap;
+reg_t reg_tmp, reg_lin, reg_fil;
+
+struct regdat_t reg[NR_REGS];
+
+#define POP_SIZE 1	/* maybe >1  (read-ahead cache) or explicit?! */
+#define CACHE_SIZE 32	/* ? */
+#define LO_GLOB		0
+#define HI_GLOB		7
+#define LO_IN		8
+#define HI_IN		15
+#define LO_LOC		16
+#define HI_LOC		23
+#define LO_OUT		24
+#define HI_OUT		31
+#define LO_FLOAT	32
+#define HI_FLOAT	63
+const13(x) 
+{
+	return (x < 4096 && x >= -4096);
+}
+
+struct cache_elt cache[CACHE_SIZE], *tos = 0;
+int c_count = 0;
+const_str_t s;
+
+static void panic(s)
+char *s;
+{
+	printf("PANIC: %s\n", s);
+	exit(1);
+}
+
+void init_cache()
+{
+	int i;
+
+	for (i = 0; i < NR_REGS; i++)
+		reg[i].inuse = 0;
+
+	reg_g0 = regnam[000];
+	reg_g1 = regnam[001];
+	reg_g2 = regnam[002];
+	reg_g3 = regnam[003];
+	reg_g4 = regnam[004];
+	reg_g5 = regnam[005];
+	reg_g6 = regnam[006];
+	reg_g7 = regnam[007];
+
+	reg_i0 = regnam[010];
+	reg_i1 = regnam[011];
+	reg_i2 = regnam[012];
+	reg_i3 = regnam[013];
+	reg_i4 = regnam[014];
+	reg_i5 = regnam[015];
+	reg_i6 = regnam[016];
+	reg_i7 = regnam[017];
+
+	reg_l0 = regnam[020];
+	reg_l1 = regnam[021];
+	reg_l2 = regnam[022];
+	reg_l3 = regnam[023];
+	reg_l4 = regnam[024];
+	reg_l5 = regnam[025];
+	reg_l6 = regnam[026];
+	reg_l7 = regnam[027];
+
+	reg_o0 = regnam[030];
+	reg_o1 = regnam[031];
+	reg_o2 = regnam[032];
+	reg_o3 = regnam[033];
+	reg_o4 = regnam[034];
+	reg_o5 = regnam[035];
+	reg_o6 = regnam[036];
+	reg_o7 = regnam[037];
+
+	reg_f0 = regnam[040];
+
+	reg_sp = reg_l0;
+	reg_lb = reg_l1;
+	reg_gap = reg_g4;
+	reg_tmp = reg_o7;
+	forced_alloc_reg(reg_g0);	/* can not be used as a reg */
+	forced_alloc_reg(reg_o6);
+	forced_alloc_reg(reg_o7);
+	forced_alloc_reg(reg_i6);
+	forced_alloc_reg(reg_i7);
+}
+
+static void flush_part_cache(n,r,f,d)
+int n,r,f,d;
+{
+/* free at least n entries, r integer registers, f float regs and d double regs
+ */
+	int i, ready;
+	int rn, j;
+	const_str_t i_str, e_str, n_str;
+	char *ext, R1, R2;
+	reg_t rh, rt;
+
+enter("flush_part_cache");
+	for (i = 0; i < c_count; i++)
+	{
+		if (i >= n && !r && !f && !d)
+			break;
+		if (cache[i].reg != reg_g0)
+		{
+			rn= REG_NUM(cache[i].reg);
+			free_reg_num(rn);
+			if (!reg[rn].inuse)
+				if (rn<LO_FLOAT)
+				{
+					if (r)
+						r--;
+				}
+				else
+				{
+					if (d && (((rn & 1) &&
+					!reg[rn-1].inuse) ||
+					(!(rn & 1) && !reg[rn+1].inuse)))
+						d--;
+					if (f)
+						f--;
+				}
+		}
+		if (cache[i].reg2 != reg_g0)
+		{
+			rn= REG_NUM(cache[i].reg2);
+			free_reg_num(rn);
+			if (!reg[rn].inuse)
+				if (rn<LO_FLOAT)
+				{
+					if (r)
+						r--;
+				}
+				else
+				{
+					if (d && (((rn & 1) &&
+					!reg[rn-1].inuse) ||
+					(!(rn & 1) && !reg[rn+1].inuse)))
+						d--;
+					if (f)
+						f--;
+				}
+		}
+	}
+	if (r || f || d)
+		panic ("can't free enough registers");
+	j = i;
+	if (i)
+	{
+		sprintf (i_str, "%d", 4*i);
+		"dec	$i_str, $reg_sp";
+		while (i--)
+		{
+			sprintf(i_str, "%d", 4*(j-1-i));
+			if (cache[i].ext)
+			{
+				ext= cache[i].ext;
+				sprintf (e_str, "%d", cache[i].cst);
+				"set	$ext+$e_str, $reg_tmp";
+				"st	$reg_tmp, [$reg_sp+$i_str]";
+				free(ext);
+			}
+			else
+			{
+				if (cache[i].reg2 != reg_g0)
+				{
+					rt = cache[i].reg;
+					rh = cache[i].reg2;
+					"add	$rt, $rh, $reg_tmp";
+					cache[i].reg = reg_tmp;
+					cache[i].reg2 = reg_g0;
+				}
+				if (!const13(cache[i].cst))
+				{
+					sprintf(n_str, "%d",
+						cache[i].cst);
+					"sethi	%hi($n_str), $reg_tmp";
+					if (cache[i].reg != reg_g0)
+					{
+						rt = cache[i].reg;
+						"add	$reg_tmp, $rt, $reg_tmp";
+					}
+					rh= reg_tmp;
+					cache[i].cst &= 0x3ff;
+				}
+				else {
+					rh= cache[i].reg;
+				}
+				if (cache[i].cst)
+				{
+					sprintf(n_str, "%d", cache[i].cst);
+					"add	$rh, $n_str, $reg_tmp";
+					rh= reg_tmp;
+				}
+				"st	$rh, [$reg_sp+$i_str]";
+			}
+		}
+		for (i= j; i < c_count; i++)
+			cache[i-j]= cache[i];
+		c_count -= j;
+		tos= &cache[c_count-1];
+	}
+leave("flush_part_cache");
+}
+
+reg_t alloc_reg()
+{
+	int i;
+	reg_t res = NULL;
+
+enter("alloc_reg");
+	for (i = LO_GLOB+1 /* SPEED-HACK */; i <= HI_GLOB; i++) {
+		if (reg[i].inuse)
+			continue;
+		reg[i].inuse = 1;	/* allocate */
+		res = regnam[i];
+		break;
+	}
+	if (!res)
+		for (i = LO_IN; i <= HI_IN; i++) {
+			if (reg[i].inuse)
+				continue;
+			reg[i].inuse = 1;	/* allocate */
+			res = regnam[i];
+			break;
+		}
+		if (!res)
+			for (i = LO_LOC; i <= HI_LOC; i++) {
+				if (reg[i].inuse)
+					continue;
+				reg[i].inuse = 1;	/* allocate */
+				res = regnam[i];
+				break;
+			}
+			if (!res)
+				for (i = LO_OUT; i <= HI_OUT; i++) {
+					if (reg[i].inuse)
+						continue;
+					reg[i].inuse = 1;	/* allocate */
+					res = regnam[i];
+					break;
+				}
+				if (!res) {
+					flush_part_cache(c_count/2,1,0,0);
+					res = alloc_reg();
+				}
+if (debug) { indent(); fprintf(stderr,"alloc_reg() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_reg");
+	return res;
+}
+
+reg_t alloc_float()
+{
+	int i;
+	reg_t res = NULL;
+
+enter("alloc_float");
+	for (i = LO_FLOAT+15; i >= LO_FLOAT; i--) {
+		if (reg[i].inuse)
+			continue;
+		reg[i].inuse = 1;	/* allocate */
+		res = regnam[i];
+		break;
+	}
+	if (!res) {
+		flush_part_cache(c_count/2,0,1,0);
+		res = alloc_float();
+	}
+if (debug) { indent(); fprintf(stderr,"alloc_float() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_float");
+	return res;
+}
+
+reg_t alloc_double(sub_reg)
+reg_t *sub_reg;
+{
+	int i;
+	reg_t res = NULL;
+
+enter("alloc_double");
+	for (i = LO_FLOAT+14; i >= LO_FLOAT; i -= 2) {
+		if (reg[i].inuse || reg[i+1].inuse)
+			continue;
+		reg[i].inuse = 1;	/* allocate */
+		reg[i+1].inuse = 1;	/* allocate */
+if (debug) { indent(); fprintf(stderr,"alloc_double() = %s\n", regnam[i]); }
+		if (sub_reg)
+			*sub_reg= regnam[i+1];
+		res = regnam[i];
+		break;
+	}
+	if (!res) {
+		flush_part_cache(c_count/2,0,0,1);
+		res = alloc_double(sub_reg);
+	}
+if (debug) { indent(); fprintf(stderr,"alloc_double() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_double");
+	return res;
+}
+
+reg_t alloc_reg_var()		/* ins and locals only */
+{
+	int i;
+	reg_t res = NULL;
+
+enter("alloc_reg_var");
+	for (i = LO_LOC +2 /* SPEED-HACK */; i <= HI_LOC; i++) {
+		if (reg[i].inuse)
+			continue;
+		reg[i].inuse = 1;	/* allocate */
+		res = regnam[i];
+		break;
+	}
+	if (!res)
+		for (i = LO_IN; i <= HI_IN; i++) {
+			if (reg[i].inuse)
+				continue;
+			reg[i].inuse = 1;	/* allocate */
+			res = regnam[i];
+			break;
+		}
+if (debug) { indent(); fprintf(stderr,"alloc_reg_var() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_reg_var");
+	return res;
+}
+
+reg_t alloc_float_var()
+{
+	int i;
+	reg_t res = NULL;
+
+enter("alloc_float_var");
+	for (i= LO_FLOAT+16; i<= HI_FLOAT; i++)
+	{
+		if (reg[i].inuse)
+			continue;
+		reg[i].inuse = 1;	/* allocate */
+		res = regnam[i];
+		break;
+	}
+if (debug) { indent(); fprintf(stderr,"alloc_reg_var() = %s\n", res ? regnam[i] : "NULL"); }
+leave("alloc_float_var");
+	return res;
+}
+
+reg_t alloc_double_var(sub_reg)
+reg_t *sub_reg;
+{
+	int i;
+	reg_t res = NULL;
+
+enter("alloc_double_var");
+	for (i = LO_FLOAT+16; i < HI_FLOAT; i += 2) {
+		if (reg[i].inuse || reg[i+1].inuse)
+			continue;
+		reg[i].inuse = 1;	/* allocate */
+		reg[i+1].inuse = 1;	/* allocate */
+if (debug) { indent(); fprintf(stderr,"alloc_double_var() = %s\n", regnam[i]); }
+		if (sub_reg)
+			*sub_reg= regnam[i+1];
+		res = regnam[i];
+		break;
+	}
+if (debug) { indent(); fprintf(stderr,"alloc_double_var() = %s\n", res? regnam[i] : "NULL"); }
+leave("alloc_double_var");
+	return res;
+}
+
+void free_reg(i)
+reg_t i;
+{
+	int r;
+
+enter("free_reg");
+	if (i != 0 && i != reg_g0) {
+		r = REG_NUM(i);
+		assert(0 <= r && r <= NR_REGS);
+		assert(reg[r].inuse > 0);	/* "freeing unused register" */
+		reg[r].inuse--;
+	}
+if (debug) { indent(); fprintf(stderr,"free_reg(%s)\n", i); }
+leave("free_reg");
+}
+
+void free_double_reg(i)
+reg_t i;
+{
+	int rn;
+
+enter("free_double_reg");
+	rn= REG_NUM(i);
+	assert (!(rn & 1));
+	free_reg(i);
+	free_reg(regnam[rn+1]);
+leave("free_double_reg");
+}
+
+
+void force_alloc_output()	/* TMP HACK */
+{
+	int i;
+
+enter("force_alloc_output");
+if (debug) { indent(); fprintf(stderr,"force_alloc_output\n"); }
+	for (i = REG_NUM(reg_o0); i <= REG_NUM(reg_o5); i++)
+		forced_alloc_reg(regnam[i]);
+leave("force_alloc_output");
+}
+
+void free_output()
+{
+	int i;
+
+enter("free_output");
+leave("free_output");
+if (debug) { indent(); fprintf(stderr,"free_output\n"); }
+	for (i = REG_NUM(reg_o0); i <= REG_NUM(reg_o5); i++) {
+		assert(reg[i].inuse > 0);
+		reg[i].inuse--;
+	}
+}
+
+void soft_alloc_reg(i)
+reg_t i;
+{
+enter("soft_alloc_reg");
+if (debug) { indent(); fprintf(stderr,"soft_alloc_reg(%s)\n", i); }
+	/* assert(reg[REG_NUM(i)].inuse); */
+	reg[REG_NUM(i)].inuse++;
+leave("soft_alloc_reg");
+}
+
+void forced_alloc_reg(i)
+reg_t i;
+{
+	int r;
+
+enter("forced_alloc_reg");
+if (debug) { indent(); fprintf(stderr,"forced_alloc_reg(%s)\n", i); }
+
+	r = REG_NUM(i);
+
+	if (reg[r].inuse) {
+		reg_t S1;
+		char *V2;
+
+		S1 = alloc_reg();
+if (debug) { indent(); fprintf(stderr,"---> inuse: moving to %s\n", S1); }
+		"mov	$i, $S1";
+		subst_reg(i, S1);
+		free_reg(S1);
+		if (reg[r].inuse)
+			panic("forced_alloc_reg: external owners left!");
+	}
+	reg[r].inuse = 1;
+leave("forced_alloc_reg");
+}
+
+void change_reg(r)	/* to be called when register r changes */
+reg_t r;
+{
+	int i;
+
+enter("change_reg");
+if (debug) { indent(); fprintf(stderr, "change_reg(%s)\n", r); }
+	if (r != reg_g0)
+		for (i = 0; i < c_count; i++)
+			if (cache[i].reg == r || cache[i].reg2 == r) {
+				reg_t S1;
+
+				if (r >= reg_f0) {
+					S1 = alloc_float();
+					"fmovs	$r, $S1";
+				} else {
+					S1 = alloc_reg();
+					"mov	$r, $S1";
+				}
+				subst_reg(r, S1);
+				free_reg(S1);
+				break;
+			}
+leave("change_reg");
+}
+
+static void subst_reg(old, new)
+reg_t old, new;
+{
+	int i;
+
+enter("subst_reg");
+if (debug) { indent(); fprintf(stderr,"subst_reg(%s, %s)\n", old, new); }
+	for (i = 0; i < c_count; i++) {
+		if (cache[i].reg == old) {
+			cache[i].reg = new;
+			free_reg(old);
+			soft_alloc_reg(new);
+		}
+		if (cache[i].reg2 == old) {
+			cache[i].reg2 = new;
+			free_reg(old);
+			soft_alloc_reg(new);
+		}
+	}
+leave("subst_reg");
+}
+
+int type_of_tos()
+{
+	int r = 0;
+
+	cache_need(1);
+
+	if (tos->ext)
+		r |= T_ext;
+	if (tos->reg != reg_g0)
+		if (tos->reg >= reg_f0)
+			r |= T_float;
+		else
+			r |= T_reg;
+	if (tos->reg2 != reg_g0)
+		if (tos->reg2 >= reg_f0)
+			r |= T_float2;
+		else
+			r |= T_reg2;
+	if (tos->cst)
+		r |= T_cst;
+	return r;
+}
+
+arith top_const()
+{
+enter("top_const");
+	assert(type_of_tos() == T_cst);
+if (debug) { indent(); fprintf(stderr,"top_const()=%d\n", tos->cst); }
+leave("top_const");
+	return tos->cst;
+}
+
+reg_t pop_reg_reg(r)
+reg_t *r;
+{
+	reg_t s;
+
+enter("pop_reg_reg");
+	POP1;
+	if (!(type_of_tos() & T_reg2))
+		push_reg(pop_reg());
+	assert(r);
+	*r = tos->reg2;
+	s = tos->reg;
+	POP2;
+if (debug) { indent(); fprintf(stderr,"pop_reg_reg()=%s\n", s); fprint(codefile,"\t\t! "); dump_cache(codefile); }
+leave("pop_reg_reg");
+	return s;
+}
+
+reg_t pop_reg_c13(n)		/* returns reg_t + optional n (as string) */
+char *n;
+{
+	reg_t S1, S2, S3;
+	register char *V1;
+	const_str_t V2;
+enter("pop_reg_c13");
+if (debug) { indent(); fprintf(stderr,"pop_reg_c13()=...\n"); }
+	*n = '0';
+	*(n+1) = 0;
+	cache_need(1);
+
+	if (tos->reg >= reg_f0) {	/* convert float to int */
+		S1= pop_float();
+		S2= alloc_reg();
+		"st	$S1, [%fp+64]";
+		"ld	[%fp+64], $S2";
+		free_reg(S1);
+		S1 = S2;
+	}
+	else if (tos->reg2 != reg_g0) {	/* add integers */
+		S1 = pop_reg();
+	}
+	else if (tos->ext) {
+		assert(tos->reg == reg_g0);
+		S1 = alloc_reg();
+		V1 = tos->ext;
+		sprintf(V2, "%d", tos->cst);
+		"sethi	%hi($V1+$V2), $S1";
+		sprintf(n, "%%lo(%s+%d)", tos->ext, tos->cst);
+		free(V1);
+		POP2;
+	} else {
+		S1 = tos->reg;
+		if (!(const13(tos->cst))) {
+			S3 = alloc_reg();
+			sprintf(V2, "%d", tos->cst);
+			"sethi	%hi($V2), $S3";
+			if (tos->reg != reg_g0) {
+				S2 = alloc_reg();
+				"add	$S3, $S1, $S2";
+				free_reg(S1);
+				free_reg(S3);
+				S1 = S2;
+			}
+			tos->cst &= 0x3FF;
+		}
+		sprintf(n, "%d", tos->cst);
+		POP2;
+	}
+if (debug) { indent(); fprint(codefile, "\t\t! %s+%s cache:", S1, n); dump_cache(codefile);}
+leave("pop_reg_c13");
+	return S1;
+}
+
+reg_t pop_float()
+{
+	reg_t S1, R1, R2;
+	char *V1, *V2;
+
+enter("pop_float");
+	cache_need(1);
+	S1 = tos->reg;
+	if (!(type_of_tos() & T_float)) {
+		S1 = pop_reg();
+		R2 = alloc_float();
+		"st	$S1, [%fp+64]";
+		"ld	[%fp+64], $R2";
+		free_reg(S1);
+		S1 = R2;
+	}
+	else if (tos->reg2 >= reg_f0) {
+		R1 = tos->reg2;
+		R2 = alloc_float();
+		"fadds	$S1, $R1, $R2";
+		free_reg(S1);	
+		free_reg(R1);	
+		S1 = R2;
+		POP2;
+	} else
+		POP2;
+if (debug) { indent(); fprint(codefile, "\t\t! %s cache:", S1); dump_cache(codefile); }
+leave("pop_float");
+	return S1;
+}
+
+void inc_tos_reg(r)
+reg_t r;
+{
+enter("inc_tos_reg");
+if (debug) { indent(); fprintf(stderr, "inc_tos_reg(%s)\n", r); }
+	if (type_of_tos() != T_reg)
+		push_reg(pop_reg());
+	tos->reg2 = r;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("inc_tos_reg");
+}
+
+void inc_tos(n)
+arith n;
+{
+	reg_t S1;
+	char *V1, *V2;
+
+enter("inc_tos");
+if (debug) { indent(); fprintf(stderr,"inc_tos(%d)\n", n); }
+	cache_need(1);
+	if (tos->reg >= reg_f0)
+	{
+		S1= pop_reg();
+		push_reg(S1);
+	}
+	else if (tos->reg2 != reg_g0) {
+		S1= pop_reg();
+		push_reg(S1);
+	}
+	tos->cst += n;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("inc_tos");
+}
+
+#define INC_TOS	if (c_count >= CACHE_SIZE) flush_part_cache(c_count/2,0,0,0); \
+			tos = &cache[c_count++];
+
+void push_const(n)
+arith n;
+{
+enter("push_const");
+	INC_TOS;
+	tos->reg = reg_g0;
+	tos->reg2 = reg_g0;
+	tos->ext = 0;
+	tos->cst = n;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_const");
+}
+
+void push_reg(i)
+reg_t i;
+{
+enter("push_reg");
+	assert(0 <= REG_NUM(i) && REG_NUM(i) < NR_REGS);
+	INC_TOS;
+	tos->reg = i;
+	tos->reg2 = reg_g0;
+	tos->ext = 0;
+	tos->cst = 0;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_reg");
+}
+
+
+void push_double_reg(i)
+reg_t i;
+{
+	int rn;
+
+enter("push_double_reg");
+	rn= REG_NUM(i);
+	assert (!(rn & 1));
+	INC_TOS;
+	tos->ext = 0;
+	tos->cst = 0;
+	tos->reg = regnam[rn+1];
+	tos->reg2 = reg_g0;
+	INC_TOS;
+	tos->ext = 0;
+	tos->cst = 0;
+	tos->reg = i;
+	tos->reg2 = reg_g0;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_double_reg");
+}
+
+void push_ext(s)
+char *s;
+{
+	char *p;
+
+enter("push_ext");
+	p = malloc(strlen(s)+1);
+	assert(p);
+
+	INC_TOS;
+	tos->reg = reg_g0;
+	tos->reg2 = reg_g0;
+	tos->ext = strcpy(p, s);
+	tos->cst = 0;
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("push_ext");
+}
+
+arith pop_const(n)
+char *n;
+{
+	arith x;
+
+enter("pop_const");
+	POP1;
+	x = top_const();
+	POP2;
+	if (n)
+		sprintf(n, "%d", x);
+if (debug) { indent(); fprint(codefile, "\t\t! %d cache:", x); dump_cache(codefile); }
+leave("pop_const");
+	return x;
+}
+
+void pop_reg_as(r)
+reg_t r;
+{
+	reg_t S1, S2;
+	register char *V1, *V3;
+	const_str_t V2, c_str;
+	char *tos_ext;
+	reg_t tos_reg, tos_reg2;
+	int tos_cst;
+
+enter("pop_reg_as");
+if (debug) { indent(); fprintf(stderr,"pop_reg_as(%s)=...\n", r); }
+	if (c_count == 0) {	/* special case */
+		"ld	[%l0], $r";
+		"inc	4, %l0";
+	} else if (r >= reg_f0) {
+		if (tos->reg < reg_f0)
+		{
+			S1= pop_reg();
+			change_reg(r);
+			"st	$S1, [%fp+64]";
+			"ld	[%fp+64], $r";
+			free_reg(S1);
+		}
+		else
+		{
+			if (tos->reg2 == reg_g0) {
+				S1= pop_float();
+				change_reg(r);
+				if (S1 != r)
+					"fmovs	$S1, $r";
+				free_reg(S1);
+			} else {
+				V1 = tos->reg;
+				V3 = tos->reg2;
+				POP2;
+				change_reg(r);
+				"fadds	$V1, $V3, $r";
+				free_reg(V1);
+				free_reg(V3);
+			}
+		}
+	} else if (tos->reg >= reg_f0) {
+		S1= pop_float();
+		change_reg(r);
+		"st	$S1, [%fp+64]";
+		"ld	[%fp+64], $r";
+		free_reg(S1);
+	} else if (tos->ext) {
+		assert(tos->reg == reg_g0);
+		V1 = tos->ext;
+		sprintf(V2, "%d", tos->cst);
+		"set	$V1+$V2, $r";
+		free(V1);
+		POP2;
+	} else {
+		POP1;
+		tos_reg= tos->reg;
+		tos_reg2= tos->reg2;
+		tos_cst= tos->cst;
+		POP2;
+		change_reg(r);
+		if (!const13(tos_cst))
+		{
+			assert (tos_reg2 == reg_g0);
+			if (tos_reg != reg_g0 || (tos_cst & 0x3ff))
+				tos_reg2= alloc_reg();
+			else
+			{
+				soft_alloc_reg(r);
+				tos_reg2= r;
+			}
+			sprintf(c_str, "%d", tos_cst);
+			"sethi	%hi($c_str), $tos_reg2";
+			tos_cst &= 0x3ff;
+			if (tos_reg == reg_g0)
+			{
+				tos_reg= tos_reg2;
+				tos_reg2= reg_g0;
+			}
+		}
+		if (tos_reg2 != reg_g0)
+		{
+			assert (tos_reg != reg_g0);
+			if (tos_cst)
+				S1= alloc_reg();
+			else
+			{
+				soft_alloc_reg(r);
+				S1= r;
+			}
+			"add	$tos_reg, $tos_reg2, $S1";
+			free_reg(tos_reg);
+			free_reg(tos_reg2);
+			tos_reg= S1;
+			tos_reg2= reg_g0;
+		}
+		if (tos_cst)
+		{
+			sprintf(c_str, "%d", tos_cst);
+			soft_alloc_reg(r);
+			"add	$tos_reg, $c_str, $r";
+			free_reg(tos_reg);
+			tos_reg= r;
+		}
+		if (tos_reg != r)
+			"mov	$tos_reg, $r";
+		free_reg(tos_reg);
+	}
+leave("pop_reg_as");
+}
+
+void pop_double_reg_as(rdl)
+reg_t rdl;
+{
+	reg_t rl, rh;
+	reg_t rdh;
+	reg_t t;
+	int rn;
+	
+enter("pop_double_reg_as");
+	rn= REG_NUM(rdl);
+	assert (!(rn & 1));
+	rdh= regnam[rn+1];
+	if (rdl>= reg_f0)
+	{
+		if (c_count == 0) {
+			"ld	[%l0], $rdl";
+			"ld	[%l0+4], $rdh";
+			"inc	8, %l0";
+		} else {
+			if (type_of_tos() & T_float)
+				rl= pop_float();
+			else
+				rl= pop_reg();
+			if (type_of_tos() & T_float)
+				rh= pop_float();
+			else
+				rh= pop_reg();
+			change_reg(rdl);
+			change_reg(rdh);
+			if (rl < reg_f0 && rh < reg_f0)
+			{
+				"st	$rl, [%fp+64]";
+				"st	$rh, [%fp+68]";
+				"ldd	[%fp+64], $rdl";
+				free_reg(rl);
+				free_reg(rh);
+			}
+			else if (rl < reg_f0)
+			{
+				if (rh != rdh)
+					"fmovs	$rh, $rdh";
+				"st	$rl, [%fp+64]";
+				"ld	[%fp+64], $rdl";
+				free_reg(rl);
+				free_reg(rh);
+			}
+			else if (rh < reg_f0)
+			{
+				if (rl != rdl)
+					"fmovs	$rl, $rdl";
+				"st	$rh, [%fp+64]";
+				"ld	[%fp+64], $rdh";
+				free_reg(rl);
+				free_reg(rh);
+			} else {
+				if (rdl == rl)
+					free_reg(rl);
+				if (rdh == rh)
+					free_reg(rh);
+				if (rdl == rh && rdh == rl)
+				{
+					t= alloc_float();
+					"fmovs	$rl, $t";
+					free_reg(rl);
+					rl= t;
+				}
+				if (rdl != rl && rdl != rh)
+				{
+					"fmovs	$rl, $rdl";
+					free_reg(rl);
+					rl= rdl;
+				}
+				if (rdh != rh && rdh != rl)
+				{
+					"fmovs	$rh, $rdh";
+					free_reg(rh);
+					rh= rdh;
+				}
+				if (rdl != rl && rdl != rh)
+				{
+					"fmovs	$rl, $rdl";
+					free_reg(rl);
+					rl= rdl;
+				}
+				assert (rdl == rl && rdh == rh);
+			}
+		}
+	}
+	else
+	{
+		pop_reg_as (rdl);
+		pop_reg_as (rdh);
+	}
+leave("pop_double_reg_as");
+}
+
+			
+		
+reg_t pop_reg()
+{
+	reg_t S1;
+
+enter("pop_reg");
+	POP1;
+	if (type_of_tos() == T_reg) {
+		S1 = tos->reg;
+		POP2;
+	} else {
+		S1 = alloc_reg();
+		pop_reg_as(S1);
+	}
+if (debug) { indent(); fprint(codefile, "\t\t! %s cache:", S1); dump_cache(codefile); }
+leave("pop_reg");
+	return S1;
+}
+
+
+reg_t pop_double(sub_reg)	/* pop_double_float actually */
+reg_t *sub_reg;
+{
+	reg_t R1, R2, R3, R4;
+	char *V1, *V2;
+
+enter("pop_double");
+	if (c_count == 0) {
+		R1 = alloc_double(&R2);
+		"ld	[%l0], $R1";
+		"ld	[%l0+4], $R2";
+		"inc	8, %l0";
+		if (sub_reg)
+			*sub_reg = R2;
+	} else {
+		cache_need(2);
+		if (tos->reg >= reg_f0 && tos[-1].reg >= reg_f0 &&
+			REG_NUM(tos->reg) == REG_NUM(tos[-1].reg)-1 &&
+			tos->reg2 == reg_g0 && tos[-1].reg2 == reg_g0)
+		{
+			R1= tos->reg;
+			if (sub_reg)
+				*sub_reg= tos[-1].reg;
+			POP2;
+			POP2;
+		} else {
+			R1= alloc_double(&R2);
+			if (sub_reg)
+				*sub_reg= R2;
+			if (tos->reg >= reg_f0 || tos[-1].reg >= reg_f0)
+			{
+				pop_reg_as(R1);
+				pop_reg_as(R2);
+			} else {
+				/* two normal registers */
+				R3= pop_reg();
+				R4= pop_reg();
+				"st	$R3, [%fp+64]";
+				"st	$R4, [%fp+68]";
+				"ldd	[%fp+64], $R1";
+				free_reg(R3);
+				free_reg(R4);
+			}
+		}
+	}
+leave("pop_double");
+	return R1;
+}
+
+void pop_nop(i)
+int i;
+{
+	const_str_t V1;
+	int j = i;
+
+enter("pop_nop");
+	while (c_count && i) {
+		i--;
+		POP1;
+		free_reg(tos->reg);
+		free_reg(tos->reg2);
+		if (tos->ext)
+			free(tos->ext);
+		POP2;
+	}
+	if (i) {
+		sprintf(V1, "%d", 4*i);
+		if (const13(4*i)) {
+			"inc	$V1, %l0";
+		} else {
+			"set	$V1, $reg_tmp";
+			"inc	%l0, $reg_tmp, %l0";
+		}
+	}
+if (debug) { indent(); fprint(codefile, "\t\t! %dw cache:",j); dump_cache(codefile); }
+leave("pop_nop");
+}
+
+check_cache()
+{
+	int i;
+if (debug)
+	for (i = 0; i < NR_REGS; i++)
+		fprintf(stderr, "%c", reg[i].inuse ? (reg[i].inuse)+48 : '.');
+	fprintf(stderr, "\n");
+}
+
+void flush_cache()		/* flush the cache onto the stack */
+{
+enter("flush_cache");
+
+if (debug) { indent(); fprintf(stderr,"flush_cache\n"); }
+	if (c_count)
+		flush_part_cache(c_count, 0, 0, 0);
+
+	/* TEST */
+if (debug)
+	check_cache();
+leave("flush_cache");
+}
+
+void cache_need(n)
+int n;
+{
+enter("cache_need");
+	if (c_count < n)
+		(void) cache_read(n, 0);
+	assert(c_count >= n);
+leave("cache_need");
+}
+
+static int cache_read(n, i)
+int n;
+int i;
+{
+	const_str_t V1;
+	reg_t S1;
+	int j;
+	int old_c_count;
+
+enter("cache_read");
+if (debug) { indent(); fprintf(stderr,"cache_read(%d, %d)\n", n,i); }
+	if (i+c_count<n)
+	{
+		S1= alloc_reg();
+		old_c_count = cache_read(n, i+1);
+
+		sprintf(V1, "%d", (old_c_count-1-i) * 4);
+		"ld	[%l0+$V1], $S1";
+		cache[i].reg= S1;
+		cache[i].reg2= reg_g0;
+		cache[i].ext= 0;
+		cache[i].cst= 0;
+		if (!i)
+		{
+			sprintf(V1, "%d", (old_c_count)*4);
+			"add	$reg_sp, $V1, $reg_sp";
+		}
+	}
+	else
+	{
+		assert (i);
+		for (j= c_count-1; j>=0; j--)
+			cache[j+i]= cache[j];
+		c_count += i;
+		tos= &cache[c_count-1];
+		old_c_count = i;
+	}
+leave("cache_read");
+	return old_c_count;
+}
+
+static void dump_cache(stream)		/* to codefile! */
+File *stream;
+{
+	int i;
+
+	assert (c_count >= 0);
+	for (i = c_count -1; i >= 0; i--) {
+		if (cache[i].ext)
+			fprint(stream, "%s", cache[i].ext);
+		if (cache[i].reg != reg_g0) {
+			if (cache[i].ext)
+				fprint(stream, "+");
+			fprint(stream, "%s", cache[i].reg);
+			if (cache[i].reg2 != reg_g0) {
+				fprint(stream, "+");
+				fprint(stream, "%s", cache[i].reg2);
+			}
+		}
+		if (cache[i].cst || (!cache[i].ext && cache[i].reg == reg_g0)) {
+			if (cache[i].ext || cache[i].reg != reg_g0)
+				fprint(stream, "+");
+			fprint(stream, "%d", cache[i].cst);
+		}
+		fprint(stream, " ");
+	}
+	fprint(stream, "\n");
+if (debug) check_cache();
+}
+
+void dup_tos(n)
+int n;
+{
+	reg_t a;
+	int i;
+	const_str_t i_str;
+
+enter("dup_tos");
+	for (i = 0;i < n; i++) {
+		INC_TOS;
+		tos->reg = reg_g0;
+		tos->reg2 = reg_g0;
+		tos->cst = 0;
+		tos->ext = 0;
+		if (c_count > n) {
+			char *ext;
+
+			*tos = tos[-n];
+			if (tos->ext)
+			{
+				ext= malloc(strlen(tos->ext)+1);
+				strcpy(ext, tos->ext);
+				tos->ext= ext;
+			}
+			soft_alloc_reg(tos->reg);
+			soft_alloc_reg(tos->reg2);
+		} else {
+			a= alloc_reg();
+			sprintf(i_str, "%d", (n-c_count)*4);
+			"ld	[$reg_sp+$i_str], $a";
+			tos->reg = a;
+		}
+	}
+if (debug) { indent(); fprint(codefile, "\t\t! "); dump_cache(codefile); }
+leave("dup_tos");
+}

+ 7 - 0
mach/sparc/ce/ce.src/.distr

@@ -0,0 +1,7 @@
+C_con_scon.c
+C_cst.c
+C_mes_begin.c
+C_mes_end.c
+C_rom_scon.c
+misc.c
+ms_reg.c

+ 14 - 0
mach/sparc/ce/ce.src/C_con_scon.c

@@ -0,0 +1,14 @@
+#define CODE_EXPANDER
+#include <em.h>
+#include "mach.h"
+#include "back.h"
+
+C_con_scon( s, n)
+char *s;
+arith n;
+{
+	switchseg( SEGCON);
+	dump_label();	
+
+	con_str( s, n);
+}

+ 8 - 0
mach/sparc/ce/ce.src/C_cst.c

@@ -0,0 +1,8 @@
+#define CODE_EXPANDER
+#include <em.h>
+
+/* in ms_reg.c
+C_cst( l)
+arith l;
+{
+} */

+ 8 - 0
mach/sparc/ce/ce.src/C_mes_begin.c

@@ -0,0 +1,8 @@
+#define CODE_EXPANDER
+#include <em.h>
+
+/* in ms_reg.c
+C_mes_begin( ms)
+int ms;
+{
+} */

+ 7 - 0
mach/sparc/ce/ce.src/C_mes_end.c

@@ -0,0 +1,7 @@
+#define CODE_EXPANDER
+#include <em.h>
+
+/* in ms_reg.c
+C_mes_end()
+{
+} */

+ 14 - 0
mach/sparc/ce/ce.src/C_rom_scon.c

@@ -0,0 +1,14 @@
+#define CODE_EXPANDER
+#include <em.h>
+#include "mach.h"
+#include "back.h"
+
+C_rom_scon( s, n)
+char *s;
+arith n;
+{
+	switchseg( SEGROM);
+	dump_label();	
+
+	rom_str( s,n);
+}

+ 54 - 0
mach/sparc/ce/ce.src/misc.c

@@ -0,0 +1,54 @@
+/*
+misc.c
+*/
+
+#include "mach.h"
+
+int power_of_2(n, ref_exp)
+int n, *ref_exp;
+{
+	int exp;
+
+	exp= 0;
+	if (n<0)
+		n= -n;
+
+	if (!n)
+		return 0;
+
+	while (!(n % 2))
+	{
+		n= n/2;
+		exp++;
+	}
+	if (n != 1)
+		return 0;
+
+	if (ref_exp)
+		*ref_exp= exp;
+	return 1;
+}
+
+int uns_power_of_2(n, ref_exp)
+unsigned n, *ref_exp;
+{
+	int exp;
+
+	exp= 0;
+
+	if (!n)
+		return 0;
+
+	while (!(n % 2))
+	{
+		n= n/2;
+		exp++;
+	}
+	if (n != 1)
+		return 0;
+
+	if (ref_exp)
+		*ref_exp= exp;
+	return 1;
+}
+

+ 338 - 0
mach/sparc/ce/ce.src/ms_reg.c

@@ -0,0 +1,338 @@
+/* catch register messages. BEWARE: code uses plain printf's (fprint's)
+ * to generate code. This is not compatible with the usual procedure
+ * used in the EM_table
+ */
+
+#define CODE_EXPANDER
+#include <em.h>
+#include <em_reg.h>
+#include <em_mes.h>
+#include "push_pop.h"
+#include "mach.h"
+#include <stdio.h>
+
+#define MAX_NR_REGS 12
+#define MAX_NR_FLTS MAX_NR_FLT_REGS	/* depends on using float or doubles */
+
+#define RM_OFFSET 0
+#define RM_SIZE 1
+#define RM_TYPE 2
+#define RM_COUNT 3
+
+typedef struct reg_info {
+	int offset;
+	int size;	/* 4 or 8 */
+	int pri;
+	reg_t reg, reg2;	/* reg2 used for doubles only */
+} reg_info;
+
+reg_info reg_dat[MAX_NR_REGS], flt_dat[MAX_NR_FLTS];
+
+int current_reg_mes[RM_COUNT+4];
+
+int in_reg_mes = 0;	/* boolean */
+int reg_mes_nr;
+
+int worst_reg_pri, worst_flt_pri; /* reset by C_prolog (to some large number) */
+int nr_reg_vars, nr_flt_vars;		/* dito  (both to 0) */
+
+init_reg_man()
+{
+  worst_reg_pri = worst_flt_pri = (unsigned)-1/2;
+  nr_reg_vars = nr_flt_vars = 0;
+}
+
+reg_t my_alloc_reg(pri,loc)
+int pri, *loc;
+{
+	reg_t S1;
+	int i;
+
+	if ((S1 = alloc_reg_var()) == NULL)
+		if (current_reg_mes[RM_COUNT] > worst_reg_pri) {
+			for (i = 0; i < nr_reg_vars; i++)
+				if (reg_dat[i].pri <= worst_reg_pri) {
+					*loc = i;
+					S1 = reg_dat[i].reg;
+					break;
+				}
+			worst_reg_pri = (unsigned)-1/2;
+			for (i = 0; i < nr_reg_vars; i++)
+				if (reg_dat[i].pri <= worst_reg_pri)
+					worst_reg_pri = reg_dat[i].pri;
+		} else
+			return NULL;	/* SORRY, FULL HOUSE! */
+	else
+		*loc = nr_reg_vars++;
+
+	return S1;
+}
+
+reg_t my_alloc_double(pri,loc,r2)
+int pri, *loc;
+reg_t *r2;
+/* implementation note: my_alloc_double only reclaims other doubles
+ * when a better candidate is given. It never reclaims floats, even if
+ * the current double is a mich better candidate.
+ */
+{
+	reg_t S1;
+	int i;
+
+	if ((S1 = alloc_double_var(r2)) == NULL)
+		if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
+			for (i = 0; i < nr_flt_vars; i++)
+				if (flt_dat[i].pri <= worst_flt_pri &&
+						flt_dat[i].size == EM_DSIZE) {
+					*loc = i;
+					S1 = flt_dat[i].reg;
+					*r2 = flt_dat[i].reg2;
+					break;
+				}
+			worst_flt_pri = (unsigned)-1/2;
+			for (i = 0; i < nr_flt_vars; i++)
+				if (flt_dat[i].pri < worst_flt_pri)
+					worst_flt_pri = flt_dat[i].pri;
+		} else
+			return NULL;	/* SORRY, FULL HOUSE! */
+	else
+		*loc = nr_flt_vars++;
+
+	return S1;
+}
+
+reg_t my_alloc_float(pri,loc)
+int pri, *loc;
+/* just as for my_alloc_double, my_alloc_float never reclaims a double,
+ * even though this me be useful and easy. Sorry.
+ */
+{
+	reg_t S1;
+	int i;
+
+	if ((S1 = alloc_float_var()) == NULL)
+		if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
+			for (i = 0; i < nr_flt_vars; i++)
+				if (flt_dat[i].pri <= worst_flt_pri &&
+						flt_dat[i].size == EM_WSIZE) {
+					*loc = i;
+					S1 = flt_dat[i].reg;
+					break;
+				}
+			worst_flt_pri = (unsigned)-1/2;
+			for (i = 0; i < nr_flt_vars; i++)
+				if (flt_dat[i].pri <= worst_flt_pri)
+					worst_flt_pri = flt_dat[i].pri;
+		} else
+			return NULL;	/* SORRY, FULL HOUSE! */
+	else
+		*loc = nr_flt_vars++;
+
+	return S1;
+}
+
+free_all_reg_vars()
+{
+  int i;
+
+  for (i = 0; i < nr_reg_vars; i++)
+	free_reg(reg_dat[i].reg);
+  for (i = 0; i < nr_flt_vars; i++)
+	switch (flt_dat[i].size) {
+	case EM_WSIZE: free_reg(flt_dat[i].reg); break;
+	case EM_DSIZE: free_double_reg(flt_dat[i].reg); break;
+	}
+  check_cache();
+}
+
+alloc_all_reg_vars()
+{
+  int i;
+
+  for (i = 0; i < nr_reg_vars; i++)
+	forced_alloc_reg(reg_dat[i].reg);
+  for (i = 0; i < nr_flt_vars; i++)
+	switch (flt_dat[i].size) {
+	case EM_WSIZE: forced_alloc_reg(flt_dat[i].reg); break;
+	case EM_DSIZE:
+		forced_alloc_reg(flt_dat[i].reg);
+		forced_alloc_reg(flt_dat[i].reg2);
+		break;
+	}
+  check_cache();
+}
+
+params_to_regs()		/* copy required parameters to registers */
+{
+  int i, j;
+
+  for (i = 0; i < nr_reg_vars; i++)
+	if (reg_dat[i].offset > 0)
+		fprint(codefile, "ld	[%%l1+%d], %s\n",
+			reg_dat[i].offset, reg_dat[i].reg);
+
+  for (i = 0; i < nr_flt_vars; i++)
+	if (flt_dat[i].offset > 0)
+	{
+		fprint(codefile, "ld	[%%l1+%d], %s\n",
+		  flt_dat[i].offset, flt_dat[i].reg);
+		if (flt_dat[i].size == EM_DSIZE)
+			fprint(codefile, "ld	[%%l1+%d], %s\n",
+			  flt_dat[i].offset + 4, flt_dat[i].reg2);
+	}
+}
+
+cmp_flt_dat(e1, e2)
+reg_info *e1, *e2;
+{
+  return (e1->offset - e2->offset);
+}
+
+save_float_regs()
+{
+  int i;
+  int offset;
+
+  qsort(flt_dat, nr_flt_vars, sizeof(flt_dat[0]), cmp_flt_dat);
+  for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
+	if ((i+1 < nr_flt_vars &&
+		flt_dat[i].offset == flt_dat[i+1].offset-4 &&
+		flt_dat[i].size == EM_FSIZE &&
+		flt_dat[i+1].size == EM_FSIZE)
+		|| (flt_dat[i].size == EM_DSIZE)) {
+		fprint(codefile, "std	%s, [%%fp + %d]\n",
+				flt_dat[i].reg, FLTSAV_OFFSET + offset);
+		if (flt_dat[i].size != EM_DSIZE)
+			++i;
+	} else
+		fprint(codefile, "st	%s, [%%fp + %d]\n",
+				flt_dat[i].reg, FLTSAV_OFFSET + offset);
+}
+
+load_float_regs()
+{
+  int i;
+  int offset;
+
+  for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
+	if ((i+1 < nr_flt_vars &&
+		flt_dat[i].offset == flt_dat[i+1].offset-4 &&
+		flt_dat[i].size == EM_FSIZE &&
+		flt_dat[i+1].size == EM_FSIZE)
+		|| (flt_dat[i].size == EM_DSIZE)) {
+		fprint(codefile, "ldd	[%%fp + %d], %s\n",
+				FLTSAV_OFFSET + offset, flt_dat[i].reg);
+		if (flt_dat[i].size != EM_DSIZE)
+			++i;
+	} else
+		fprint(codefile, "ld	[%%fp + %d], %s\n",
+				FLTSAV_OFFSET + offset, flt_dat[i].reg);
+
+}
+
+C_mes_begin( ms)
+int ms;
+{
+	reg_mes_nr = 0;
+	in_reg_mes = (ms == ms_reg);
+	if (ms == ms_gto)
+		fprint(codefile, "ta	3\n");
+}
+
+C_mes_end()
+{
+	int pos;
+	reg_t S1, S2;
+
+	if (!in_reg_mes)	/* end of some other mes */
+		return;
+	if (reg_mes_nr == 0) {	/* end of reg_mes's */
+		save_float_regs();
+		params_to_regs();
+		if (debug)
+			dump_reg_tabs(codefile);
+		return;
+	}
+	if (current_reg_mes[RM_COUNT] == 0)	/* never used, so ignore */
+		return;
+	if (current_reg_mes[RM_OFFSET] >= 0)
+		current_reg_mes[RM_OFFSET] += EM_BSIZE;
+	if (debug)
+		fprint(codefile, "\t\t! Got reg_mes: %d %d %d %d\n",
+			current_reg_mes[0], current_reg_mes[1],
+		current_reg_mes[2], current_reg_mes[3]);
+	if (current_reg_mes[RM_TYPE] == reg_float) {
+		switch(current_reg_mes[RM_SIZE]) {
+		case EM_WSIZE :
+			if ((S1 = my_alloc_float(current_reg_mes[RM_COUNT], &pos))
+									== NULL)
+				return;
+			break;
+		case EM_DSIZE:
+			if ((S1 = my_alloc_double(current_reg_mes[RM_COUNT], &pos, &S2))
+									== NULL)
+				return;
+			flt_dat[pos].reg2 = S2;
+		default: break;
+		}
+		flt_dat[pos].offset = current_reg_mes[RM_OFFSET];
+		flt_dat[pos].size = current_reg_mes[RM_SIZE];
+		flt_dat[pos].pri = current_reg_mes[RM_COUNT];
+		flt_dat[pos].reg = S1;
+	} else {
+		if (current_reg_mes[RM_SIZE] != EM_WSIZE)
+			return;		/* IGNORE THESE */
+		if ((S1 = my_alloc_reg(current_reg_mes[RM_COUNT], &pos)) == NULL)
+			return;		/* SORRY, FULL HOUSE! */
+
+		reg_dat[pos].offset = current_reg_mes[RM_OFFSET];
+		reg_dat[pos].size = current_reg_mes[RM_SIZE];
+		reg_dat[pos].pri = current_reg_mes[RM_COUNT];
+		reg_dat[pos].reg = S1;
+	}
+}
+
+C_cst( l)
+arith l;
+{
+	if (in_reg_mes)
+		current_reg_mes[reg_mes_nr++] = l;
+}
+
+dump_reg_tabs(stream)
+FILE *stream;
+{
+  int i;
+
+  fprint(stream, "!offset\tsize\tname (%d regvars)\n", nr_reg_vars);
+  for (i = 0; i < nr_reg_vars; i++)
+	fprint(stream, "! %d\t%d\t%s\n", reg_dat[i].offset, reg_dat[i].size,
+			reg_dat[i].reg);
+
+  fprint(stream, "!offset\tsize\tname (%d fltvars)\n", nr_flt_vars);
+  for (i = 0; i < nr_flt_vars; i++)
+	fprint(stream, "! %d\t%d\t%s\n", flt_dat[i].offset, flt_dat[i].size,
+			flt_dat[i].reg);
+}
+
+reg_t find_local(offset, reg2)	/* WARNING: no size checking here! */
+int offset;
+reg_t *reg2;
+{
+  int i;
+
+  if (reg2)
+	*reg2 = NULL;
+  for (i = 0; i < nr_reg_vars; i++)
+	if (reg_dat[i].offset == offset)
+		return reg_dat[i].reg;
+
+  for (i = 0; i < nr_flt_vars; i++)
+	if (flt_dat[i].offset == offset) {
+		if (flt_dat[i].size == EM_DSIZE)
+			if (reg2)
+				*reg2 = flt_dat[i].reg2;
+		return flt_dat[i].reg;
+	}
+  return NULL;
+}

+ 30 - 0
mach/sparc/ce/cegpp

@@ -0,0 +1,30 @@
+# dit sed script zet regels van het type "sll $a, $$, $44" om in
+# fprint(codefile, "sll %s, $, $44\n", a);
+# en meer....
+# Usage: sed -f $0 < EM_table.x > EM_table
+# remember to include special thingies in  "mach.h"
+#n
+s/==>/&\
+code_combiner(/
+s/\.[ 	]*$/)\
+&/
+/^[ 	]*"/{
+s/%/%%/g
+i\
+fprint ( codefile,
+s/\$\$/__NEVER_USED__/g
+s/\$\([0-9][0-9]*\)/__NEVER_USED__\1/g
+s/\$\$/%a/g
+:a
+s/\([^\$]*\)\$\([^\$][A-Za-z0-9_]*\)\(.*\)/\1%s\3\
+\2/
+t a
+s/\n/,/g
+s/__NEVER_USED__/$/g
+s/";/"/
+s/\([^"]*"[^"]*\)"\(.*\)/\1\\n"\2/
+p
+i\
+);
+D
+}

+ 35 - 0
mach/sparc/ce/mach.c

@@ -0,0 +1,35 @@
+#define CODE_EXPANDER
+#include "mach.h"
+#include <back.h>
+#include <system.h>
+
+
+#ifdef DEBUG
+arg_error( s, arg)
+char *s;
+int arg;
+{
+	fprint( STDERR, "arg_error %s %d\n", s, arg);
+}
+#endif
+
+
+/*
+do_open( filename)
+char *filename;
+{
+	if ( filename == (char *)0 || !sys_open( filename, OP_WRITE, &codefile))
+		return( 0);
+
+	fprint( codefile, ".sect .text; .sect .rom; .sect .data; .sect .bss\n");
+	return( 1);
+}
+*/
+
+#define IEEEFLOAT
+#define FL_MSL_AT_LOW_ADDRESS	1
+#define FL_MSW_AT_LOW_ADDRESS	1
+#define FL_MSB_AT_LOW_ADDRESS	1
+#include <con_float>
+
+#include <cache.c>

+ 20 - 0
mach/sparc/ce/mach.h

@@ -0,0 +1,20 @@
+/*
+mach.h
+*/
+
+#ifndef MACH_H
+#define MACH_H
+
+#include "ctype.h"
+#include "mach_em.h"
+#include "push_pop.h"
+#include "ms_reg.h"
+#include "misc.h"
+
+#if RESOLV_debug
+	#define debug 0
+#else
+	extern int debug;
+#endif
+
+#endif /* MACH_H */

+ 59 - 0
mach/sparc/ce/mach_em.h

@@ -0,0 +1,59 @@
+#define DEBUG 1
+#include <sun4/asm_linkage.h>
+
+#define BYTES_REVERSED
+#define WORDS_REVERSED
+
+#define ONE_BYTE        int
+#define TWO_BYTES	int
+#define FOUR_BYTES	long
+
+#define EM_WSIZE	4
+#define EM_PSIZE	4
+#define EM_FSIZE	4
+#define EM_DSIZE	8
+#define EM_BSIZE	REGSAV
+
+#define	BSS_INIT	0
+
+#define NAME_FMT	"_%s"
+#define DNAM_FMT	"_%s"
+#define DLB_FMT		"L_%ld"
+#define	ILB_FMT		"L%x_%lx"
+#define HOL_FMT		"hol%d"
+#define STR_FMT		".ascii\t"
+
+#define GENLAB		'L'
+
+#define	ALIGN_FMT		".align 4\n"
+
+#define	BYTE_FMT		".byte %ld\n"
+#define	WORD_FMT		".half %ld\n"
+#define	LONG_FMT  		".word %ld\n"
+#define	BSS_FMT			".skip %ld\n"
+
+#define	SEGTXT_FMT  		".seg \"text\"\n"
+#define	SEGDAT_FMT		".seg \"data\"\n"
+#define	SEGBSS_FMT		".seg \"bss\"\n"
+
+#define	SYMBOL_DEF_FMT		"%s:\n"
+#define	GLOBAL_FMT		".global %s\n"
+#define COMM_FMT		".reserve %s, %ld, \"bss\"\n"
+#define	LOCAL_FMT		""
+
+#define	RELOC1_FMT		"ONLY LONGS CAN BE RELOCATED!"
+#define	RELOC2_FMT		"ONLY LONGS CAN BE RELOCATED!"
+#define	RELOC4_FMT		".seg \"data\"\n.align 4\n.word %s+%d\n"
+
+#define ALIGN_GAP	4
+#define FLOATTRANS	8
+#define MAX_NR_FLT_REGS	16
+#define FLTSAV		(MAX_NR_FLT_REGS * 4)
+#define FLTSAV_OFFSET	(WINDOWSIZE + FLOATTRANS)
+#define REGSAV		(WINDOWSIZE + FLOATTRANS + ALIGN_GAP + FLTSAV)
+
+#define MATH_DIVIDE	1
+
+#ifndef DEBUG
+#define arg_error(s,i)
+#endif

+ 11 - 0
mach/sparc/ce/misc.h

@@ -0,0 +1,11 @@
+/*
+misc.h
+*/
+
+#ifndef MISC_H
+#define MISC_H
+
+_PROTOTYPE( int power_of_2, (int n, int *ref_exp));
+
+#endif /* MISC_H */
+

+ 10 - 0
mach/sparc/ce/ms_reg.h

@@ -0,0 +1,10 @@
+/* ms_reg.h */
+
+#ifndef MS_REG_H
+#define MS_REG_H
+
+#include "push_pop.h"
+
+_PROTOTYPE(reg_t find_local, (int, reg_t*));
+
+#endif

+ 37 - 0
mach/sparc/ce/proto.make

@@ -0,0 +1,37 @@
+# $Header$
+
+#PARAMS		do not remove this line!
+
+MACH = sparc
+OBJ = as
+SRC_DIR = $(SRC_HOME)/mach/$(MACH)/ce
+
+CEG = $(TARGET_HOME)/lib.bin/ceg/util
+
+all:
+	( cd $(SRC_DIR); make )
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH)
+
+install:
+	( cd $(SRC_DIR); make )
+	-mkdir $(TARGET_HOME)/lib.bin/sparc
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) install
+
+cmp:
+	( cd $(SRC_DIR); make )
+	-make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) cmp
+
+pr:
+	@pr $(SRC_DIR)/proto.make $(SRC_DIR)/EM_table.x $(SRC_DIR)/mach.h \
+	    $(SRC_DIR)/mach.c $(SRC_DIR)/cache.c.x
+
+opr:
+	make pr | opr
+
+# total cleanup
+clean:
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) clean
+
+# only remove ce, ceg, and back directories
+dclean:
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) dclean

+ 89 - 0
mach/sparc/ce/push_pop.h

@@ -0,0 +1,89 @@
+/*
+push_pop.h
+*/
+
+#ifndef PUSH_POP_H
+#define PUSH_POP_H
+
+#include "back.h"
+
+#define NR_REGS 64
+
+typedef char *reg_t;
+
+typedef struct cache_elt {
+	reg_t	reg, reg2;
+	char	*ext;
+	arith	cst;
+} cache_elt;
+
+#define REG_NUM(r) (((char(*)[8])(r))-regnam)
+
+#define T_cst	1
+#define T_ext	2
+#define T_reg	4
+#define T_float	8
+#define T_reg2	16
+#define T_float2 32
+
+typedef char const_str_t[NR_REGS];
+
+extern reg_t reg_g0, reg_g1, reg_g2, reg_g3, reg_g4, reg_g5, reg_g6, reg_g7;
+extern reg_t reg_i0, reg_i1, reg_i2, reg_i3, reg_i4, reg_i5, reg_i6, reg_i7;
+extern reg_t reg_l0, reg_l1, reg_l2, reg_l3, reg_l4, reg_l5, reg_l6, reg_l7;
+extern reg_t reg_o0, reg_o1, reg_o2, reg_o3, reg_o4, reg_o5, reg_o6, reg_o7;
+extern reg_t reg_f0;
+extern reg_t reg_sp, reg_lb, reg_gap;
+extern reg_t reg_tmp;
+
+#ifdef __STDC__
+#define _PROTOTYPE(x,y) x y
+#else
+#define _PROTOTYPE(x,y) x()
+#endif
+
+_PROTOTYPE(int const13, (int));
+_PROTOTYPE(void init_cache, (void));
+_PROTOTYPE(void free_reg, (reg_t));
+_PROTOTYPE(void free_double, (reg_t));	/* ..._reg */
+_PROTOTYPE(void forced_alloc_reg, (reg_t));
+_PROTOTYPE(void soft_alloc_reg, (reg_t));
+_PROTOTYPE(void change_reg, (reg_t));
+_PROTOTYPE(int type_of_tos, (void));
+_PROTOTYPE(void inc_tos, (arith));
+_PROTOTYPE(void inc_tos_reg, (reg_t));
+_PROTOTYPE(void push_const, (arith));
+_PROTOTYPE(void push_reg, (reg_t));
+_PROTOTYPE(void push_ext, (char *));
+_PROTOTYPE(void flush_cache, (void));
+static _PROTOTYPE(void flush_part_cache, (int c, int r, int f, int d));
+static _PROTOTYPE(void subst_reg, (reg_t, reg_t));
+_PROTOTYPE(void cache_need, (int));
+static _PROTOTYPE(int cache_read, (int n, int i));
+static _PROTOTYPE(void dump_cache, (File *stream));
+_PROTOTYPE(void pop_nop, (int));
+static _PROTOTYPE(void panic, (char*));
+
+_PROTOTYPE(reg_t alloc_reg, (void));
+_PROTOTYPE(reg_t alloc_reg_var, (void));
+_PROTOTYPE(reg_t alloc_float, (void));
+_PROTOTYPE(reg_t alloc_float_var, (void));
+_PROTOTYPE(reg_t alloc_double, (reg_t *sub_reg));
+_PROTOTYPE(reg_t alloc_double_var, (reg_t *sub_reg));
+_PROTOTYPE(reg_t pop_reg, (void));
+_PROTOTYPE(reg_t pop_reg_c13, (char*));
+_PROTOTYPE(reg_t pop_reg_reg, (reg_t*));
+_PROTOTYPE(reg_t pop_float, (void));
+_PROTOTYPE(reg_t pop_double, (reg_t *sub_reg));
+_PROTOTYPE(void pop_reg_as, (reg_t r));
+static _PROTOTYPE(reg_t top_reg, (void));
+static _PROTOTYPE(reg_t top_reg_c13, (char*));
+
+_PROTOTYPE(arith pop_const, (char *n_str));
+_PROTOTYPE(arith top_const, (void));
+_PROTOTYPE(void dup_tos, (int n));
+_PROTOTYPE(void exg_top, (int n));
+
+#define code_combiner(x) x
+
+#endif /* PUSH_POP_H */

+ 5 - 0
mach/sparc/libsys/.distr

@@ -0,0 +1,5 @@
+LIST
+libmon_s.a
+head_em.s
+SYS.h
+syscall.h

+ 180 - 0
mach/sparc/libsys/LIST

@@ -0,0 +1,180 @@
+libmon_s.a
+_alarm.c
+_brk.s
+_close.s
+_creat.s
+_dup.s
+_dup2.s
+_execl.c
+_execve.s
+_exit.s
+_fork.s
+_fstat.s
+_ftime.c
+_getpid.s
+_getrusage.s
+_gettimday.s
+_gtty.c
+_ioctl.s
+_kill.s
+_link.s
+_lseek.s
+_open.s
+_pause.c
+_pipe.s
+_read.s
+_setitimer.s
+_sigblock.s
+_sigpause.s
+_sigsetmask.s
+_sigvec.c
+_sigvecscall.s
+_times.c
+_unlink.s
+_wait4.s
+_write.s
+accept.s
+access.s
+acct.s
+adjtime.s
+alarm.c
+bind.s
+brk.s
+cerror.s
+chdir.s
+chmod.s
+chown.s
+chroot.s
+cleanup.c
+close.s
+connect.s
+creat.s
+dup.s
+dup2.s
+execl.c
+execle.c
+execv.c
+execve.s
+exit.c
+fchdir.s
+fchmod.s
+fchown.s
+fchroot.s
+fcntl.s
+fif.s
+flock.s
+fork.s
+fstat.s
+fstatfs.s
+fsync.s
+ftime.c
+ftruncate.s
+getdents.s
+getdirent.s
+getdomnam.s
+getdtabsiz.s
+getegid.s
+geteuid.s
+getgid.s
+getgroups.s
+gethostname.s
+getitimer.s
+getmsg.s
+getpeername.s
+getpgrp.s
+getpid.s
+getpriority.s
+getrlimit.s
+getrusage.s
+getsockname.s
+getsockopt.s
+gettimeofday.s
+getuid.s
+gtty.c
+ioctl.s
+kill.s
+killpg.s
+link.s
+listen.s
+lockf.c
+lseek.s
+lstat.s
+mincore.s
+mkdir.s
+mknod.s
+mmap.s
+mount.s
+mprotect.s
+msync.s
+munmap.s
+nfssvc.s
+nice.c
+open.s
+pause.c
+pipe.s
+plock.c
+poll.s
+profil.s
+ptrace.s
+putmsg.s
+quotactl.s
+read.s
+readlink.s
+readv.s
+reboot.s
+recv.s
+recvfrom.s
+recvmsg.s
+rename.s
+rmdir.s
+sbrk.s
+select.s
+send.s
+sendmsg.s
+sendto.s
+setdomnam.s
+setgid.c
+setgroups.s
+sethostname.s
+setitimer.s
+setpgrp.s
+setpriority.s
+setregid.s
+setreuid.s
+setrlimit.s
+setsockopt.s
+settimeofday.s
+setuid.c
+shutdown.s
+sigblock.s
+signal.c
+sigpause.s
+sigsetmask.s
+sigstack.s
+sigtramp.s
+sigvec.c
+sigvec_scall.s
+socket.s
+socketpair.s
+stat.s
+statfs.s
+stime.c
+stty.c
+swapon.s
+symlink.s
+tell.c
+time.c
+times.c
+truncate.s
+ulimit.c
+umask.s
+uname.c
+unlink.s
+unmount.s
+utime.c
+utimes.s
+vadvise.s
+vfork.s
+wait4.s
+write.s
+writev.s

+ 147 - 0
mach/sparc/libsys/SYS.h

@@ -0,0 +1,147 @@
+/*
+SYS.h
+*/
+
+#ifndef SYS_H
+#define SYS_H
+
+#include <syscall.h>
+
+#define SYS_call_0(x) \
+	LABEL_(x); \
+	BODY(x)
+
+#define _SYS_call_0(x) \
+	LABEL__(x); \
+	LABEL(x); \
+	BODY(x)
+
+#define SYS_call_1(x) \
+	LABEL_(x); \
+	ENTRY1; \
+	BODY(x)
+
+#define _SYS_call_1(x) \
+	LABEL__(x); \
+	ENTRY1; \
+	LABEL(x); \
+	BODY(x)
+
+#define SYS_call_2(x) \
+	LABEL_(x); \
+	ENTRY2; \
+	BODY(x)
+
+#define _SYS_call_2(x) \
+	LABEL__(x); \
+	ENTRY2; \
+	LABEL(x); \
+	BODY(x)
+
+#define SYS_call_3(x) \
+	LABEL_(x); \
+	ENTRY3; \
+	BODY(x)
+
+#define _SYS_call_3(x) \
+	LABEL__(x); \
+	ENTRY3; \
+	LABEL(x); \
+	BODY(x)
+
+#define SYS_call_4(x) \
+	LABEL_(x); \
+	ENTRY4; \
+	BODY(x)
+
+#define _SYS_call_4(x) \
+	LABEL__(x); \
+	ENTRY4; \
+	LABEL(x); \
+	BODY(x)
+
+#define SYS_call_5(x) \
+	LABEL_(x); \
+	ENTRY5; \
+	BODY(x)
+
+#define _SYS_call_5(x) \
+	LABEL__(x); \
+	ENTRY5; \
+	LABEL(x); \
+	BODY(x)
+
+#define SYS_call_6(x) \
+	LABEL_(x); \
+	ENTRY6; \
+	BODY(x)
+
+#define _SYS_call_6(x) \
+	LABEL__(x); \
+	ENTRY6; \
+	LABEL(x); \
+	BODY(x)
+
+#define BODY(x) \
+	sys_call(x); \
+	ta	%g0; \
+	bgeu 0f; \
+	sethi   %hi(cerror), %o5; \
+	or      %o5, %lo(cerror), %o5; \
+	jmp	%o5; \
+	nop; \
+0:; \
+	retl; \
+	nop
+
+#if __STDC__
+#define LABEL_(x) \
+	.global _ ## x; \
+	_ ## x:
+#define LABEL__(x) \
+	.global __ ## x; \
+	__ ## x:
+#else
+#define LABEL_(x) \
+	.global _/**/x; \
+	_/**/x:
+#define LABEL__(x) \
+	.global __/**/x; \
+	__/**/x:
+#endif
+#define LABEL(x) \
+	.global x; \
+	x:
+
+#define ENTRY1 \
+	ld	[%l0], %o0 \
+
+#define ENTRY2 \
+	ENTRY1; \
+	ld	[%l0+4], %o1 \
+
+#define ENTRY3 \
+	ENTRY2; \
+	ld	[%l0+8], %o2 \
+
+#define ENTRY4 \
+	ENTRY3; \
+	ld	[%l0+12], %o3 \
+
+#define ENTRY5 \
+	ENTRY4; \
+	ld	[%l0+16], %o4 \
+
+#define ENTRY6 \
+	ENTRY5; \
+	ld	[%l0+20], %o5 \
+
+#if __STDC__
+#define sys_call(x) \
+	mov	SYS_ ## x, %g1
+#else
+#define sys_call(x) \
+	mov	SYS_/**/x, %g1
+#endif
+
+#endif /* SYS_H */

+ 13 - 0
mach/sparc/libsys/_alarm.c

@@ -0,0 +1,13 @@
+unsigned
+_alarm(n)
+	unsigned n;
+{
+	struct { long l1,l2,l3,l4; } t1,t2;
+	t1.l1 = 0;
+	t1.l2 = 0;
+	t1.l4 = 0;
+	t1.l3 = n;
+	if (_setitimer(0,&t1,&t2) < 0) return -1;
+	if (t2.l4) t2.l3++;
+	return t2.l3;
+}

+ 46 - 0
mach/sparc/libsys/_brk.s

@@ -0,0 +1,46 @@
+.global cerror, __brk, __sbrk, limhp, brk, sbrk
+
+__brk:	
+	ld	[%l0], %o0
+brk:	inc	7, %o0
+	andn	%o0, 7, %o0
+	mov     %o0, %o2
+	mov     0x11, %g1
+	ta	%g0
+	nop
+	bgeu	0f
+	nop
+	set	cerror, %o5
+	jmp	%o5
+	nop
+0:
+	set	limhp, %g1
+	st	%o2, [%g1]
+	retl
+	nop
+
+
+__sbrk:	
+	ld	[%l0], %o0
+sbrk:	inc	7, %o0
+	andn	%o0, 7, %o0
+	set	limhp, %o1
+	ld	[%o1], %o2
+	inc	7, %o2
+	andn	%o2, 7, %o3
+	add	%o3, %o0, %o0
+	mov	%o0, %o4
+	mov     0x11, %g1
+	ta	%g0
+	nop
+	bgeu	0f
+	nop
+	set	cerror, %o5
+	jmp	%o5
+	nop
+0:
+	set	limhp, %g1
+	st	%o4, [%g1]
+	mov	%o3, %o0
+	retl
+	nop

+ 3 - 0
mach/sparc/libsys/_close.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_1(close)

+ 3 - 0
mach/sparc/libsys/_creat.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(creat)

+ 3 - 0
mach/sparc/libsys/_dup.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_1(dup)

+ 3 - 0
mach/sparc/libsys/_dup2.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(dup2)

+ 8 - 0
mach/sparc/libsys/_execl.c

@@ -0,0 +1,8 @@
+_execl(name,args)
+	char *name;
+	int args;
+{
+	extern char **environ;
+
+	_execve(name,&args,environ);
+}

+ 3 - 0
mach/sparc/libsys/_execve.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(execve)

+ 7 - 0
mach/sparc/libsys/_exit.s

@@ -0,0 +1,7 @@
+#include "SYS.h"
+
+.global __exit
+__exit:
+	ld	[%l0], %o0
+	set	SYS_exit, %g1
+	ta	%g0

+ 3 - 0
mach/sparc/libsys/_fork.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_0(fork)

+ 3 - 0
mach/sparc/libsys/_fstat.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(fstat)

+ 15 - 0
mach/sparc/libsys/_ftime.c

@@ -0,0 +1,15 @@
+#include <sys/types.h>
+
+_ftime(p)
+	struct { time_t time; unsigned short millitm;
+		 short timezone; short dstflag; } *p;
+{
+	struct { long l1,l2; } t1,t2;
+
+	if (_gettimeofday(&t1,&t2) < 0) return -1;
+	p->time = t1.l1;
+	p->millitm = t1.l2/1000;
+	p->dstflag = t2.l2;
+	p->timezone = t2.l1;
+	return 0;
+}

+ 3 - 0
mach/sparc/libsys/_getpid.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_0(getpid)

+ 3 - 0
mach/sparc/libsys/_getrusage.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(getrusage)

+ 3 - 0
mach/sparc/libsys/_gettimday.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(gettimeofday)

+ 8 - 0
mach/sparc/libsys/_gtty.c

@@ -0,0 +1,8 @@
+#include <sgtty.h>
+int
+_gtty(fildes,argp)
+	int fildes ;
+	struct sgttyb *argp ;
+{
+	return _ioctl(fildes,TIOCGETP,argp) ;
+}

+ 3 - 0
mach/sparc/libsys/_ioctl.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(ioctl)

+ 3 - 0
mach/sparc/libsys/_kill.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(kill)

+ 3 - 0
mach/sparc/libsys/_link.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_2(link)

+ 3 - 0
mach/sparc/libsys/_lseek.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(lseek)

+ 3 - 0
mach/sparc/libsys/_open.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(open)

+ 3 - 0
mach/sparc/libsys/_pause.c

@@ -0,0 +1,3 @@
+_pause() {
+	_sigpause(_sigblock());
+}

+ 3 - 0
mach/sparc/libsys/_pipe.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_1(pipe)

+ 3 - 0
mach/sparc/libsys/_read.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(read)

+ 4 - 0
mach/sparc/libsys/_setitimer.s

@@ -0,0 +1,4 @@
+#include "SYS.h"
+
+_SYS_call_3(setitimer)
+

+ 3 - 0
mach/sparc/libsys/_sigblock.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(sigblock)

+ 3 - 0
mach/sparc/libsys/_sigpause.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_1(sigpause)

+ 3 - 0
mach/sparc/libsys/_sigsetmask.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_1(sigsetmask)

+ 36 - 0
mach/sparc/libsys/_sigvec.c

@@ -0,0 +1,36 @@
+#include "syscall.h"
+#include <errno.h>
+struct sigvec { int (*handler)(); int mask,flags; };
+int (*(_sigfunc[32]))();
+extern int _sigtramp();
+extern int errno;
+
+sigvec(sig,vec,ovec)
+	register struct sigvec *vec;
+	struct sigvec *ovec;
+{
+	struct sigvec tmp;
+	int (*old)();
+
+	if ((unsigned) sig >= 32) {
+		errno = EINVAL;
+		return -1;
+	}
+	old = _sigfunc[sig];
+	if (vec) {
+		tmp = *vec;
+		vec = &tmp;
+		if (vec->handler && vec->handler != (int (*)()) 1) {
+			_sigfunc[sig] = vec->handler;
+			vec->handler = _sigtramp;
+		}
+	}
+	if (_sigvec_scall(sig,vec,ovec) < 0) {
+		_sigfunc[sig] = old;
+		return -1;
+	}
+	if (ovec && ovec->handler == _sigtramp) {
+		ovec->handler = old;
+	}
+	return 0;
+}

+ 5 - 0
mach/sparc/libsys/_sigvecscall.s

@@ -0,0 +1,5 @@
+#include "SYS.h"
+
+#define SYS_sigvec_scall SYS_sigvec
+
+_SYS_call_3(sigvec_scall)

+ 16 - 0
mach/sparc/libsys/_times.c

@@ -0,0 +1,16 @@
+#include <sys/types.h>
+
+#define Xval(xx)	((xx).l1*60+(xx).l2/(100000/6))
+
+_times(bp)
+	struct { time_t l1,l2,l3,l4;} *bp;
+{
+	struct { struct { long l1,l2; }s1,s2; long x[20]; } t;
+	if (_getrusage(0,&t) < 0) return -1;
+	bp->l1 = Xval(t.s1);
+	bp->l2 = Xval(t.s2);
+	if (_getrusage(-1,&t) < 0) return -1;
+	bp->l3 = Xval(t.s1);
+	bp->l4 = Xval(t.s2);
+	return 0;
+}

+ 3 - 0
mach/sparc/libsys/_unlink.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_1(unlink)

+ 19 - 0
mach/sparc/libsys/_wait4.s

@@ -0,0 +1,19 @@
+#include "SYS.h"
+
+.global __wait, __wait3
+
+__wait:
+	mov	0, %o0
+	ld	[%l0], %o1
+	mov	0, %o2
+	b	wait4
+	mov	0, %o3
+
+__wait3:
+	ld	[%l0+8], %o3
+	ld	[%l0+4], %o2
+	ld	[%l0], %o1
+	b	wait4
+	mov	0, %o0
+
+_SYS_call_4(wait4)

+ 3 - 0
mach/sparc/libsys/_write.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+_SYS_call_3(write)

+ 3 - 0
mach/sparc/libsys/accept.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_3(accept)

+ 4 - 0
mach/sparc/libsys/access.s

@@ -0,0 +1,4 @@
+#include "SYS.h"
+
+SYS_call_2(access)
+

+ 3 - 0
mach/sparc/libsys/acct.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(acct)

+ 3 - 0
mach/sparc/libsys/adjtime.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(adjtime)

+ 13 - 0
mach/sparc/libsys/alarm.c

@@ -0,0 +1,13 @@
+unsigned
+alarm(n)
+	unsigned n;
+{
+	struct { long l1,l2,l3,l4; } t1,t2;
+	t1.l1 = 0;
+	t1.l2 = 0;
+	t1.l4 = 0;
+	t1.l3 = n;
+	if (setitimer(0,&t1,&t2) < 0) return -1;
+	if (t2.l4) t2.l3++;
+	return t2.l3;
+}

+ 4 - 0
mach/sparc/libsys/bind.s

@@ -0,0 +1,4 @@
+#include "SYS.h"
+
+SYS_call_3(bind)
+

+ 6 - 0
mach/sparc/libsys/brk.s

@@ -0,0 +1,6 @@
+.global _brk, __brk
+
+_brk:	
+	set	__brk,%o7
+	jmp	%o7
+	nop

+ 14 - 0
mach/sparc/libsys/cerror.s

@@ -0,0 +1,14 @@
+.global _errno
+.global cerror
+
+cerror:
+	set	_errno, %o5
+	st	%o0, [%o5]
+	set	-1, %o0
+	retl
+	nop
+
+.seg	"data"
+_errno:
+	.long	0
+

+ 3 - 0
mach/sparc/libsys/chdir.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(chdir)

+ 3 - 0
mach/sparc/libsys/chmod.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(chmod)

+ 3 - 0
mach/sparc/libsys/chown.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_3(chown)

+ 3 - 0
mach/sparc/libsys/chroot.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(chroot)

+ 1 - 0
mach/sparc/libsys/cleanup.c

@@ -0,0 +1 @@
+_cleanup() { }

+ 3 - 0
mach/sparc/libsys/close.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(close)

+ 4 - 0
mach/sparc/libsys/connect.s

@@ -0,0 +1,4 @@
+#include "SYS.h"
+
+SYS_call_3(connect)
+

+ 3 - 0
mach/sparc/libsys/creat.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(creat)

+ 3 - 0
mach/sparc/libsys/dup.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(dup)

+ 3 - 0
mach/sparc/libsys/dup2.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(dup2)

+ 8 - 0
mach/sparc/libsys/execl.c

@@ -0,0 +1,8 @@
+execl(name,args)
+	char *name;
+	int args;
+{
+	extern char **environ;
+
+	execve(name,&args,environ);
+}

+ 9 - 0
mach/sparc/libsys/execle.c

@@ -0,0 +1,9 @@
+execle(name,args)
+	char *name;
+	char *args;
+{
+	char **p = &args;
+	while (*p++) ;
+
+	execve(name,&args,*p);
+}

+ 7 - 0
mach/sparc/libsys/execv.c

@@ -0,0 +1,7 @@
+execv(name,args)
+	char *name;
+	char **args;
+{
+	extern char **environ;
+	execve(name,args,environ);
+}

+ 3 - 0
mach/sparc/libsys/execve.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_3(execve)

+ 5 - 0
mach/sparc/libsys/exit.c

@@ -0,0 +1,5 @@
+exit(n)
+{
+	_cleanup();
+	_exit(n);
+}

+ 3 - 0
mach/sparc/libsys/fchdir.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(fchdir)

+ 3 - 0
mach/sparc/libsys/fchmod.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(fchmod)

+ 3 - 0
mach/sparc/libsys/fchown.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_3(fchown)

+ 3 - 0
mach/sparc/libsys/fchroot.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_1(fchroot)

+ 4 - 0
mach/sparc/libsys/fcntl.s

@@ -0,0 +1,4 @@
+#include "SYS.h"
+
+SYS_call_3(fcntl)
+

+ 67 - 0
mach/sparc/libsys/fif.s

@@ -0,0 +1,67 @@
+.global fif8, Fd0, Fd1, Fd80000000, Fs80000000, Fs0
+
+.align 8
+Fd0:
+.double 0r0
+Fd1:
+.double 0r1
+FxE15:
+.word 0x43300000, 0x0	! magic const: (a.b + x) - x == a.0
+Fd80000000:
+.align 8
+.double 0r4294967296
+Fs80000000:
+.single 0r2147483648
+Fs0:
+.single 0r0
+
+fif8:
+	ld	[%l0], %f0
+	ld	[%l0+4], %f1
+	ld	[%l0+8], %f2
+	ld	[%l0+12], %f3
+	fmuld	%f0, %f2, %f0
+	fmovs	%f0, %f6
+	fmovs	%f1, %f7
+	set	Fd0, %o0
+	ldd	[%o0], %f8
+	fcmpd	%f0, %f8
+	nop
+	fbuge,a	1f
+	mov	%g0, %o1
+	set	1, %o1
+	fnegs	%f0, %f0
+1:
+	set	FxE15, %o0
+	ldd	[%o0], %f10
+	fcmpd	%f0, %f10
+	nop
+	fbuge	2f
+	nop
+	faddd	%f0, %f10, %f4
+	fsubd	%f4, %f10, %f4
+	fsubd	%f0, %f4, %f2
+	set	Fd1, %o0
+	ldd	[%o0], %f12
+4:	fcmpd	%f2, %f12
+	nop
+	fbge,a	4b
+	fsubd	%f2, %f12, %f2
+5:	fcmpd	%f2, %f8
+	nop
+	fbl,a	5b
+	faddd	%f2, %f12, %f2
+	fsubd	%f0, %f2, %f0
+2:
+	tst	%o1
+	bz	3f
+	nop
+	fnegs	%f0, %f0
+3:
+	fsubd	%f6, %f0, %f2
+	st	%f0, [%l0]
+	st	%f1, [%l0+4]
+	st	%f2, [%l0+8]
+	st	%f3, [%l0+12]
+	retl
+	nop

+ 3 - 0
mach/sparc/libsys/flock.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(flock)

+ 3 - 0
mach/sparc/libsys/fork.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_0(fork)

+ 3 - 0
mach/sparc/libsys/fstat.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(fstat)

+ 3 - 0
mach/sparc/libsys/fstatfs.s

@@ -0,0 +1,3 @@
+#include "SYS.h"
+
+SYS_call_2(fstatfs)

Some files were not shown because too many files changed in this diff