Browse Source

Initial revision

ceriel 36 years ago
parent
commit
6ae90c8f34

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

@@ -0,0 +1,15 @@
+EM_table
+Make.back
+Makefile
+as.c
+as.h
+as_table
+do_close.c
+do_open.c
+end_back.c
+lib
+mach.c
+mach.h
+misc.c
+output.c
+relocation.c

+ 805 - 0
mach/sun3/ce/EM_table

@@ -0,0 +1,805 @@
+#define small(x) ((x)>=1 && (x)<=8)
+
+/******************************************************************************/
+/*                                                                            */
+/*			Group 1 : Load instructions			      */
+/*							 		      */
+/******************************************************************************/
+
+/*	a6 : local base.
+ *	sp : stack pointer
+ */
+
+C_loc		==>	"pea ($1)".
+
+C_lol		==> 	"move.l ($1, a6), -(sp)". 
+
+C_loe..		==> 	"move.l ($1+$2), -(sp)".
+
+C_lil		==> 	"move.l ([$1,a6]), -(sp)".
+
+C_lof		==> 	"move.l (sp)+, a0";
+			"move.l ($1,a0), -(sp)".
+
+C_lal		==> 	"pea ($1,a6)".
+	
+C_lae..		==> 	"pea ($1+$2)".
+
+C_lxl		
+  	$1 == 0		==>	"move.l a6, -(sp)".
+  	$1 == 1		==>	"move.l (8, a6), -(sp)".
+  	default		==>	"move.l (8, a6), a0";
+				"move.l #$1-2, d0";
+				"1: move.l (8,a0), a0";
+				"dbf d0, 1b";
+				"move.l a0, -(sp)".
+
+C_lxa
+  	$1 == 0 	==>	"pea (8,a6)".
+  	$1 == 1 	==>	"pea ([8,a6],8)".
+  	default		==>	"move.l (8, a6), a0";
+				"move.l #$1-2, d0";
+				"1: move.l (8,a0), a0";
+				"dbf d0, 1b";
+				"pea (8,a0)".
+
+C_loi		
+  	$1 == 1		==>	"move.l (sp)+, a0";
+				"clr.l -(sp)";
+				"move.b (a0), (3,sp)".
+  	$1 == 2		==>	"move.l (sp)+, a0";
+				"clr.l -(sp)";
+				"move.w (a0), (2,sp)".
+  	$1 == 4		==>	"move.l (sp)+, a0";
+				"move.l (a0), -(sp)".
+	$1 == 8         ==>     "move.l (sp)+, a0";
+				"move.l (4,a0), -(sp)";
+				"move.l (a0), -(sp)".
+  	$1 % 4 == 0	==>	"move.l (sp)+, a0";
+				"move.l #$1/4-1, d0";
+				"add.l #$1, a0";	
+				"1:";
+				"move.l -(a0), -(sp)";
+				"dbf d0, 1b".
+	default		==> 	arg_error( "loi", $1).
+
+
+C_los		
+	$1 == 4		==> 	"jsr (.los)".
+	default		==> 	arg_error( "los", $1).
+
+C_ldl		==> 	"move.l ($1+4, a6), -(sp)";
+			"move.l ($1, a6), -(sp)".
+
+C_lde..		==> 	"move.l ($1+$2+4), -(sp)";
+			"move.l ($1+$2), -(sp)".
+
+C_ldf		==> 	"move.l (sp)+, a0";
+			"move.l ($1+4,a0), -(sp)";
+			"move.l ($1,a0), -(sp)".
+
+C_lpi		==> 	"pea ($1)".
+
+
+/******************************************************************************/
+/*                                                                            */
+/*			Group 2 : Store instructions			      */
+/*							 		      */
+/******************************************************************************/
+
+C_stl		==> 	"move.l (sp)+, ($1,a6)".
+
+C_ste..		==> 	"move.l (sp)+, ($1+$2)".
+
+C_sil		==>	"move.l (sp)+, ([$1,a6])".
+
+C_stf		==> 	"move.l (sp)+, a0";
+			"move.l (sp)+, ($1,a0)".
+
+C_sti		
+  	$1 == 1		==>	"move.l (sp)+, a0";	
+				"move.l (sp)+, d0";
+				"move.b d0, (a0)".
+  	$1 == 2		==>	"move.l (sp)+, a0";
+				"move.l (sp)+, d0";
+				"move.w d0, (a0)".
+  	$1 == 4		==>	"move.l (sp)+, a0";
+				"move.l (sp)+, (a0)".
+  	$1 % 4 == 0  	==>	"move.l (sp)+, a0";
+				"move.l #$1/4-1, d0";
+				"1:move.l (sp)+, (a0)+";
+				"dbf d0, 1b".
+	default		==> 	arg_error( "sti", (arith) $1).
+
+
+C_sts		==> 	"jsr (.sts)".
+
+C_sdl		==> 	"move.l (sp)+, ($1,a6)";
+			"move.l (sp)+, ($1+4,a6)".
+
+C_sde..		==> 	"move.l (sp)+, ($1+$2)";
+			"move.l (sp)+, ($1+$2+4)".
+
+C_sdf		==> 	"move.l (sp)+, a0";
+			"move.l (sp)+, ($1,a0)";
+			"move.l (sp)+, ($1+4,a0)".
+
+/******************************************************************************/
+/*									      */
+/*		Group 3 : Integer arithmetic				      */
+/*									      */
+/******************************************************************************/
+
+C_adi		
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"add.l d0, (sp)".
+	default		==> 	arg_error( "adi", $1).
+
+C_sbi		
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"sub.l d0, (sp)".
+	default		==> 	arg_error( "sbi", $1).
+
+C_mli
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"muls.l (sp)+, d0";
+				"move.l d0, -(sp)".
+	default		==>	arg_error( "mli", $1).
+
+C_dvi		
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"divs.l d0, d1";
+				"move.l d1, -(sp)".
+	default		==> 	arg_error( "dvi", $1).
+
+C_rmi	
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"divsl.l d0, d2:d1";
+				"move.l d2, -(sp)".
+	default		==>	arg_error( "rmi", $1).
+
+C_ngi		
+	$1 == 4		==> 	"neg.l (sp)".
+	default 	==>	arg_error( "ngi", $1).
+
+
+C_sli		
+	$1 == 4		==> 	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"asl.l d0, d1";
+				"move.l d1, -(sp)".
+	default		==> 	arg_error( "sli", $1).
+
+C_sri		
+	$1 == 4		==> 	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"asr.l d0, d1";
+				"move.l d1, -(sp)".
+	default		==>	arg_error( "sri", $1).
+
+
+/******************************************************************************/
+/*									      */
+/*		Group 4 : Unsigned arithmetic 				      */
+/*									      */
+/******************************************************************************/
+
+
+C_adu		==> 	C_adi( w).
+
+C_sbu		==> 	C_sbi( w).
+
+C_mlu
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"mulu.l (sp)+, d0";
+				"move.l d0, -(sp)".
+	default		==>	arg_error( "mlu", $1).
+
+C_dvu		
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"divu.l d0, d1";
+				"move.l d1, -(sp)".
+	default		==> 	arg_error( "dvu", $1).
+
+C_rmu		
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"divul.l d0, d2:d1";
+				"move.l d2, -(sp)".
+	default		==> 	arg_error( "rmu", $1).
+
+C_slu		==> 	C_sli( w).
+
+C_sru
+	$1 == 4		==> 	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"lsr.l d0, d1";
+				"move.l d1, -(sp)".
+	default		==>	arg_error( "sru", $1).
+
+
+/******************************************************************************/
+/*									      */
+/*		Group 5 : Floating point arithmetic 			      */
+/*									      */
+/******************************************************************************/
+
+C_adf	
+	$1 == 4		==>	"jsr (adf4)".
+	$1 == 8		==>	"jsr (adf8)".
+	default		==>	arg_error( "adf", $1).
+
+C_sbf	
+	$1 == 4		==>	"jsr (sbf4)".
+	$1 == 8		==>	"jsr (sbf8)".
+	default		==>	arg_error( "sbf", $1).
+
+C_mlf	
+	$1 == 4		==>	"jsr (mlf4)".
+	$1 == 8		==>	"jsr (mlf8)".
+	default		==>	arg_error( "mlf", $1).
+
+C_dvf	
+	$1 == 4		==>	"jsr (dvf4)".
+	$1 == 8		==>	"jsr (dvf8)".
+	default		==>	arg_error( "dvf", $1).
+
+C_ngf	==>			"move.l #7,d0";
+				"bchg d0,(sp)".
+
+C_fif	
+	$1 == 4		==>	"jsr (fif4)".
+	$1 == 8		==>	"jsr (fif8)".
+	default		==>	arg_error( "fif", $1).
+
+C_fef	
+	$1 == 4		==>	"jsr (fef4)".
+	$1 == 8		==>	"jsr (fef8)".
+	default		==>	arg_error( "fef", $1).
+
+/******************************************************************************/
+/*									      */
+/*		Group 6 : Pointer arithmetic 				      */
+/*									      */
+/******************************************************************************/
+
+C_adp		
+	$1 == 0		==> 	.
+	default		==> 	"add.l #$1, (sp)".
+
+C_ads
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"add.l d0, (sp)".
+  	default		==>	arg_error( "ads", $1).
+
+C_sbs		
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"sub.l d0, (sp)".
+  	default		==>	arg_error( "sbs", $1).
+
+/******************************************************************************/
+/*									      */
+/*		Group 7 : Increment/decrement/zero			      */
+/*									      */
+/******************************************************************************/
+
+C_inc		==> 	"add.l #1, (sp)".
+
+C_inl		==>	"add.l #1, ($1, a6)".
+
+C_ine..		==> 	"add.l #1, ($1+$2)".
+
+C_dec		==> 	"sub.l #1, (sp)".
+
+C_del		==>	"sub.l #1, ($1, a6)".
+
+C_dee..		==> 	"sub.l #1, ($1+$2)".
+
+C_zrl		==>	"clr.l ($1, a6)".
+
+C_zre..		==> 	"clr.l ($1+$2)".
+
+C_zrf 		==>	C_zer( $1).
+
+C_zer
+  	$1 == 4		==>	"clr.l -(sp)".
+  	$1 == 8		==>	"clr.l -(sp)";
+  				"clr.l -(sp)".
+  	default		==>	"move.l #$1/4-1, d0";
+				"1:";
+				"clr.l -(sp)";
+				"dbf d0, 1b".
+
+/******************************************************************************/
+/*									      */
+/*		Group 8 : Convert 					      */
+/*									      */
+/******************************************************************************/
+
+C_cii		==> 	"   move.l (sp), d0";
+			"   move.l (4, sp), d1";
+			"   cmp.l d1, d0";
+			"   ble 4f";
+			"   cmp.l #4, d1";
+			"   bge 4f";
+			"   move.l (8, sp), d2";
+			"   cmp.l #1, d1";
+			"   bne 2f";
+			"   cmp.l #2, d0";
+			"   bne 1f";
+			"   ext.w d2";
+			"   bra 3f";
+			"1: extl.l d2";
+			"   bra 3f";
+			"2: ext.l d2";
+			"3: move.l d2, (8, sp)";
+			"   move.l #4, (4, sp)";
+			"4: jsr (.cii)".
+
+C_cuu		==> 	"lea	(8,sp),sp".
+
+C_ciu		==>	C_cuu().
+
+C_cui		==>	C_cuu().
+
+C_cfi		==>	"jsr (cfi)".
+
+C_cfu		==>	"jsr (cfu)".
+
+C_cff		==>	"jsr (cff)".
+
+C_cif		==>	"jsr (cif)".
+
+C_cuf		==>	"jsr (cuf)".
+
+/******************************************************************************/
+/*									      */
+/*		Group 9 : Logical 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_and		
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"and.l d0, (sp)".
+  	default		==>	"move.l #$1/4-1, d0";
+				"lea ($1, sp), a0";
+				"1:";
+				"move.l (sp)+, d1";
+				"and.l d1, (a0)+";
+				"dbf d0, 1b".
+
+C_ior		
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"or.l d0, (sp)".
+  	default		==>	"move.l #$1/4-1, d0";
+				"lea ($1, sp), a0";
+				"1:";
+				"move.l (sp)+, d1";
+				"or.l d1, (a0)+";
+				"dbf d0, 1b".
+
+C_xor		
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"eor.l d0, (sp)".
+  	default		==>	"move.l #$1/4-1, d0";
+				"lea ($1, sp), a0";
+				"1:";
+				"move.l (sp)+, d1";
+				"eor.l d1, (a0)+";
+				"dbf d0, 1b".
+
+C_com	
+  	$1 == 4		==>	"not.l (sp)".
+  	$1 == 8		==>	"not.l (sp)";
+				"not.l (4, sp)".
+  	default		==>	"move.l #$1/4-1, d0";
+				"move.l sp, a0";
+				"1:";
+				"not.l (a0)+";
+				"dbf d0, 1b".
+
+C_rol
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"rol.l d0, d1";
+				"move.l d1, -(sp)".
+  	default		==>	arg_error( "rol", $1).
+
+C_ror
+	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"ror.l d0, d1";
+				"move.l d1, -(sp)".
+  	default		==>	arg_error( "ror", $1).
+
+
+/******************************************************************************/
+/*									      */
+/*		Group 10 : Sets 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_inn
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"btst d0, d1";
+				"sne d1";
+				"and.l #1, d1";
+				"move.l d1, -(sp)".
+  	default		==>	"move.l (sp)+, d0";
+				"move.l #$1, d1";
+				"jsr (.inn)";
+				"move.l d0, -(sp)".
+
+C_inn_narg	==> 	"move.l (sp)+, d1";
+			"move.l (sp)+, d0";
+			"jsr (.inn)";
+			"move.l d0, -(sp)".
+  
+C_set
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"clr.l d1";
+				"bset d0, d1";
+				"move.l d1, -(sp)".
+  	default		==>	"move.l (sp)+, d0";
+				"move.l #$1, d1";
+				"jsr (.set)".
+
+C_set_narg	==> 	"move.l (sp)+, d1";
+			"move.l (sp)+, d0";
+			"jsr (.set)".
+
+/******************************************************************************/
+/*									      */
+/*		Group 11 : Array 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_lar		==>	"move.l #$1, d0";
+			"jsr (.lar)".
+
+C_lar_narg	==> 	"move.l (sp)+, d0";
+			"jsr (.lar)".
+
+C_sar		==>	"move.l #$1, d0";
+			"jsr (.sar)".
+
+C_sar_narg	==> 	"move.l (sp)+, d0";
+			"jsr (.sar)".
+
+C_aar		==>	"move.l #$1, d0";
+			"jsr (.aar)";
+			"move.l a0, -(sp)".
+
+C_aar_narg	==> 	"move.l (sp)+, d0";
+			"jsr (.aar)";
+			"move.l a0, -(sp)".
+
+/******************************************************************************/
+/*									      */
+/*		Group 12 : Compare 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_cmi		
+  	$1 == 4		==>	"clr.l d0";
+		  		"cmp.l (sp)+, (sp)+";
+				"beq 2f";
+				"blt 1f";
+				"add.l #1, d0";
+				"bra 2f";
+				"1 : sub.l #1, d0";
+				"2 : move.l d0, -(sp)".
+  	default		==>	"move.l #$1, d0";
+				"jsr (.cmi)";
+				"move.l d0, -(sp)".
+
+
+C_cmu		
+  	$1 == 4		==>	"clr.l d0";
+		  		"cmp.l (sp)+, (sp)+";
+				"beq 2f";
+				"bcs 1f";
+				"add.l #1, d0";
+				"bra 2f";
+				"1 : sub.l #1, d0";
+				"2 : move.l d0, -(sp)".
+
+  	default		==>	"move.l #$1, d0";
+				"jsr (.cmu)";
+				"move.l d0, -(sp)".
+
+C_cmu_narg	==> 	"move.l (sp)+, d0";
+			"jsr (.cmu)";
+			"move.l d0, -(sp)".
+
+C_cms		==> 	"move.l #$1, d0";
+			"jsr (.cms)";
+			"move.l d0, -(sp)".
+
+C_cms_narg	==> 	"move.l (sp)+, d0";
+			"jsr (.cms)";
+			"move.l d0, -(sp)".
+
+C_cmp		==>	C_cmu( (arith)4).
+
+C_tlt		==> 	"move.l (sp)+, d0";
+			"move.l #1, -(sp)";
+			"tst.l d0";
+			"blt 1f";
+			"clr.l (sp)";
+			"1:".
+
+C_tle		==> 	"move.l (sp)+, d0";
+			"move.l #1, -(sp)";
+			"tst.l d0";
+			"ble 1f";
+			"clr.l (sp)";
+			"1:".
+
+C_teq		==> 	"move.l (sp)+, d0";
+			"move.l #1, -(sp)";
+			"tst.l d0";
+			"beq 1f";
+			"clr.l (sp)";
+			"1:".
+
+C_tne		==> 	"move.l (sp)+, d0";
+			"move.l #1, -(sp)";
+			"tst.l d0";
+			"bne 1f";
+			"clr.l (sp)";
+			"1:".
+
+C_tge		==> 	"move.l (sp)+, d0";
+			"move.l #1, -(sp)";
+			"tst.l d0";
+			"bge 1f";
+			"clr.l (sp)";
+			"1:".
+
+C_tgt		==> 	"move.l (sp)+, d0";
+			"move.l #1, -(sp)";
+			"tst.l d0";
+			"bgt 1f";
+			"clr.l (sp)";
+			"1:".
+
+C_cmf
+	$1 == 4	==>	"jsr (cmf4)".
+	$1 == 8 ==>	"jsr (cmf8)".
+	default ==>	arg_error("cmf", $1).
+
+/******************************************************************************/
+/*									      */
+/*		Group 13 : Branch 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_bra		==> 	"bra $1".
+
+C_blt		==> 	"move.l (sp)+, d0";
+			"cmp.l (sp)+, d0";
+			"bgt $1".
+
+C_ble		==> 	"move.l (sp)+, d0";
+			"cmp.l (sp)+, d0";
+			"bge $1".
+
+C_beq		==> 	"move.l (sp)+, d0";
+			"cmp.l (sp)+, d0";
+			"beq $1".	
+
+C_bne		==> 	"move.l (sp)+, d0";
+			"cmp.l (sp)+, d0";
+			"bne $1".
+
+C_bge		==> 	"move.l (sp)+, d0";
+			"cmp.l (sp)+, d0";
+			"ble $1".
+
+C_bgt		==> 	"move.l (sp)+, d0";
+			"cmp.l (sp)+, d0";
+			"blt $1".
+
+C_zlt		==> 	"tst.l (sp)+";
+			"blt $1".
+
+C_zle		==> 	"tst.l (sp)+";
+			"ble $1".
+
+C_zeq		==> 	"tst.l (sp)+";
+			"beq $1".
+
+C_zne		==> 	"tst.l (sp)+";
+			"bne $1".
+
+C_zge		==> 	"tst.l (sp)+";
+			"bge $1".
+
+C_zgt		==> 	"tst.l (sp)+";
+			"bgt $1".
+
+
+/******************************************************************************/
+/*                                                                            */
+/*			Group 14 : Procedure call instructions		      */
+/*							 		      */
+/******************************************************************************/
+
+C_cai		==> 	"move.l (sp)+, a0";
+			"jsr (a0)".
+
+C_cal		==> 	"jsr ($1)".
+
+C_lfr		
+  	$1 == 4		==>	"move.l d0, -(sp)".
+  	$1 == 8		==>	"move.l d1, -(sp)";
+				"move.l d0, -(sp)".
+  	default		==>	arg_error( "lfr", $1).
+
+C_ret		
+	$1 == 0		==>	"unlk a6";
+				"rts".
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"unlk a6";
+				"rts".
+  	$1 == 8		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, d1";
+				"unlk a6";
+				"rts".
+  	default		==>	arg_error( "ret", $1).
+
+/******************************************************************************/
+/*                                                                            */
+/*			Group 15 : Miscellaneous instructions		      */
+/*							 		      */
+/******************************************************************************/
+
+C_asp		
+	small( $1)	==> 	"add.l #$1, sp".
+	default		==>	"lea ($1, sp), sp".
+
+C_ass		
+  	$1 == 4		==>	"add.l (sp)+, sp".
+  	default		==>	arg_error( "ass", $1).
+
+C_blm		
+  	$1 == 4		==>	"move.l (sp)+, a0";
+				"move.l (sp)+, a1";
+				"move.l (a1), (a0)".
+  	$1 == 8		==>	"move.l (sp)+, a0";
+				"move.l (sp)+, a1";
+				"move.l (a1), (a0)";
+				"move.l (4, a1), (4, a0)".
+  	default		==>	"move.l (sp)+, a0";
+				"move.l (sp)+, a1";
+				"move.l #$1/4-1, d0";
+				"1:";
+				"move.l (a1)+, (a0)+";
+				"dbf d0, 1b".
+
+C_bls		
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"move.l (sp)+, a0";
+				"move.l (sp)+, a1";
+				"asr.l #2, d1";
+				"beq 2f";
+				"1:";
+				"move.l (a1)+, (a0)+";
+				"dbf d0, 1b";
+				"2:".
+  	default		==>	arg_error( "bls", $1).
+
+
+C_csa		
+	$1 == 4		==>	"jmp (.csa)".
+  	default		==>	arg_error( "csa", $1).
+
+C_csb		
+	$1 == 4		==>	"jmp (.csb)".
+  	default		==>	arg_error( "csb", $1).
+
+C_dch		==>	C_loi( (arith)4).
+
+C_dup		
+  	$1 == 4		==>	"move.l (sp), -(sp)".
+  	$1 == 4		==>	"move.l (4, sp), -(sp)";
+  				"move.l (4, sp), -(sp)".
+  	default		==>	"move.l #$1/4-1, d0";
+				"1:";
+				"move.l ($1-4, sp), -(sp)";
+				"dbf d0, 1b".
+
+C_dus		
+  	$1 == 4		==>	"move.l (sp)+, d0";
+				"lea (0, sp, d0.l*1), a0";
+				"asr.l #2, d0";
+				"beq 2f";
+				"sub.l #1, d0";
+				"1:";
+				"move.l -(a0), -(sp)";
+				"dbf d0, 1b";
+				"2:".
+  	default		==>	arg_error( "dus", $1).
+
+C_exg		==>	"move.l #$1, d0";
+			"jsr (.exg)".
+
+C_fil..		==> 	"move.l #$1+$2, (.filn)".
+
+C_gto..		==> 	"move.l #$1+$2, a0";
+			"move.l (8, a0), a6";
+			"move.l (4, a0), sp";
+			"jmp ([0,a0], 0)".
+
+C_lim		==> 	"move.l (.trpim), -(sp)".
+
+C_lin		==> 	"move.l #$1, (.lino)".
+
+C_lni		==> 	"add.l #1, (.lino)".
+
+C_lor
+  	$1 == 0		==>	"move.l a6, -(sp)".
+  	$1 == 1		==>	"move.l sp, -(sp)".
+  	$1 == 2		==>	"move.l (.reghp), -(sp)".
+	default		==>	arg_error( "lor", $1).
+
+C_lpb		==>	C_adp( (arith)8).
+
+C_mon		==>	"jsr (.mon)".
+
+C_nop		==>	"jsr (.nop)".
+
+C_rck		
+  	$1 == 4		==>	"move.l (sp)+, a0";
+				"move.l (sp)+, d0";
+				"cmp2.l (a0), d0";
+				"bcc 1f";
+				"pea (1)";	/* push constant 1 == ERANGE */
+				"jsr (.trp)";
+				"1: move.l d0, -(sp)".
+  	default		==>	arg_error( "rck", $1).
+
+C_rtt		==>	C_ret( (arith)0).
+
+C_sig		==>	"move.l (.trppc), a0";
+			"move.l (sp)+, (.trppc)";
+			"move.l a0, -(sp)".
+
+C_sim		==> 	"move.l (sp)+, (.trpim)".
+
+C_str
+  	$1 == 0		==>	"move.l (sp)+, a6".
+  	$1 == 1		==>	"move.l (sp)+, sp".
+  	$1 == 2		==>	"jsr (.strhp)".
+	default		==>	arg_error( "str", $1).
+
+C_trp		==> 	"jsr (.trp)".
+
+/*****************************************************************************/
+
+..icon	
+	$2 == 1  	==>	gen1( (ONE_BYTE) atoi( $1)).
+	$2 == 2  	==> 	gen2( (TWO_BYTES) atoi( $1)).
+	$2 == 4  	==> 	gen4( (FOUR_BYTES) atol( $1)).
+	default     	==> 	arg_error( "icon", $2).
+
+..ucon	
+	$2 == 1  	==>	gen1( (ONE_BYTE) atoi( $1)).
+	$2 == 2  	==> 	gen2( (TWO_BYTES) atoi( $1)).
+	$2 == 4  	==> 	gen4( (FOUR_BYTES) atol( $1)).
+	default     	==> 	arg_error( "icon", $2).
+
+..fcon			==>	con_float($1, $2).
+
+/*****************************************************************************/
+
+prolog		==>	.
+
+jump 		==>	"jmp $1".
+
+locals		==>	"link a6, #-$1".

