--- /dev/null
+#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".
--- /dev/null
+#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);
+}
--- /dev/null
+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)).