From: ceriel Date: Thu, 18 Aug 1988 14:33:57 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~2913 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=a1684f6d0bd6be581e51669f2c842aeacaa69501;p=ack.git Initial revision --- diff --git a/mach/m68020/ce/.distr b/mach/m68020/ce/.distr new file mode 100644 index 000000000..cc484247b --- /dev/null +++ b/mach/m68020/ce/.distr @@ -0,0 +1,6 @@ +as_table +mach.c +mach.h +as.c +as.h +EM_table diff --git a/mach/m68020/ce/EM_table b/mach/m68020/ce/EM_table new file mode 100644 index 000000000..104788cc9 --- /dev/null +++ b/mach/m68020/ce/EM_table @@ -0,0 +1,804 @@ +#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 ::= C_cal( "adf4"); + C_asp( (arith) 4). + $1 == 8 ::= C_cal( "adf8"); + C_asp( (arith) 8). + default ==> arg_error( "adf", $1). + +C_sbf + $1 == 4 ::= C_cal( "sbf4"); + C_asp( (arith) 4). + $1 == 8 ::= C_cal( "sbf8"); + C_asp( (arith) 8). + default ==> arg_error( "sbf", $1). + +C_mlf + $1 == 4 ::= C_cal( "mlf4"); + C_asp( (arith) 4). + $1 == 8 ::= C_cal( "mlf8"); + C_asp( (arith) 8). + default ==> arg_error( "mlf", $1). + +C_dvf + $1 == 4 ::= C_cal( "dvf4"); + C_asp( (arith) 4). + $1 == 8 ::= C_cal( "dvf8"); + C_asp( (arith) 8). + default ==> arg_error( "dvf", $1). + +C_ngf + $1 == 4 ::= C_cal( "ngf4"). + $1 == 8 ::= C_cal( "ngf8"). + default ==> arg_error( "ngf", $1). + +C_fif + $1 == 4 ::= C_cal( "fif4"). + $1 == 8 ::= C_cal( "fif8"). + default ==> arg_error( "fif", $1). + +C_fef + $1 == 4 ::= C_dup( (arith) 4); + C_cal( "fef4"). + $1 == 8 ::= "move.l (sp)+, d0"; + "move.l (sp)+, d1"; + "move.l d0, -(sp)"; + "move.l d1, -(sp)"; + "move.l d0, -(sp)"; + C_cal( "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 ==> "jsr (.cuu) ". + +C_ciu ::= C_cuu(). + +C_cui ::= C_cuu(). + +/******************************************************************************/ +/* */ +/* 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:". + +/******************************************************************************/ +/* */ +/* 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). + +/*****************************************************************************/ + +prolog ==> . + +jump ==> "jmp $1". + +locals ==> "link a6, #-$1". diff --git a/mach/m68020/ce/as.c b/mach/m68020/ce/as.c new file mode 100644 index 000000000..abf819fe0 --- /dev/null +++ b/mach/m68020/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/m68020/ce/as.h b/mach/m68020/ce/as.h new file mode 100644 index 000000000..03c00d36f --- /dev/null +++ b/mach/m68020/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/m68020/ce/as_table b/mach/m68020/ce/as_table new file mode 100644 index 000000000..91a7c5ff9 --- /dev/null +++ b/mach/m68020/ce/as_table @@ -0,0 +1,165 @@ +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). + +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/m68020/ce/mach.c b/mach/m68020/ce/mach.c new file mode 100644 index 000000000..67340514e --- /dev/null +++ b/mach/m68020/ce/mach.c @@ -0,0 +1,24 @@ +#include "mach.h" +#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); +} +*/ diff --git a/mach/m68020/ce/mach.h b/mach/m68020/ce/mach.h new file mode 100644 index 000000000..f90811c25 --- /dev/null +++ b/mach/m68020/ce/mach.h @@ -0,0 +1,42 @@ +#define BYTES_REVERSED +#define WORDS_REVERSED + +#define ONE_BYTE char +#define TWO_BYTES short +#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%03d%ld" +#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)