+ 106 - 0
mach/sun3/ce/Make.back

@@ -0,0 +1,106 @@
+EMHOME=../../../..
+CEG=$(EMHOME)/lib/ceg
+SOURCE=$(CEG)/ce_back/obj_back
+CFLAGS=-O
+CC=cc
+
+IDIRS=-I.\
+      -I..\
+      -I$(EMHOME)/h\
+      -I$(EMHOME)/modules/h
+
+all : data.o con2.o con4.o relocation.o end_back.o gen1.o gen2.o\
+      gen4.o init_back.o mysprint.o output.o reloc1.o reloc2.o reloc4.o\
+      rom2.o rom4.o set_global.o set_local.o switchseg.o symboldef.o text2.o\
+      text4.o do_open.o do_close.o memory.o label.o misc.o extnd.o symtable.o\
+      common.o
+
+data.o : data.h back.h header.h $(SOURCE)/data.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/data.c
+
+memory.o :data.h  back.h header.h $(SOURCE)/memory.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/memory.c
+
+con2.o : data.h back.h header.h $(SOURCE)/con2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con2.c
+
+con4.o : data.h back.h header.h $(SOURCE)/con4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/con4.c
+
+relocation.o : data.h back.h ../mach.h ../relocation.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. ../relocation.c
+
+do_open.o : data.h back.h ../mach.h ../do_open.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. ../do_open.c
+
+do_close.o : data.h back.h ../mach.h ../do_close.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. ../do_close.c
+
+gen1.o : data.h back.h header.h $(SOURCE)/gen1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen1.c
+
+gen2.o : data.h back.h header.h $(SOURCE)/gen2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen2.c
+
+gen4.o : data.h back.h header.h $(SOURCE)/gen4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/gen4.c
+
+init_back.o : data.h back.h ../mach.h $(SOURCE)/init_back.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/init_back.c
+
+end_back.o : data.h back.h ../mach.h ../end_back.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. ../end_back.c
+
+mysprint.o : data.h back.h data.h $(SOURCE)/mysprint.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/mysprint.c
+
+output.o : data.h back.h ../mach.h ../output.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. ../output.c
+
+reloc1.o : data.h back.h header.h $(SOURCE)/reloc1.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc1.c
+
+reloc2.o : data.h back.h header.h $(SOURCE)/reloc2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc2.c
+
+reloc4.o : data.h back.h header.h $(SOURCE)/reloc4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/reloc4.c
+
+rom2.o : data.h back.h header.h $(SOURCE)/rom2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom2.c
+
+rom4.o : data.h back.h header.h $(SOURCE)/rom4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/rom4.c
+
+set_global.o : data.h back.h ../mach.h $(SOURCE)/set_global.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/set_global.c
+
+set_local.o : data.h back.h ../mach.h $(SOURCE)/set_local.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/set_local.c
+
+switchseg.o : data.h back.h ../mach.h $(SOURCE)/switchseg.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/switchseg.c
+
+symboldef.o : data.h back.h ../mach.h $(SOURCE)/symboldef.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/symboldef.c
+
+text2.o : data.h back.h ../mach.h $(SOURCE)/text2.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/text2.c
+
+text4.o : data.h back.h ../mach.h $(SOURCE)/text4.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/text4.c
+
+symtable.o : data.h back.h ../mach.h $(SOURCE)/symtable.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/symtable.c
+
+extnd.o : data.h back.h ../mach.h $(SOURCE)/extnd.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/extnd.c
+
+misc.o : data.h back.h ../mach.h $(SOURCE)/misc.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. ../misc.c
+
+label.o : data.h back.h ../mach.h $(SOURCE)/label.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/label.c
+
+common.o : data.h back.h ../mach.h $(SOURCE)/common.c
+	$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/common.c

