From 6ae90c8f349b78ead9bb6297d451c5cf9fde69bb Mon Sep 17 00:00:00 2001 From: ceriel Date: Wed, 28 Sep 1988 16:47:47 +0000 Subject: [PATCH] Initial revision --- mach/sun3/ce/.distr | 15 + mach/sun3/ce/EM_table | 805 ++++++++++++++++++++++++++++++++++++++ mach/sun3/ce/Make.back | 106 +++++ mach/sun3/ce/Makefile | 16 + mach/sun3/ce/as.c | 352 +++++++++++++++++ mach/sun3/ce/as.h | 33 ++ mach/sun3/ce/as_table | 167 ++++++++ mach/sun3/ce/do_close.c | 8 + mach/sun3/ce/do_open.c | 13 + mach/sun3/ce/end_back.c | 24 ++ mach/sun3/ce/mach.c | 200 ++++++++++ mach/sun3/ce/mach.h | 42 ++ mach/sun3/ce/misc.c | 45 +++ mach/sun3/ce/output.c | 225 +++++++++++ mach/sun3/ce/relocation.c | 67 ++++ 15 files changed, 2118 insertions(+) create mode 100644 mach/sun3/ce/.distr create mode 100644 mach/sun3/ce/EM_table create mode 100644 mach/sun3/ce/Make.back create mode 100644 mach/sun3/ce/Makefile create mode 100644 mach/sun3/ce/as.c create mode 100644 mach/sun3/ce/as.h create mode 100644 mach/sun3/ce/as_table create mode 100644 mach/sun3/ce/do_close.c create mode 100644 mach/sun3/ce/do_open.c create mode 100644 mach/sun3/ce/end_back.c create mode 100644 mach/sun3/ce/mach.c create mode 100644 mach/sun3/ce/mach.h create mode 100644 mach/sun3/ce/misc.c create mode 100644 mach/sun3/ce/output.c create mode 100644 mach/sun3/ce/relocation.c diff --git a/mach/sun3/ce/.distr b/mach/sun3/ce/.distr new file mode 100644 index 000000000..fc9ec50b4 --- /dev/null +++ b/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 diff --git a/mach/sun3/ce/EM_table b/mach/sun3/ce/EM_table new file mode 100644 index 000000000..5b47fe27d --- /dev/null +++ b/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". diff --git a/mach/sun3/ce/Make.back b/mach/sun3/ce/Make.back new file mode 100644 index 000000000..ef46d185f --- /dev/null +++ b/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 diff --git a/mach/sun3/ce/Makefile b/mach/sun3/ce/Makefile new file mode 100644 index 000000000..7e6327508 --- /dev/null +++ b/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 diff --git a/mach/sun3/ce/as.c b/mach/sun3/ce/as.c new file mode 100644 index 000000000..abf819fe0 --- /dev/null +++ b/mach/sun3/ce/as.c @@ -0,0 +1,352 @@ +#include +#include +#include +#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); +} diff --git a/mach/sun3/ce/as.h b/mach/sun3/ce/as.h new file mode 100644 index 000000000..03c00d36f --- /dev/null +++ b/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) diff --git a/mach/sun3/ce/as_table b/mach/sun3/ce/as_table new file mode 100644 index 000000000..0f45b0659 --- /dev/null +++ b/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)). diff --git a/mach/sun3/ce/do_close.c b/mach/sun3/ce/do_close.c new file mode 100644 index 000000000..a9f3721de --- /dev/null +++ b/mach/sun3/ce/do_close.c @@ -0,0 +1,8 @@ +#include + +extern File *out_file; + +close_back() +{ + sys_close( out_file); +} diff --git a/mach/sun3/ce/do_open.c b/mach/sun3/ce/do_open.c new file mode 100644 index 000000000..337fc6253 --- /dev/null +++ b/mach/sun3/ce/do_open.c @@ -0,0 +1,13 @@ +#include + +File *out_file; + +open_back( filename) +char *filename; +{ + if ( filename == (char *) '\0') + return( 0); + else + return( sys_open( filename, OP_WRITE, &out_file)); +} + diff --git a/mach/sun3/ce/end_back.c b/mach/sun3/ce/end_back.c new file mode 100644 index 000000000..f776e41ad --- /dev/null +++ b/mach/sun3/ce/end_back.c @@ -0,0 +1,24 @@ +#include +#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'); +} diff --git a/mach/sun3/ce/mach.c b/mach/sun3/ce/mach.c new file mode 100644 index 000000000..eee6575ce --- /dev/null +++ b/mach/sun3/ce/mach.c @@ -0,0 +1,200 @@ +#include "mach.h" +#include +#include +#include + + +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 + +#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 diff --git a/mach/sun3/ce/mach.h b/mach/sun3/ce/mach.h new file mode 100644 index 000000000..f9091c4c8 --- /dev/null +++ b/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) diff --git a/mach/sun3/ce/misc.c b/mach/sun3/ce/misc.c new file mode 100644 index 000000000..10eced7e6 --- /dev/null +++ b/mach/sun3/ce/misc.c @@ -0,0 +1,45 @@ +#include +#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; + } +} + diff --git a/mach/sun3/ce/output.c b/mach/sun3/ce/output.c new file mode 100644 index 000000000..c960e75cc --- /dev/null +++ b/mach/sun3/ce/output.c @@ -0,0 +1,225 @@ +#include +#include +#include +#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 +#include + +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); +} diff --git a/mach/sun3/ce/relocation.c b/mach/sun3/ce/relocation.c new file mode 100644 index 000000000..f1c41a6d9 --- /dev/null +++ b/mach/sun3/ce/relocation.c @@ -0,0 +1,67 @@ +#include +#include +#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); + */ +} -- 2.34.1