+ 16 - 0
mach/sun3/ce/Makefile

@@ -0,0 +1,16 @@
+EMHOME=../../..
+BACK=$(EMHOME)/lib/ceg/ce_back
+
+install : back.a
+	install_ceg
+
+clean:
+	rm -rf back.a back
+
+back.a :
+	-mkdir back
+	cp $(BACK)/obj_back/*h back
+	cp Make.back back/Makefile
+	( cd back; make)
+	ar r back.a back/*o;
+	-ranlib back.a

+ 352 - 0
mach/sun3/ce/as.c

@@ -0,0 +1,352 @@
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include "as.h"
+#include "arg_type.h"
+
+
+process_label() {}
+
+
+process_mnemonic( m)
+char *m;
+{
+	for ( ; *m != '\0'; m++)
+		if ( *m == '.')
+			*m = '_';
+}
+
+
+process_operand( str, op)
+char *str;
+struct t_operand *op;
+{
+	char *glob_lbl();
+
+	op->type = 0;
+
+	switch ( *str) {
+	  case '#' : op->type = IS_IMMEDIATE;
+		     op->expr = str+1;
+
+		     if ( *(op->expr) != '$') {			/*  #1  */
+			op->val = atoi( str+1);
+			if ( 1 <= op->val  &&  op->val <= 8 ) {
+				op->type = IS_QUICK;
+				op->lbl = NULL;
+			}
+		     }
+		     else 
+			if ( arg_type( str+1) == STRING) {	/*  #$1+$2  */
+				op->lbl = op->expr;
+				*(op->lbl+2) = '\0';
+				op->expr = op->lbl+3;
+		     	}
+		     	else					/*  #$1  */
+				op->lbl = NULL;
+		     break;
+
+	  case '(' : if ( index( str+1, ',') == NULL)
+			if ( is_reg( str+1)) {
+				op->reg = reg_val( str+1);
+
+				if ( *(str+4) == '+')		/*  (sp)+  */
+					op->type = IS_INCR;
+				else				/*  (a0)  */
+					op->type = IS_IND_REG;
+			}
+			else {
+				op->type = IS_IND_MEM;
+				op->expr = str+1;
+				for ( str++; *++str != ')';)
+					;
+				*str = '\0';
+
+				if ( *(op->expr) == '$')
+					if ( arg_type( op->expr) == STRING) {
+								/*  ($1+$2)  */
+						op->lbl = op->expr;
+						if ( strlen( op->lbl) == 2) 
+							op->expr = "0";
+						else {
+							*(op->lbl+2) = '\0';
+							op->expr = op->lbl+3;
+						}
+		     			}
+		     			else			/*  ($1)  */
+						op->lbl = NULL;
+				else if ( isdigit( *(op->expr))) /*  (1)  */
+					op->lbl = NULL;
+				else {				/*  (.trppc) */
+					op->lbl = glob_lbl( op->expr);
+					op->expr = "0";
+				}
+			}
+		     else
+			if ( *(str+1) == '[') {
+				op->type = IS_IND_IND;
+				op->expr = str+2;
+				for ( str += 2; *++str != ',';)
+					;
+				*str++ = '\0';
+				for ( ; *str == ' '; str++)
+					;
+				op->reg = reg_val( str);
+
+				for ( ; *str++ != ']';)
+					;
+				if ( *str == ')')	/*  ([$1, a6])  */
+					op->expr2 = 0;
+				else {			/*  ([8,a6],8)  */
+					for ( ; *str++ != ',';)
+						;
+					for ( ; *str == ' '; str++)
+						;
+					op->expr2 = atoi( str);
+				}
+			}
+			else {
+				op->expr = str+1;
+				for ( str++; *++str != ',';)
+					;
+				*str++ = '\0';
+				for ( ; *str == ' '; str++)
+					;
+				op->reg = reg_val( str);
+				if ( *(str+2) == ')')		/*  (4, a0)  */
+					op->type = IS_IND_REG_DISPL;
+				else {			 /*  (0, sp, d0.l*1)  */
+					op->type = IS_3_OPS;
+					for ( str++; *++str != ',';)
+						;
+					for ( ; *str == ' '; str++)
+						;
+					op->reg2 = reg_val( str);
+
+					for ( ; *str++ != '*';)
+						;
+					op->scale = atoi( str);
+				}
+			}
+		     break;
+
+	  case '-' : op->type = IS_DECR;			/*  -(sp)  */
+		     op->reg = reg_val( str+2);
+		     break;
+
+	  case '$' : op->type = IS_GLOB_LBL;			/*  $1  */
+		     op->lbl = str;
+		     op->expr ="0";
+		     break;
+
+	  default  : if ( is_reg( str)) {
+			op->reg = reg_val( str);
+			if ( *(str+2) == ':') {			/*  d2:d1  */
+				op->type = IS_REG_PAIR;
+				op->reg2 = reg_val( str+3);
+			}
+			else					/*  a6  */
+				op->type = ( *str == 'd' ? IS_D_REG : IS_A_REG);
+		     }
+		     else if ( isdigit( *str)) {		/*  1f  */
+			op->type = IS_LOC_LBL;
+			op->lbl = str;
+			op->expr = "0";
+			*(str+1) ='\0';
+		     }
+		     else {					/*  .strhp  */
+			op->type = IS_GLOB_LBL;
+			op->lbl = glob_lbl( str);
+			*(str+1) ='\0';
+			op->expr = "0";
+		     }
+	}
+}
+
+
+int reg_val( reg)
+char *reg;
+{
+	return( *reg == 's' ? 7 : atoi( reg+1));
+}
+
+int is_reg( str)
+char *str;
+{
+	switch ( *str) {
+	  case 'a' :
+	  case 'd' : return( isdigit( *(str+1)));
+
+	  case 's' : return( *(str+1) == 'p');
+
+	  default  : return( 0);
+	}
+}
+
+
+char *glob_lbl( lbl)
+char *lbl;
+{
+	char *gl, *malloc();
+
+	gl = malloc( strlen( lbl) + 3);
+	sprintf( gl, "\"%s\"", lbl);
+	return( gl);
+}
+
+
+/******************************************************************************/
+
+
+int mode_reg( eaddr)
+struct t_operand *eaddr;
+{
+	switch ( eaddr->type) {
+	  case IS_A_REG         : return( 0x08 | eaddr->reg);
+
+	  case IS_D_REG         : return( 0x00 | eaddr->reg);
+
+	  case IS_IND_REG       : return( 0x10 | eaddr->reg);
+
+	  case IS_INCR          : return( 0x18 | eaddr->reg);
+
+	  case IS_DECR          : return( 0x20 | eaddr->reg);
+
+	  case IS_IND_MEM       : return( 0x39);
+
+	  case IS_IND_IND       : return( 0x30 | eaddr->reg);
+
+	  case IS_IND_REG_DISPL : return( 0x28 | eaddr->reg);
+
+	  case IS_GLOB_LBL      : return( 0x39);
+
+	  case IS_3_OPS         : if ( isdigit( *(eaddr->expr)) &&
+				                    atoi( eaddr->expr) < 128)
+					return( 0x30 | eaddr->reg);
+				  else
+					fprintf( stderr, "FOUT in IS_3_OPS\n");
+				  break;
+
+	  case IS_QUICK		:
+	  case IS_IMMEDIATE	: return( 0x3c);
+
+	  default		: fprintf( stderr,
+					   "mode_reg(), verkeerde operand %d\n",
+					   eaddr->type);
+				  abort();
+				  break;
+	}
+}
+
+
+code_extension( eaddr)
+struct t_operand *eaddr;
+{
+
+	switch ( eaddr->type) {
+	  case IS_IND_MEM       : if ( eaddr->lbl == NULL) 
+					@text4( %$( eaddr->expr));
+				  else
+					@reloc4( %$( eaddr->lbl),
+						 %$( eaddr->expr),
+						 ABSOLUTE);
+				  break;
+
+	  case IS_IND_IND       : if ( eaddr->expr2 == 0) {
+				  	@text2( 0x161);
+					@text2( %$(eaddr->expr));
+				  }
+				  else {
+				  	@text2( 0x162);
+					@text2( %$(eaddr->expr));
+					@text2( %d(eaddr->expr2));
+				  }
+				  break;
+
+	  case IS_IND_REG_DISPL : @text2( %$( eaddr->expr));
+				  break;
+
+	  case IS_GLOB_LBL      : @reloc4( %$(eaddr->lbl),
+					   %$(eaddr->expr),
+					   ABSOLUTE);
+				  break;
+
+	  case IS_3_OPS         : if ( isdigit( *(eaddr->expr)) &&
+				                    atoi( eaddr->expr) < 128) {
+
+					@text2( %d( 0x0800 |
+				  	  	  ( eaddr->reg2 << 12) |
+					  	  ( two_log( eaddr->scale)<<9) |
+					  	  atoi( eaddr->expr)));
+				  }
+				  else
+					fprintf( stderr, "FOUT in IS_3_OPS\n");
+				  break;
+
+	  case IS_QUICK		:
+	  case IS_IMMEDIATE	: if ( eaddr->lbl != NULL)
+					@reloc4( %$(eaddr->lbl),
+						 %$(eaddr->expr),
+						 ABSOLUTE);
+				  else
+					@text4( %$(eaddr->expr));
+	}
+}
+
+
+int reg_mode( eaddr)
+struct t_operand *eaddr;
+{
+	int mr;
+
+	mr = mode_reg( eaddr);
+	return( ((mr & 0x7) << 3) | ((mr & 0x38) >> 3));
+}
+
+
+code_opcode( opcode, field1, field2, eaddr)
+int opcode, field1, field2;
+struct t_operand *eaddr;
+{
+	@text2( %d(((opcode & 0xf) << 12) | ((field1 & 0x7) << 9) |
+		   ((field2 & 0x7) << 6) | (mode_reg(eaddr) & 0x3f)));
+}
+
+
+code_instr( opcode, field1, field2, eaddr)
+int opcode, field1, field2;
+struct t_operand *eaddr;
+{
+	code_opcode( opcode, field1, field2, eaddr);
+	code_extension( eaddr);
+}
+
+
+code_move( size, src, dst)
+int size;
+struct t_operand *src, *dst;
+{
+	@text2( %d( ((size & 0x3) << 12) | ((reg_mode( dst) & 0x3f) << 6) |
+		    	     		   (mode_reg( src) & 0x3f)));
+	code_extension( src);
+	code_extension( dst);
+}
+
+
+code_dist4( dst)
+struct t_operand *dst;
+{
+	@reloc4( %$(dst->lbl), %$(dst->expr) + 4, PC_REL);
+}
+
+
+int two_log( nr)
+int nr;
+{
+	int log;
+
+	for ( log = 0; nr >= 2; nr >>= 1)
+		log++;
+
+	return( log);
+}

+ 33 - 0
mach/sun3/ce/as.h

@@ -0,0 +1,33 @@
+#define ARITH_FMT	"%ld"
+#define INT_FMT		"%d"
+
+struct t_operand {
+	unsigned type;
+	char *expr, *lbl;
+	int val, reg, reg2, scale, expr2;
+       };
+
+#define IS_QUICK		1
+#define IS_IMMEDIATE		2
+#define IS_A_REG		3
+#define IS_D_REG		4
+#define IS_REG_PAIR		5
+#define IS_INCR			6
+#define IS_DECR			7
+#define IS_3_OPS		8
+#define IS_IND_MEM		9
+#define IS_IND_IND		10
+#define IS_GLOB_LBL		11
+#define IS_LOC_LBL		12
+#define IS_IND_REG		13
+#define IS_IND_REG_DISPL	14
+
+#define QUICK( op)	(op->type == IS_QUICK)
+#define IMMEDIATE( op)	(op->type == IS_IMMEDIATE)
+#define A_REG( op)	(op->type == IS_A_REG)
+#define D_REG( op)	(op->type == IS_D_REG)
+#define REG_PAIR( op)	(op->type == IS_REG_PAIR)
+#define INCR( op)	(op->type == IS_INCR)
+#define REG( op)	(op->type == IS_A_REG || op->type == IS_D_REG)
+#define LOC_LBL( op)	(op->type == IS_LOC_LBL)
+#define GLOB_LBL( op)	(op->type == IS_GLOB_LBL)

+ 167 - 0
mach/sun3/ce/as_table

@@ -0,0 +1,167 @@
+add_l src:QUICK, dst		==> code_instr( 0x5, src->val, 0x2, dst).
+...   src:IMMEDIATE, dst:A_REG	==> @if ( small( %$(src->expr)))
+					@text2( 0x5088 | (%d(dst->reg) & 0x7) |
+						((%$(src->expr) & 0x7) << 9)).
+				    @else
+					code_instr( 0xd, dst->reg, 0x7, src).
+				    @fi.
+...   src:IMMEDIATE, dst	==> code_opcode( 0x0, 0x3, 0x2, dst);
+				    code_extension( src);
+				    code_extension( dst).
+...   src, dst:D_REG		==> code_instr( 0xd, dst->reg, 0x6, src).
+...   src, dst:A_REG		==> code_instr( 0xd, dst->reg, 0x7, src).
+...   src:D_REG, dst		==> code_instr( 0xd, src->reg, 0x6, dst).
+
+and_l src:QUICK, dst		==> code_opcode( 0x0, 0x1, 0x2, dst);
+				    code_extension( src);
+				    code_extension( dst).
+...   src:IMMEDIATE, dst	==> code_opcode( 0x0, 0x1, 0x2, dst);
+				    code_extension( src);
+				    code_extension( dst).
+...   src:D_REG, dst		==> code_instr( 0xc, src->reg, 0x6, dst).
+
+asl_l cnt:D_REG, dst:D_REG	==> @text2( %d( 0xe1a0 | (cnt->reg << 9) |
+						dst->reg)).
+
+asr_l cnt:QUICK, dst:D_REG	==> @text2( %d( 0xe080 | (cnt->val << 9) |
+						dst->reg)).
+...   cnt:D_REG, dst:D_REG	==> @text2( %d( 0xe0a0 | (cnt->reg << 9) |
+						dst->reg)).
+
+bcc dst:LOC_LBL			==> @text2( 0x6400 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x64ff);
+				    code_dist4( dst).
+bcs dst:LOC_LBL			==> @text2( 0x6500 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x65ff);
+				    code_dist4( dst).
+beq dst:LOC_LBL			==> @text2( 0x6700 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x67ff);
+				    code_dist4( dst).
+bge dst:LOC_LBL			==> @text2( 0x6c00 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x6cff);
+				    code_dist4( dst).
+bgt dst:LOC_LBL			==> @text2( 0x6e00 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x6eff);
+				    code_dist4( dst).
+ble dst:LOC_LBL			==> @text2( 0x6f00 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x6fff);
+				    code_dist4( dst).
+bls dst:LOC_LBL			==> @text2( 0x6300 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x63ff);
+				    code_dist4( dst).
+blt dst:LOC_LBL			==> @text2( 0x6d00 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x6dff);
+				    code_dist4( dst).
+bmi dst:LOC_LBL			==> @text2( 0x6b00 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x6bff);
+				    code_dist4( dst).
+bne dst:LOC_LBL			==> @text2( 0x6600 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x66ff);
+				    code_dist4( dst).
+bra dst:LOC_LBL			==> @text2( 0x6000 | %dist( dst->lbl)).
+... dst:GLOB_LBL		==> @text2( 0x60ff);
+				    code_dist4( dst).
+
+bset nr:D_REG, dst		==> code_instr( 0x0, nr->reg, 0x7, dst).
+
+btst nr:D_REG, dst		==> code_instr( 0x0, nr->reg, 0x4, dst).
+
+bchg nr:D_REG, dst		==> code_instr( 0x0, nr->reg, 0x5, dst).
+
+clr_l dst			==> code_instr( 0x4, 0x1, 0x2, dst).
+ 
+cmp_l src:INCR, dst:INCR	==> @text2( 0xb188 | %d( src->reg << 9) |
+					    %d( dst->reg)).
+...   src, dst:D_REG		==> code_instr( 0xb, dst->reg, 0x2, src).
+
+cmp2_l src, reg:D_REG		==> code_opcode( 0x0, 0x2, 0x3, src);
+				    @text2( (%d(reg->reg) & 0x7) << 12);
+				    code_extension( src).
+
+dbf reg:D_REG, dst:LOC_LBL	==> @text2( 0x51c8 | (%d(reg->reg) & 0x7));
+				    @text2( %dist(dst->lbl) + 2).
+
+divs_l src, dst:D_REG		==> code_opcode( 0x4, 0x6, 0x1, src);
+				    @text2( 0x800 | (%d(dst->reg) & 0x7) |
+					    ((%d(dst->reg) & 0x7) << 12));
+				    code_extension( src).
+
+divsl_l src, dst:REG_PAIR	==> code_opcode( 0x4, 0x6, 0x1, src);
+				    @text2( 0x800 | (%d(dst->reg) & 0x7) |
+					    ((%d(dst->reg2) & 0x7) << 12));
+				    code_extension( src).
+
+divu_l src, dst:D_REG		==> code_opcode( 0x4, 0x6, 0x1, src);
+				    @text2( (%d(dst->reg) & 0x7) |
+					    ((%d(dst->reg) & 0x7) << 12));
+				    code_extension( src).
+
+divul_l src, dst:REG_PAIR	==> code_opcode( 0x4, 0x6, 0x1, src);
+				    @text2( (%d(dst->reg) & 0x7) |
+					    ((%d(dst->reg2) & 0x7) << 12));
+				    code_extension( src).
+
+eor_l src:D_REG, dst		==> code_instr( 0xb, src->reg, 0x6, dst).
+
+ext_w dst:D_REG			==> @text2( 0x4880 | (%d(dst->reg) & 0x7)).
+
+ext_l dst:D_REG			==> @text2( 0x48c0 | (%d(dst->reg) & 0x7)).
+
+extl_l dst:D_REG		==> @text2( 0x49c0 | (%d(dst->reg) & 0x7)).
+
+jmp dst				==> code_instr( 0x4, 0x7, 0x3, dst).
+
+jsr dst				==> code_instr( 0x4, 0x7, 0x2, dst).
+
+lea src, dst:A_REG		==> code_instr( 0x4, dst->reg, 0x7, src).
+
+link reg:A_REG, displ:IMMEDIATE	==> @text2( 0x4e50 | %d(reg->reg));
+				    @text2( %$(displ->expr)).
+
+lsr_l cnt:D_REG, dst:D_REG	==> @text2( 0xe0a8 | (%d(dst->reg) & 0x7) |
+					    ((%d(cnt->reg) & 0x7) << 9)).
+
+move_b src, dst			==> code_move( 0x1, src, dst).
+
+move_l src, dst:A_REG		==> code_instr( 0x2, dst->reg, 0x1, src).
+...    src, dst			==> code_move( 0x2, src, dst).
+
+move_w src, dst			==> code_move( 0x3, src, dst).
+
+muls_l src, dst:D_REG		==> code_opcode( 0x4, 0x6, 0x0, src);
+				    @text2( 0x800 | (%d(dst->reg) & 0x7) |
+					    ((%d(dst->reg) & 0x7) << 12));
+				    code_extension( src).
+
+mulu_l src, dst:D_REG		==> code_opcode( 0x4, 0x6, 0x0, src);
+				    @text2( (%d(dst->reg) & 0x7) |
+					    ((%d(dst->reg) & 0x7) << 12));
+				    code_extension( src).
+
+neg_l dst			==> code_instr( 0x4, 0x2, 0x2, dst).
+
+not_l dst			==> code_instr( 0x4, 0x3, 0x2, dst).
+
+or_l src:D_REG, dst		==> code_instr( 0x8, src->reg, 0x6, dst).
+
+pea src				==> code_instr( 0x4, 0x4, 0x1, src).
+
+rol_l cnt:D_REG, dst:D_REG	==> @text2( 0xe1b8 | (%d(dst->reg) & 0x7) |
+						((%d(cnt->reg) & 0x7) << 9)).
+
+ror_l cnt:D_REG, dst:D_REG	==> @text2( 0xe0b8 | (%d(dst->reg) & 0x7) |
+						((%d(cnt->reg) & 0x7) << 9)).
+
+rts 				==> @text2( 0x4e75).
+
+sne dst				==> code_instr( 0x5, 0x3, 0x3, dst).
+
+sub_l src:IMMEDIATE, dst	==> code_opcode( 0x0, 0x2, 0x2, dst);
+				    code_extension( src);
+				    code_extension( dst).
+...   src:QUICK, dst		==> code_instr( 0x5, src->val, 0x6, dst).
+...   src:D_REG, dst		==> code_instr( 0x9, src->reg, 0x6, dst).
+
+tst_l dst			==> code_instr( 0x4, 0x5, 0x2, dst).
+
+unlk reg:A_REG			==> @text2( 0x4e58 | %d(reg->reg)).

+ 8 - 0
mach/sun3/ce/do_close.c

@@ -0,0 +1,8 @@
+#include <system.h>
+
+extern File *out_file;
+
+close_back()
+{
+	sys_close( out_file);
+}

+ 13 - 0
mach/sun3/ce/do_open.c

@@ -0,0 +1,13 @@
+#include <system.h>
+
+File *out_file;
+
+open_back( filename)
+char *filename;
+{
+	if ( filename == (char *) '\0')
+		return( 0);
+	else
+		return( sys_open( filename, OP_WRITE, &out_file));
+}
+

+ 24 - 0
mach/sun3/ce/end_back.c

@@ -0,0 +1,24 @@
+#include <out.h>
+#include "mach.h"
+#include "data.h"
+#include "back.h"
+#include "header.h"
+
+static do_algn();
+
+end_back()
+{
+	do_algn();                 
+	do_local_relocation();
+	output();
+}
+
+
+static
+do_algn()
+{
+	while ( ( text - text_area) % EM_WSIZE != 0 ) 
+		text1( '\0');
+	while ( ( data - data_area) % EM_WSIZE != 0 )
+		con1( '\0');
+}

+ 200 - 0
mach/sun3/ce/mach.c

@@ -0,0 +1,200 @@
+#include "mach.h"
+#include <back.h>
+#include <stdio.h>
+#include <out.h>
+
+
+arg_error( s, arg)
+char *s;
+int arg;
+{
+	fprintf( stderr, "arg_error %s %d\n", s, arg);
+}
+
+
+/*
+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 OWNFLOAT	/* compile on SUN, generate code for SUN FP ... */
+
+con_float(str, argval)
+	char *str;
+	int argval;
+{
+#ifdef NOFLOAT
+
+static int been_here;
+	if (argval != 4 && argval != 8)
+		arg_error("fcon", argval);
+	if (argval == 8)
+		gen4((FOUR_BYTES) 0);
+	gen4((FOUR_BYTES) 0);
+	if ( !been_here++)
+	{
+	fputs("Warning : dummy float-constant(s)\n", stderr);
+	}
+#else
+#define IEEEFLOAT
+	double f;
+	double atof();
+	int i;
+	int j;
+	double frexp();
+#ifndef OWNFLOAT
+	int sign = 0;
+	int fraction[4] ;
+#else OWNFLOAT
+	float fl;
+	char *p;
+#endif OWNFLOAT
+
+	if (argval!= 4 && argval!= 8)	{
+		arg_error("fcon", argval);
+		argval = 8;
+	}
+	f = atof(str);
+	if (f == 0) {
+		if (argval == 8) gen4((FOUR_BYTES) 0);
+		gen4((FOUR_BYTES) 0);
+		return;
+	}
+#ifdef OWNFLOAT
+	if (argval == 4) {
+		/* careful: avoid overflow */
+		double ldexp();
+		f = frexp(f, &i);
+		fl = f;
+		fl = frexp(fl,&j);
+		if (i+j > 127) {
+			/* overflow situation */
+			gen1(f<0?0377:0177);
+			gen1(0377);
+			gen1(0377);
+			gen1(0377);
+			return;
+		}
+		if (i+j < -127) {
+			/* underflow situation */
+			gen1(f<0?0200:0);
+			gen1(0200);
+			gen1(0);
+			gen1(0);
+			return;
+		}
+		fl = ldexp(fl, i+j);
+		p = (char *) &fl;
+	}
+	else {
+		p = (char *) &f;
+	}
+	gen1(*p++&0377);
+	for (i = argval-1; i; i--) {
+		gen1(*p++&0377);
+	}
+#else OWNFLOAT
+	f = frexp(f, &i);
+	if (f < 0) {
+		f = -f;
+		sign = 1;
+	}
+	while (f < 0.5) {
+		f += f;
+		i --;
+	}
+	f = 2*f - 1.0;		/* hidden bit */
+	i--;			/* exponent is one lower for SUN floating point! */
+#ifdef IEEEFLOAT
+	if (argval == 4) {
+#endif IEEEFLOAT
+		i = (i + 128) & 0377;
+		fraction[0] = (sign << 15) | (i << 7);
+		for (j = 6; j>= 0; j--) {
+			f *= 2;
+			if (f >= 1.0) {
+				f -= 1.0;
+				fraction[0] |= (1 << j);
+			}
+		}
+#ifdef IEEEFLOAT
+	}
+	else {
+		i = (i + 1024) & 03777;
+		fraction[0] = (sign << 15) | (i << 4);
+		for (j = 3; j>= 0; j--) {
+			f *= 2;
+			if (f >= 1.0) {
+				fraction[0] |= (1 << j);
+				f -= 1.0;
+			}
+		}
+	}
+#endif IEEEFLOAT
+	for (i = 1; i < argval / 2; i++) {
+		fraction[i] = 0;
+		for (j = 15; j>= 0; j--) {
+			f *= 2;
+			if (f >= 1.0) {
+				fraction[i] |= (1 << j);
+				f -= 1.0;
+			}
+		}
+	}
+	if (f >= 0.5) {
+		for (i = argval/2 - 1; i >= 0; i--) {
+			for (j = 0; j < 16; j++) {
+				if (fraction[i] & (1 << j)) {
+					fraction[i] &= ~(1 << j);
+				}
+				else {
+					fraction[i] |= (1 << j);
+					break;
+				}
+			}
+			if (j != 16) break;
+		}
+	}
+	for (i = 0; i < argval/2; i++) {
+		gen1((fraction[i]>>8)&0377);
+		gen1(fraction[i]&0377);
+	}
+#endif OWNFLOAT
+#endif
+}
+
+#define CODE_EXPANDER
+#include <em.h>
+
+#if EM_WSIZE == 1
+#define conEM_WSIZE	con1
+#define romEM_WSIZE	rom1
+#define CAST_WSIZE	ONE_BYTE
+#endif
+#if EM_WSIZE == 2
+#define conEM_WSIZE	con2
+#define romEM_WSIZE	rom2
+#define CAST_WSIZE	TWO_BYTES
+#endif
+#if EM_WSIZE == 4
+#define conEM_WSIZE	con4
+#define romEM_WSIZE	rom4
+#define CAST_WSIZE	FOUR_BYTES
+#endif
+
+#if EM_PSIZE == 1
+#define relocEM_PSIZE	reloc1
+#endif
+#if EM_PSIZE == 2
+#define relocEM_PSIZE	reloc2
+#endif
+#if EM_PSIZE == 4
+#define relocEM_PSIZE	reloc4
+#endif

+ 42 - 0
mach/sun3/ce/mach.h

@@ -0,0 +1,42 @@
+#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_BSIZE	8
+
+#define	BSS_INIT	0
+
+#define NAME_FMT	"_%s"
+#define DNAM_FMT	"_%s"
+#define DLB_FMT		"_%ld"
+#define	ILB_FMT		"I%x_%lx"
+#define HOL_FMT		"hol%d"
+
+#define	ALIGN_FMT		".align\n"
+
+#define	BYTE_FMT		".data1 %ld\n"
+#define	WORD_FMT		".data2 %ld\n"
+#define	LONG_FMT  		".data4 %ld\n"
+#define	BSS_FMT			".space %ld\n"
+
+#define	SEGTXT_FMT  		".sect .text\n"
+#define	SEGDAT_FMT		".sect .data\n"
+#define	SEGBSS_FMT		".sect .bss\n"
+
+#define	SYMBOL_DEF_FMT		"%s :\n"
+#define	GLOBAL_FMT		".extern %s\n"
+#define	LOCAL_FMT		""
+
+#define	RELOC1_FMT		".data1 %s + %ld\n"
+#define	RELOC2_FMT		".data2 %s + %ld\n"
+#define	RELOC4_FMT		".data4 %s + %ld\n"
+
+
+
+
+#define small( x)	( 1 <= (x) && (x) <= 8)

+ 45 - 0
mach/sun3/ce/misc.c

@@ -0,0 +1,45 @@
+#include <system.h>
+#include "mach.h"
+#include "back.h"
+
+/* The following functions are called from reloc1(), reloc2(), reloc4(),
+ * dump_label().
+ */
+
+align_word()
+
+/* Do word allignment.
+ */
+{
+	switch ( cur_seg) {	
+		case SEGTXT : return;
+		case SEGCON : if ( (data - data_area) % 2 != 0) 
+					con1( '\0');
+			      return;
+		case SEGROM : if ( (data - data_area) % 2 != 0) 
+					rom1( '\0');
+			      return;
+		case SEGBSS : if ( nbss % 2 != 0) 
+					nbss++;
+			      return;
+		default     : fprint( STDERR, "align_word() : unknown seg\n");
+			      return;
+	}
+}
+
+
+long cur_value()
+
+/* Return the index of the first free entry.
+ */
+{
+	switch( cur_seg) {
+		case SEGTXT: return text - text_area;
+		case SEGCON: return data - data_area;
+		case SEGROM: return data - data_area;
+		case SEGBSS: return nbss;
+		default    : fprint( STDERR, "cur_value() : unknown seg\n");
+			     return -1L;
+	}
+}
+

+ 225 - 0
mach/sun3/ce/output.c

@@ -0,0 +1,225 @@
+#include <system.h>
+#include <em.h>
+#include <out.h>
+#include "mach.h"
+#include "back.h"
+#include "data.h"
+
+/*	Unportable code. Written for SUN, meant to be run on a SUN.
+*/
+#ifndef sun
+Read above comment ...
+#endif
+
+extern File *out_file;
+
+#include <a.out.h>
+#include <alloc.h>
+
+struct exec u_header;
+
+long ntext, ndata, nrelo, nchar, base_address();
+int trsize=0, drsize=0;
+
+output()
+{
+	register int i;
+	struct relocation_info *u_reloc;
+	struct nlist *u_name;
+
+	/*
+	 * first, convert relocation data structures. This also requires
+	 * some re-ordering, as SUN .o format needs has text relocation
+	 * structures in front of the data relocation structures, whereas in
+	 * ACK they can be in any order.
+	 */
+
+	nrelo = relo - reloc_info;
+	u_reloc = (struct relocation_info *)
+			Malloc((unsigned)nrelo*sizeof(struct relocation_info));
+
+	for (i = 0; i < nrelo; i++) {
+		if (  ( reloc_info[i].or_sect-S_MIN) == SEGTXT) {
+			convert_reloc( &reloc_info[i], u_reloc++);
+			trsize++;
+		}
+	}
+	for (i = 0; i < nrelo; i++) {
+		if (  ( reloc_info[i].or_sect-S_MIN) != SEGTXT) {
+			convert_reloc( &reloc_info[i], u_reloc++);
+			drsize++;
+		}
+	}
+
+	u_reloc -= nrelo;
+
+	init_unixheader();
+
+	putbuf( (char *) &u_header, sizeof(struct exec));
+	putbuf( (char *) text_area,  ntext);
+	putbuf( (char *) data_area, ndata);
+	putbuf((char *) u_reloc, sizeof(struct relocation_info)*nrelo);
+	free(u_reloc);
+	
+	u_name = (struct nlist *)
+			Malloc((unsigned)nname * sizeof(struct nlist));
+
+	for (i = 0; i < nname ; i++) { /* The segment names can be omitted */
+		convert_name( &symbol_table[i], u_name++);
+	}
+	u_name -= nname;
+	putbuf((char *) u_name, sizeof(struct nlist)*nname);
+	free(u_name);
+
+	/* print( "size string_area %d\n", nchar); */
+
+	put_stringtablesize( nchar + 4);
+	putbuf((char *) string_area, nchar);
+}
+
+
+init_unixheader()
+{
+	ntext = text - text_area;
+	ndata = data - data_area;
+	nchar = string - string_area;
+
+	u_header.a_magic = OMAGIC;
+	u_header.a_machtype = M_68020;
+	u_header.a_text = ntext;
+	u_header.a_data = ndata;
+	u_header.a_bss = nbss;
+	u_header.a_syms = nname * sizeof(struct nlist);
+	u_header.a_entry = 0;
+	u_header.a_trsize = trsize * sizeof(struct relocation_info);
+  	u_header.a_drsize = drsize * sizeof(struct relocation_info);
+	/* print( "header %o %d %d %d %d %d %d %d\n",
+		u_header.a_magic, u_header.a_text, u_header.a_data,
+		u_header.a_bss, u_header.a_syms, u_header.a_entry,
+		u_header.a_trsize, u_header.a_drsize);
+	 */
+}
+
+convert_reloc( a_relo, u_relo)
+struct outrelo *a_relo;
+struct relocation_info *u_relo;
+{
+	u_relo->r_address = a_relo->or_addr;
+	u_relo->r_symbolnum = a_relo->or_nami;
+	u_relo->r_pcrel = (a_relo->or_type & RELPC) >> 3;
+	u_relo->r_length = 2;
+	if ( symbol_table[ a_relo->or_nami].on_valu == -1 ||
+	     (symbol_table[ a_relo->or_nami].on_type & S_COM)) 
+		u_relo->r_extern = 1;
+	else  
+		u_relo->r_extern = 0;
+	if ( u_relo->r_extern == 0) {
+		switch ( (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN) {
+			case SEGTXT : u_relo->r_symbolnum = N_TEXT;
+				      break;
+			case SEGCON : u_relo->r_symbolnum = N_DATA;
+				      break;
+			case SEGBSS : u_relo->r_symbolnum = N_BSS;
+				      break;
+			default : fprint( STDERR, 
+					   "convert_relo(): bad segment %d\n",
+			    (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN);
+		}
+	}
+}
+
+
+/*
+int convert_length( length)
+int length;
+{
+	if ( length & RELO1)
+		return( 0);
+	else if ( length & RELO2)
+		return( 1);
+	else if ( length & RELO4)
+		return( 2);
+	else
+		fprint( STDERR, "convert_length(): size is impossible %d\n",
+			length);
+}
+*/
+
+#define 	n_mptr 		n_un.n_name
+#define 	n_str		n_un.n_strx
+
+
+convert_name( a_name, u_name)
+struct outname *a_name;
+struct nlist *u_name;
+{
+	/* print( "naam is %s\n", a_name->on_foff + string_area);   */
+
+	u_name->n_str = a_name->on_foff + 4;
+	fill_type( &(u_name->n_type), &(a_name->on_type), a_name->on_valu);
+	u_name->n_other = '\0';
+	u_name->n_desc = 0;
+	if (a_name->on_type & S_COM) 
+		u_name->n_value = a_name->on_valu;
+	else if ( a_name->on_valu != -1)
+		u_name->n_value = a_name->on_valu + 
+			base_address( ( a_name->on_type & S_TYP) - S_MIN);
+	else 
+		 u_name->n_value = 0;
+}
+
+
+fill_type( u_type, a_type, valu)
+unsigned char *u_type;
+ushort *a_type;
+long valu; 
+{
+	int sect;
+
+	*u_type = '\0';
+	*u_type |= ( *a_type & S_EXT) ? N_EXT : N_UNDF;
+
+	if ( valu != -1 && (! (*a_type & S_COM))) {
+		sect = ( *a_type & S_TYP ) - S_MIN;
+		switch ( sect) {
+			case SEGTXT: *u_type |= N_TEXT;
+			      	     break;
+			case SEGCON : *u_type |= N_DATA;
+			              break;
+			case SEGBSS : *u_type |= N_BSS;
+			              break;
+			default: fprint(STDERR, 
+					"fill_type() : bad section %d\n", sect);
+		}
+	}
+}
+
+
+long base_address( seg)
+int seg;
+{
+	switch ( seg) {
+		case SEGTXT : return( 0);
+			      break;
+		case SEGCON : return( text - text_area);
+			      break;
+		case SEGBSS : return( text - text_area + data - data_area);
+			      break;
+		default : fprint( STDERR,
+			"base_adres() : bad section %d\n", seg);
+	}
+}
+
+put_stringtablesize( n)
+long n;
+{
+	putbuf( (char *)&n, 4L);
+}
+
+
+putbuf(buf,n)
+char *buf;
+long n;
+{
+	sys_write( out_file, buf, n);
+}

+ 67 - 0
mach/sun3/ce/relocation.c

@@ -0,0 +1,67 @@
+#include <system.h>
+#include <out.h>
+#include "data.h"
+#include "back.h"
+
+long 		get4(); 
+extern long 	base_address();
+extern short    get2();
+extern char 	get1();
+
+static do_relo();
+
+do_local_relocation()
+{
+	register struct outrelo *ptr;
+	register int s;
+	
+	/* print( "n relocation records %d\n", relo - reloc_info);  */
+
+	for ( ptr = reloc_info; ptr < relo; ptr++) {
+		s = ptr->or_nami;
+		if ( symbol_table[ s].on_valu  != -1 &&
+		     ! (symbol_table[s].on_type & S_COM)) 
+			do_relo(&symbol_table[ s], ptr);
+	}
+}
+
+
+static
+do_relo(np,rp)
+struct outname *np;
+struct outrelo *rp;
+{
+	long oldval,newval;
+	char *sect;
+
+	switch( rp->or_sect - S_MIN) {
+		case SEGTXT:
+			sect = text_area;
+			break;
+		case SEGCON:
+			sect = data_area;
+			break;
+		default:
+			fprint( STDERR, 
+				"do_local_relo(): bad section %d\n",
+				 rp->or_sect - S_MIN);
+			break;
+	}
+	oldval = get4( sect, rp->or_addr);
+	newval = oldval + np->on_valu + 
+			base_address( (np->on_type & S_TYP) -S_MIN);	 
+	if  ( rp->or_type & RELO4) 
+		put4( sect, rp->or_addr, newval);
+	/*
+	else if  ( rp->or_type & RELO2) 
+		put2( sect, rp->or_addr, (int) newval);
+	else if  ( rp->or_type & RELO1) 
+		put1( sect, rp->or_addr, (char) newval);
+	*/
+	else
+		print( STDERR, "do_relo() : bad relocation size\n");
+	/* print( "reloc %s adrr=%ld sect=%ld oldval=%ld newval=%ld def = %ld\n",
+np->on_foff + string_area, rp->or_addr, rp->or_sect-S_MIN, oldval, newval, 
+np->on_valu);
+	 */
+}