--- /dev/null
+EM_table
+as.c
+as.h
+as_table
+mach.c
+mach.h
--- /dev/null
+#define PUSH_POP_OPT TRUE
+
+/******************************************************************************/
+/* */
+/* Group 1 : load instructions */
+/* */
+/******************************************************************************/
+
+C_loc ==> "mov ax, $1";
+ "push ax".
+
+C_ldc ==> C_loc( $1>>16);
+ C_loc( $1).
+
+C_lol ==> "push $1(bp)".
+
+C_loe.. ==> "push ($1+$2)".
+
+C_lil ==> "mov bx, $1(bp)";
+ "push (bx)".
+
+C_lof ==> "pop bx";
+ "push $1(bx)".
+
+C_lal ==> "lea ax, $1(bp)";
+ "push ax".
+
+C_lae.. ==> "mov ax, $1+$2";
+ "push ax".
+
+C_lxl
+ $1 == 0 ==> "push bp".
+
+ $1 == 1 ==> "push 4(bp)".
+
+ default ==> "mov cx, $1-1";
+ "mov bx, 4(bp)";
+ "1: mov bx, 4(bx)";
+ "loop 1b";
+ "push bx".
+
+C_lxa
+ $1 == 0 ==> "lea ax, 4(bp)";
+ "push ax".
+
+ $1 == 1 ==> "mov ax, 4(bp)";
+ "add ax, 4";
+ "push ax".
+
+ default ==> "mov cx, $1-1";
+ "mov bx, 4(bp)";
+ "1: mov bx, 4(bx)";
+ "loop 1b";
+ "add bx, 4";
+ "push bx".
+
+C_loi
+ $1 == 1 ==> "pop bx";
+ "xor ax, ax";
+ "movb al, (bx)";
+ "push ax".
+
+ $1 == 2 ==> "pop bx";
+ "push (bx)".
+
+ $1 == 4 ==> "pop bx";
+ "push 2(bx)";
+ "push (bx)".
+
+ default ==> "pop bx";
+ "mov cx, $1";
+ "call .loi".
+
+C_los
+ $1 == 2 ==> "pop cx";
+ "pop bx";
+ "call .loi".
+
+ default ==> arg_error( "C_los", $1).
+
+C_los_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop cx";
+ "pop bx";
+ "call .loi".
+
+C_ldl ==> "push $1+2(bp)";
+ "push $1(bp)".
+
+C_lde.. ==> "push ($1+$2+2)";
+ "push ($1+$2)".
+
+C_ldf ==> "pop bx";
+ "push $1+2(bx)";
+ "push $1(bx)".
+
+C_lpi ==> "mov ax, $1";
+ "push ax".
+
+/******************************************************************************/
+/* */
+/* Group 2 : store instructions */
+/* */
+/******************************************************************************/
+
+C_stl ==> "pop $1(bp)".
+
+C_ste.. ==> "pop ($1+$2)".
+
+C_sil ==> "mov bx, $1(bp)";
+ "pop (bx)".
+
+C_stf ==> "pop bx";
+ "pop $1(bx)".
+
+C_sti
+ $1 == 1 ==> "pop bx";
+ "pop ax";
+ "movb (bx), al".
+
+ $1 == 2 ==> "pop bx";
+ "pop (bx)".
+
+ $1 == 4 ==> "pop bx";
+ "pop (bx)";
+ "pop 2(bx)".
+
+ default ==> "pop bx";
+ "mov cx, $1";
+ "call .sti".
+
+C_sts
+ $1 == 2 ==> "pop cx";
+ "pop bx";
+ "call .sti".
+
+ default ==> arg_error( "C_sts", $1).
+
+C_sts_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop cx";
+ "pop bx";
+ "call .sti".
+
+C_sdl ==> "pop $1(bp)";
+ "pop $1+2(bp)".
+
+C_sde.. ==> "pop ($1+$2)";
+ "pop ($1+$2+2)".
+
+C_sdf ==> "pop bx";
+ "pop $1(bx)";
+ "pop $1+2(bx)".
+
+/******************************************************************************/
+/* */
+/* Group 3 : integer arithmetic */
+/* */
+/******************************************************************************/
+
+C_adi
+ $1 == 2 ==> "pop ax";
+ "pop bx";
+ "add ax, bx";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "pop cx";
+ "pop dx";
+ "add ax, cx";
+ "adc bx, dx";
+ "push bx";
+ "push ax".
+
+ default ==> "pop ax";
+ "mov cx, $1";
+ "call .adi";
+ "push ax".
+
+C_adi_narg ==> "pop cx";
+ "pop ax";
+ "call .adi";
+ "push ax".
+
+C_sbi
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "sub ax, bx";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "pop cx";
+ "pop dx";
+ "sub cx, ax";
+ "sbb dx, bx";
+ "push dx";
+ "push cx".
+
+ default ==> "pop ax";
+ "mov cx, $1";
+ "call .sbi";
+ "push ax".
+
+C_sbi_narg ==> "pop cx";
+ "pop ax";
+ "call .sbi";
+ "push ax".
+
+C_mli
+ $1 == 2 ==> "pop ax";
+ "pop bx";
+ "mul bx";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop dx";
+ "call .mli4";
+ "push dx";
+ "push ax".
+
+ default ==> arg_error( "C_mli", $1).
+
+C_mli_narg ==> "pop ax";
+ "call .mli".
+
+C_dvi
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "cwd";
+ "idiv bx";
+ "push ax".
+
+ $1 == 4 ==> "call .dvi4";
+ "push dx";
+ "push ax".
+
+ default ==> arg_error( "C_dvi", $1).
+
+C_dvi_narg ==> "pop ax";
+ "call .dvi".
+
+C_rmi
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "cwd";
+ "idiv bx";
+ "push dx".
+
+ $1 == 4 ==> "call .rmi4";
+ "push dx";
+ "push ax".
+
+ default ==> arg_error( "C_rmi", $1).
+
+C_rmi_narg ==> "pop ax";
+ "call .rmi".
+
+C_ngi
+ $1 == 2 ==> "pop ax";
+ "neg ax";
+ "push ax".
+
+ $1 == 4 ==> "pop bx";
+ "pop ax";
+ "neg ax";
+ "neg bx";
+ "sbb ax, 0";
+ "push ax";
+ "push bx".
+
+ default ==> "mov ax, $1";
+ "call .ngi".
+
+C_ngi_narg ==> "pop ax";
+ "call .ngi".
+
+C_sli
+ $1 == 2 ==> "pop cx";
+ "pop ax";
+ "sal ax, cl";
+ "push ax".
+
+ default ==> "mov ax, $1";
+ "call .sli".
+
+C_sli_narg ==> "pop ax";
+ "call .sli".
+
+C_sri
+ $1 == 2 ==> "pop cx";
+ "pop ax";
+ "sar ax, cl";
+ "push ax".
+
+ default ==> "mov ax, $1";
+ "call .sri".
+
+C_sri_narg ==> "pop ax";
+ "call .sri".
+
+/******************************************************************************/
+/* */
+/* Group 4 : Unsigned arithmetic */
+/* */
+/******************************************************************************/
+
+C_adu ==> C_adi( $1).
+
+C_adu_narg ==> C_adi_narg().
+
+C_sbu ==> C_sbi( $1).
+
+C_sbu_narg ==> C_sbi_narg().
+
+C_mlu ==> C_mli( $1).
+
+C_mlu_narg ==> C_mli_narg().
+
+C_dvu
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "xor dx, dx";
+ "div bx";
+ "push ax".
+
+ $1 == 4 ==> "call .dvu4";
+ "push dx";
+ "push ax".
+
+ default ==> "mov ax, $1";
+ "call .dvu".
+
+C_dvu_narg ==> "pop ax";
+ "call .dvu".
+
+C_rmu
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "xor dx, dx";
+ "div bx";
+ "push dx".
+
+ $1 == 4 ==> "call .dvu4";
+ "push dx";
+ "push ax".
+
+ default ==> "mov ax, $1";
+ "call .rmu".
+
+C_rmu_narg ==> "pop ax";
+ "call .rmu".
+
+C_slu ==> C_sli( $1).
+
+C_slu_narg ==> C_sli_narg().
+
+C_sru
+ $1 == 2 ==> "pop cx";
+ "pop ax";
+ "shr ax, cl";
+ "push ax".
+
+ $1 == 4 ==> "pop cx";
+ "pop bx";
+ "pop ax";
+ "1 : shr ax, 1";
+ "rcr bx, 1";
+ "loop 1b";
+ "push ax";
+ "push bx".
+
+ default ==> arg_error( "C_sru", $1).
+
+/******************************************************************************/
+/* */
+/* Group 5 : Floating point arithmetic */
+/* */
+/******************************************************************************/
+
+/******************************************************************************/
+/* */
+/* Group 6 : Pointer arithmetic */
+/* */
+/******************************************************************************/
+
+C_adp
+
+#ifndef PEEPHOLE_OPT
+ $1 == 0 ==> .
+#endif
+
+ $1 == 1 ==> "pop ax";
+ "inc ax";
+ "push ax".
+
+ $1 == -1 ==> "pop ax";
+ "dec ax";
+ "push ax".
+
+ default ==> "pop ax";
+ "add ax, $1";
+ "push ax".
+
+C_ads
+ $1 == 2 ==> "pop ax";
+ "pop bx";
+ "add ax, bx";
+ "push ax".
+
+ default ==> arg_error( "C_ads", $1).
+
+C_ads_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop ax";
+ "pop bx";
+ "add ax, bx";
+ "push ax".
+
+C_sbs
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "sub ax, bx";
+ "push ax".
+
+ default ==> arg_error( "C_sbs", $1).
+
+C_sbs_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop bx";
+ "pop ax";
+ "sub ax, bx";
+ "push ax".
+
+/******************************************************************************/
+/* */
+/* Group 7 : Increment/decrement/zero */
+/* */
+/******************************************************************************/
+
+C_inc ==> "pop ax";
+ "inc ax";
+ "push ax".
+
+C_inl ==> "inc $1(bp)".
+
+C_ine.. ==> "inc ($1+$2)".
+
+C_dec ==> "pop ax";
+ "dec ax";
+ "push ax".
+
+C_del ==> "dec $1(bp)".
+
+C_dee.. ==> "dec ($1+$2)".
+
+C_zrl ==> "mov $1(bp), 0".
+
+C_zre.. ==> "mov ($1+$2), 0".
+
+C_zer
+ $1 == 2 ==> "xor ax, ax";
+ "push ax".
+
+ $1 == 4 ==> "xor ax, ax";
+ "push ax";
+ "push ax".
+
+ $1 == 6 ==> "xor ax, ax";
+ "push ax";
+ "push ax";
+ "push ax".
+
+ $1 == 8 ==> "xor ax, ax";
+ "push ax";
+ "push ax";
+ "push ax";
+ "push ax".
+
+ $1 % 2 == 0 ==> "mov cx, $1/2";
+ "xor ax, ax";
+ "1: push ax";
+ "loop 1b".
+
+ default ==> arg_error( "C_zer", $1).
+
+C_zer_narg ==> "pop cx";
+ "sar cx, 1";
+ "xor ax, ax";
+ "1: push ax";
+ "loop 1b".
+
+/******************************************************************************/
+/* */
+/* Group 8 : Convert */
+/* */
+/******************************************************************************/
+
+C_cii ==> "pop cx";
+ "pop dx";
+ "pop ax";
+ "call .cii";
+ "push ax".
+
+C_cui ==> C_cuu().
+
+C_ciu ==> C_cuu().
+
+C_cuu ==> "pop cx";
+ "pop dx";
+ "pop ax";
+ "call .cuu";
+ "push ax".
+
+/******************************************************************************/
+/* */
+/* Group 9 : Logical */
+/* */
+/******************************************************************************/
+
+C_and
+ $1 == 2 ==> "pop ax";
+ "pop bx";
+ "and ax, bx";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "pop cx";
+ "pop dx";
+ "and ax, cx";
+ "and bx, dx";
+ "push bx";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .and".
+
+C_and_narg ==> "pop cx";
+ "call .and".
+
+C_ior
+ $1 == 2 ==> "pop ax";
+ "pop bx";
+ "or ax, bx";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "pop cx";
+ "pop dx";
+ "or ax, cx";
+ "or bx, dx";
+ "push bx";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .ior".
+
+C_ior_narg ==> "pop cx";
+ "call .ior".
+
+C_xor
+ $1 == 2 ==> "pop ax";
+ "pop bx";
+ "xor ax, bx";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "pop cx";
+ "pop dx";
+ "xor ax, cx";
+ "xor bx, dx";
+ "push bx";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .xor".
+
+C_xor_narg ==> "pop cx";
+ "call .xor".
+
+C_com
+ $1 == 2 ==> "pop ax";
+ "not ax";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "not ax";
+ "not bx";
+ "push bx";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .com".
+
+C_com_narg ==> "pop cx";
+ "call .com".
+
+C_rol
+ $1 == 2 ==> "pop cx";
+ "pop ax";
+ "rol ax, cl";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .rol".
+
+C_rol_narg ==> "pop cx";
+ "call .rol".
+
+C_ror
+ $1 == 2 ==> "pop cx";
+ "pop ax";
+ "ror ax, cl";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .ror".
+
+C_ror_narg ==> "pop cx";
+ "call .ror".
+
+/******************************************************************************/
+/* */
+/* Group 10 : Sets */
+/* */
+/******************************************************************************/
+
+C_inn
+ $1 == 2 ==> "pop cx";
+ "pop ax";
+ "shr ax, cl";
+ "and ax, 1";
+ "push ax".
+
+ default ==> "pop ax";
+ "mov cx, $1";
+ "call .inn";
+ "push ax".
+
+C_inn_narg ==> "pop cx";
+ "pop ax";
+ "call .inn";
+ "push ax".
+
+C_set
+ $1 == 2 ==> "pop cx";
+ "mov ax, 1";
+ "shl ax, cl";
+ "push ax".
+
+ default ==> "pop ax";
+ "mov cx, $1";
+ "call .set".
+
+C_set_narg ==> "pop cx";
+ "pop ax";
+ "call .set".
+
+/******************************************************************************/
+/* */
+/* Group 11 : Array */
+/* */
+/******************************************************************************/
+
+C_lar
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "call .lar2".
+
+ default ==> arg_error( "C_lar", $1).
+
+C_lar_narg ==> "call .ilar".
+
+C_sar
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "call .sar2".
+
+ default ==> arg_error( "C_sar", $1).
+
+C_sar_narg ==> "call .isar".
+
+C_aar
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "pop cx";
+ "sub ax, (bx)";
+ "mul 4(bx)";
+ "add ax, cx";
+ "push ax".
+
+ default ==> arg_error( "C_aar", $1).
+
+C_aar_narg ==> "call .iaar";
+ "push bx".
+
+/******************************************************************************/
+/* */
+/* Group 12 : Compare */
+/* */
+/******************************************************************************/
+
+C_cmi
+ $1 == 2 ==> /* bug : C_sbi( (arith) 2). */
+ "pop bx";
+ "pop cx";
+ "xor ax, ax";
+ "cmp cx, bx";
+ "je 2f";
+ "jl 1f";
+ "inc ax";
+ "jmp 2f";
+ "1: dec ax";
+ "2: push ax".
+
+ $1 == 4 ==> "call .cmi4";
+ "push ax".
+
+ default ==> arg_error( "C_cmi", $1).
+
+C_cmu
+ $1 == 2 ==> C_cmp().
+
+ $1 == 4 ==> "call .cmu4";
+ "push ax".
+
+ default ==> arg_error( "C_cmu", $1).
+
+C_cms
+ $1 == 2 ==> C_sbi( (arith) 2).
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "pop cx";
+ "pop dx";
+ "sub cx, ax";
+ "sbb dx, bx";
+ "jne 1f";
+ "or dx, cx";
+ "1: push dx".
+
+ default ==> "mov cx, $1";
+ "call .cms";
+ "push cx".
+
+C_cms_narg ==> "pop cx";
+ "call .cms";
+ "push cx".
+
+C_cmp ==> "pop bx";
+ "pop cx";
+ "xor ax, ax";
+ "cmp cx, bx";
+ "je 2f";
+ "jb 1f";
+ "inc ax";
+ "jmp 2f";
+ "1: dec ax";
+ "2: push ax".
+
+C_tlt ==> "pop ax";
+ "xor bx, bx";
+ "test ax, ax";
+ "jge 1f";
+ "inc bx";
+ "1: push bx".
+
+C_tle ==> "pop ax";
+ "xor bx, bx";
+ "test ax, ax";
+ "jg 1f";
+ "inc bx";
+ "1: push bx".
+
+C_teq ==> "pop ax";
+ "xor bx, bx";
+ "test ax, ax";
+ "jne 1f";
+ "inc bx";
+ "1: push bx".
+
+C_tne ==> "pop ax";
+ "xor bx, bx";
+ "test ax, ax";
+ "je 1f";
+ "inc bx";
+ "1: push bx".
+
+C_tge ==> "pop ax";
+ "xor bx, bx";
+ "test ax, ax";
+ "jl 1f";
+ "inc bx";
+ "1: push bx".
+
+C_tgt ==> "pop ax";
+ "xor bx, bx";
+ "test ax, ax";
+ "jle 1f";
+ "inc bx";
+ "1: push bx".
+
+/******************************************************************************/
+/* */
+/* Group 13 : Branch */
+/* */
+/******************************************************************************/
+
+C_bra ==> "jmp $1".
+
+C_blt ==> "pop ax";
+ "pop bx";
+ "cmp bx, ax";
+ "jl $1".
+
+C_ble ==> "pop ax";
+ "pop bx";
+ "cmp bx, ax";
+ "jle $1".
+
+C_beq ==> "pop ax";
+ "pop bx";
+ "cmp bx, ax";
+ "je $1".
+
+C_bne ==> "pop ax";
+ "pop bx";
+ "cmp bx, ax";
+ "jne $1".
+
+C_bge ==> "pop ax";
+ "pop bx";
+ "cmp bx, ax";
+ "jge $1".
+
+C_bgt ==> "pop ax";
+ "pop bx";
+ "cmp bx, ax";
+ "jg $1".
+
+C_zlt ==> "pop ax";
+ "test ax, ax";
+ "jl $1".
+
+C_zle ==> "pop ax";
+ "test ax, ax";
+ "jle $1".
+
+C_zeq ==> "pop ax";
+ "test ax, ax";
+ "je $1".
+
+C_zne ==> "pop ax";
+ "test ax, ax";
+ "jne $1".
+
+C_zge ==> "pop ax";
+ "test ax, ax";
+ "jge $1".
+
+C_zgt ==> "pop ax";
+ "test ax, ax";
+ "jg $1".
+
+/******************************************************************************/
+/* */
+/* Group 14 : Procedure call instructions */
+/* */
+/******************************************************************************/
+
+C_cai ==> "pop bx";
+ "call bx".
+
+C_cal ==> "call $1".
+
+C_lfr
+ $1 == 2 ==> "push ax".
+
+ $1 == 4 ==> "push dx";
+ "push ax".
+
+ $1 == 6 ==> "call .lfr6".
+
+ $1 == 8 ==> "call .lfr8".
+
+ default ==> arg_error( "C_lfr", $1).
+
+C_ret
+ $1 == 0 ==> "mov sp, bp";
+ "pop bp";
+ "ret".
+
+ $1 == 2 ==> "pop ax";
+ "mov sp, bp";
+ "pop bp";
+ "ret".
+
+ $1 == 4 ==> "pop ax";
+ "pop dx";
+ "mov sp, bp";
+ "pop bp";
+ "ret".
+
+ $1 == 6 ==> "call .ret6";
+ "mov sp, bp";
+ "pop bp";
+ "ret".
+
+ $1 == 8 ==> "call .ret8";
+ "mov sp, bp";
+ "pop bp";
+ "ret".
+
+ default ==> arg_error( "C_ret", $1).
+
+/******************************************************************************/
+/* */
+/* Group 15 : Miscellaneous instructions */
+/* */
+/******************************************************************************/
+
+C_asp
+ $1 == 2 ==> "pop bx".
+
+ $1 == 4 ==> "pop bx";
+ "pop bx".
+
+ $1 == -2 ==> "push ax".
+
+ default ==> "add sp, $1".
+
+C_ass
+ $1 == 2 ==> "pop ax";
+ "add sp, ax".
+
+ default ==> arg_error( "C_ass", $1).
+
+C_ass_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop ax";
+ "add sp, ax".
+
+C_blm
+ $1 % 2 == 0 ==> "mov cx, $1/2";
+ "call .blm".
+
+ default ==> arg_error( "C_blm", $1).
+
+C_bls
+ $1 == 2 ==> "pop cx";
+ "sar cx,1";
+ "call .blm".
+
+ default ==> arg_error( "C_bls", $1).
+
+C_bls_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop cx";
+ "sar cx, 1";
+ "call .blm".
+
+C_csa
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "jmp .csa2".
+
+ default ==> arg_error( "C_csa", $1).
+
+C_csa_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop bx";
+ "pop ax";
+ "jmp .csa2".
+
+C_csb
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "jmp .csb2".
+
+ default ==> arg_error( "C_csb", $1).
+
+C_csb_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop bx";
+ "pop ax";
+ "jmp .csb2".
+
+C_dch ==> "mov bp, (bp)".
+
+C_dup
+ $1 == 2 ==> "pop ax";
+ "push ax";
+ "push ax".
+
+ $1 == 4 ==> "pop ax";
+ "pop bx";
+ "push bx";
+ "push ax";
+ "push bx";
+ "push ax".
+
+ default ==> "mov cx, $1";
+ "call .dup".
+
+C_dus
+ $1 == 2 ==> "pop cx";
+ "call .dup".
+
+ default ==> arg_error( "C_dus", $1).
+
+C_dus_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop cx";
+ "call .dup".
+
+C_exg ==> "mov cx, $1";
+ "call .exg".
+
+C_exg_narg ==> "pop cx";
+ "call .exg".
+
+C_fil.. ==> "mov (hol0+4), $1+$2".
+
+C_gto.. ==> "mov bx, $1+$2";
+ "call .gto".
+
+C_lim ==> "push (.ignmask)".
+
+C_lin ==> "mov (hol0), $1".
+
+C_lni ==> "inc (hol0)".
+
+C_lor
+ $1 == 0 ==> "push bp".
+
+ $1 == 1 ==> "mov ax, sp";
+ "push ax".
+
+ $1 == 2 ==> "push (.reghp)".
+
+ default ==> arg_error( "C_lor", $1).
+
+C_lpb ==> "add bp, 4".
+
+C_mon ==> "pop ax";
+ "call .mon".
+
+C_nop ==> "call .nop".
+
+C_rck
+ $1 == 2 ==> "pop bx";
+ "pop ax";
+ "call .rck";
+ "push ax".
+
+ default ==> arg_error( "C_rck", $1).
+
+C_rck_narg ==> "pop ax";
+ "cmp ax, 2";
+ "jne .unknown";
+ "pop bx";
+ "pop ax";
+ "call .rck";
+ "push ax".
+
+
+C_rtt ==> C_ret( (arith) 0).
+
+C_sig ==> "pop ax";
+ "xchg (.trppc), ax";
+ "push ax".
+
+C_sim ==> "pop (.ignmask)".
+
+C_str
+ $1 == 0 ==> "pop bp".
+
+ $1 == 1 ==> "pop sp".
+
+ $1 == 2 ==> "pop (.reghp)".
+
+ default ==> arg_error( "C_str", $1).
+
+C_trp ==> "pop ax";
+ "call .trp".
+
+/******************************************************************************/
+/* */
+/* Storage-routines */
+/* */
+/******************************************************************************/
+
+
+..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", $1).
+
+..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( "..ucon", $1).
+
+/******************************************************************************/
+/* */
+/* Extra-routines */
+/* */
+/******************************************************************************/
+
+#ifdef PUSH_POP_OPT
+
+C_df_ilb ==> clean_push_buf();
+ symbol_definition( $1);
+ set_local_visible( $1).
+#endif
+
+jump ==> "jmp $1".
+
+prolog ==> "push bp";
+ "mov bp, sp".
+
+locals
+ $1 == 0 ==> .
+
+ $1 == 2 ==> "push ax".
+
+ $1 == 4 ==> "push ax";
+ "push ax".
+
+ default ==> "sub sp, $1".
--- /dev/null
+#include "arg_type.h"
+#include "as.h"
+
+static struct t_operand dummy = { IS_REG, AX, 0, 0, 0};
+struct t_operand saved_op, *AX_oper = &dummy;
+
+save_op( op)
+struct t_operand *op;
+{
+ saved_op.type = op->type;
+ saved_op.reg = op->reg;
+ saved_op.expr = op->expr;
+ saved_op.lab = op->lab;
+ saved_op.off = op->off;
+}
+
+#define last( s) ( s + strlen( s) - 1)
+#define LEFT '('
+#define RIGHT ')'
+#define DOLLAR '$'
+
+block_assemble( instr, nr, first, Last)
+char **instr;
+int nr, first, Last;
+{
+ int i;
+
+ if ( first) {
+ if( strncmp( instr[0], "pop", 3) == 0) {
+ *instr[0] = 'P';
+ *( instr[0]+1) = 'O';
+ *( instr[0]+2) = 'P';
+ }
+ else
+ @clean_push_buf();
+ }
+ if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
+ *instr[nr-1] = 'P';
+ *( instr[nr-1]+1) = 'U';
+ *( instr[nr-1]+2) = 'S';
+ *( instr[nr-1]+3) = 'H';
+ }
+
+ for( i=0; i<nr; i++)
+ assemble( instr[i]);
+}
+
+
+process_label( l)
+char *l;
+{
+}
+
+
+process_mnemonic( m)
+char *m;
+{
+}
+
+
+process_operand( str, op)
+char *str;
+struct t_operand *op;
+
+/* expr -> IS_DATA en IS_LABEL
+ * reg -> IS_REG en IS_ACCU
+ * (expr) -> IS_ADDR
+ * expr(reg) -> IS_MEM
+ */
+{
+ char *ptr, *index();
+
+ op->type = UNKNOWN;
+ if ( *last( str) == RIGHT) {
+ ptr = index( str, LEFT);
+ *last( str) = '\0';
+ *ptr = '\0';
+ if ( is_reg( ptr+1, op)) {
+ op->type = IS_MEM;
+ op->expr = ( *str == '\0' ? "0" : str);
+ }
+ else {
+ set_label( ptr+1, op);
+ op->type = IS_ADDR;
+ }
+ }
+ else
+ if ( is_reg( str, op))
+ op->type = IS_REG;
+ else {
+ if ( contains_label( str))
+ set_label( str, op);
+ else {
+ op->type = IS_DATA;
+ op->expr = str;
+ }
+ }
+}
+
+int is_reg( str, op)
+char *str;
+struct t_operand *op;
+{
+ if ( strlen( str) != 2)
+ return( 0);
+
+ switch ( *(str+1)) {
+ case 'x' :
+ case 'l' : switch( *str) {
+ case 'a' : op->reg = 0;
+ return( TRUE);
+
+ case 'c' : op->reg = 1;
+ return( TRUE);
+
+ case 'd' : op->reg = 2;
+ return( TRUE);
+
+ case 'b' : op->reg = 3;
+ return( TRUE);
+
+ default : return( FALSE);
+ }
+
+ case 'h' : switch( *str) {
+ case 'a' : op->reg = 4;
+ return( TRUE);
+
+ case 'c' : op->reg = 5;
+ return( TRUE);
+
+ case 'd' : op->reg = 6;
+ return( TRUE);
+
+ case 'b' : op->reg = 7;
+ return( TRUE);
+
+ default : return( FALSE);
+ }
+
+ case 'p' : switch ( *str) {
+ case 's' : op->reg = 4;
+ return( TRUE);
+
+ case 'b' : op->reg = 5;
+ return( TRUE);
+
+ default : return( FALSE);
+ }
+
+ case 'i' : switch ( *str) {
+ case 's' : op->reg = 6;
+ return( TRUE);
+
+ case 'd' : op->reg = 7;
+ return( TRUE);
+
+ default : return( FALSE);
+ }
+
+ default : return( FALSE);
+ }
+}
+
+#include <ctype.h>
+#define isletter( c) ( isalpha( c) || c == '_')
+
+int contains_label( str)
+char *str;
+{
+ while( !isletter( *str) && *str != '\0')
+ if ( *str == '$')
+ if ( arg_type( str) == STRING)
+ return( TRUE);
+ else
+ str += 2;
+ else
+ str++;
+
+ return( isletter( *str));
+}
+
+set_label( str, op)
+char *str;
+struct t_operand *op;
+{
+ char *ptr, *index(), *sprint();
+ static char buf[256];
+
+ ptr = index( str, '+');
+
+ if ( ptr == 0)
+ op->off = "0";
+ else {
+ *ptr = '\0';
+ op->off = ptr + 1;
+ }
+
+ if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
+ *(str+2) == '\0') {
+ *(str+1) = '\0'; /* b of f verwijderen! */
+ op->lab = str;
+ op->type = IS_ILB;
+ }
+ else {
+ op->type = IS_LABEL;
+ if ( index( str, DOLLAR) != 0)
+ op->lab = str;
+ else
+ /* nood oplossing */
+ op->lab = sprint( buf, "\"%s\"", str);
+ }
+}
+
+
+/******************************************************************************/
+
+
+
+mod_RM( reg, op)
+int reg;
+struct t_operand *op;
+{
+ if ( REG( op))
+ R233( 0x3, reg, op->reg);
+ else if ( ADDR( op)) {
+ R233( 0x0, reg, 0x6);
+ @reloc2( %$(op->lab), %$(op->off), ABSOLUTE);
+ }
+ else if ( strcmp( op->expr, "0") == 0)
+ switch( op->reg) {
+ case SI : R233( 0x0, reg, 0x4);
+ break;
+
+ case DI : R233( 0x0, reg, 0x5);
+ break;
+
+ case BP : R233( 0x1, reg, 0x6); /* Uitzondering! */
+ @text1( 0);
+ break;
+
+ case BX : R233( 0x0, reg, 0x7);
+ break;
+
+ default : fprint( STDERR, "Wrong index register %d\n",
+ op->reg);
+ }
+ else {
+ @if ( fit_byte( %$(op->expr)))
+ switch( op->reg) {
+ case SI : R233( 0x1, reg, 0x4);
+ break;
+
+ case DI : R233( 0x1, reg, 0x5);
+ break;
+
+ case BP : R233( 0x1, reg, 0x6);
+ break;
+
+ case BX : R233( 0x1, reg, 0x7);
+ break;
+
+ default : fprint( STDERR, "Wrong index register %d\n",
+ op->reg);
+ }
+ @text1( %$(op->expr));
+ @else
+ switch( op->reg) {
+ case SI : R233( 0x2, reg, 0x4);
+ break;
+
+ case DI : R233( 0x2, reg, 0x5);
+ break;
+
+ case BP : R233( 0x2, reg, 0x6);
+ break;
+
+ case BX : R233( 0x2, reg, 0x7);
+ break;
+
+ default : fprint( STDERR, "Wrong index register %d\n",
+ op->reg);
+ }
+ @text2( %$(op->expr));
+ @fi
+ }
+}
+
+mov_REG_EADDR( dst, src)
+struct t_operand *dst, *src;
+{
+ if ( REG(src) && dst->reg == src->reg)
+ ; /* Nothing!! result of push/pop optimization */
+ else {
+ @text1( 0x8b);
+ mod_RM( dst->reg, src);
+ }
+}
+
+
+R233( a, b, c)
+int a,b,c;
+{
+ @text1( %d( (a << 6) | ( b << 3) | c));
+}
+
+
+R53( a, b)
+int a,b;
+{
+ @text1( %d( (a << 3) | b));
+}
--- /dev/null
+#define UNKNOWN 0
+#define IS_REG 0x1
+#define IS_ACCU 0x2
+#define IS_DATA 0x4
+#define IS_LABEL 0x8
+#define IS_MEM 0x10
+#define IS_ADDR 0x20
+#define IS_ILB 0x40
+
+#define AX 0
+#define BX 3
+#define CL 1
+#define SP 4
+#define BP 5
+#define SI 6
+#define DI 7
+
+#define REG( op) ( op->type & IS_REG)
+#define ACCU( op) ( op->type & IS_REG && op->reg == AX)
+#define REG_CL( op) ( op->type & IS_REG && op->reg == CL)
+#define DATA( op) ( op->type & IS_DATA)
+#define lABEL( op) ( op->type & IS_LABEL)
+#define ILB( op) ( op->type & IS_ILB)
+#define MEM( op) ( op->type & IS_MEM)
+#define ADDR( op) ( op->type & IS_ADDR)
+#define EADDR( op) ( op->type & ( IS_ADDR | IS_MEM | IS_REG))
+#define CONST1( op) ( op->type & IS_DATA && strcmp( "1", op->expr) == 0)
+#define MOVS( op) ( op->type & IS_LABEL&&strcmp("\"movs\"", op->lab) == 0)
+#define IMMEDIATE( op) ( op->type & ( IS_DATA | IS_LABEL))
+
+#define TRUE 1
+#define FALSE 0
+
+struct t_operand {
+ unsigned type;
+ int reg;
+ char *expr, *lab, *off;
+ };
+
+extern struct t_operand saved_op, *AX_oper;
--- /dev/null
+adc dst:REG, src:EADDR ==> @text1( 0x13);
+ mod_RM( dst->reg, src).
+
+add dst:REG, src:EADDR ==> @text1( 0x3);
+ mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA ==> @text1( 0x5);
+ @text2( %$(src->expr)).
+
+... dst:EADDR, src:DATA ==> @text1( 0x81);
+ mod_RM( 0, dst);
+ @text2( %$(src->expr)).
+
+... dst:ACCU, src:lABEL ==> @text1( 0x5);
+ @reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+... dst:EADDR, src:lABEL ==> @text1( 0x81);
+ mod_RM( 0, dst);
+ @reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+and dst:REG, src:EADDR ==> @text1( 0x23);
+ mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA ==> @text1( 0x25);
+ @text2( %$(src->expr)).
+
+call dst:lABEL ==> @text1( 0xe8);
+ @reloc2( %$(dst->lab), %$(dst->off), PC_REL).
+
+... dst:EADDR ==> @text1( 0xff);
+ mod_RM( 2, dst).
+
+cmp dst:REG, src:EADDR ==> @text1( 0x3b);
+ mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA ==> @text1( 0x3d);
+ @text2( %$(src->expr)).
+
+cwd ==> @text1( 0x99).
+
+dec dst:REG ==> R53( 9, dst->reg).
+
+... dst:EADDR ==> @text1( 0xff);
+ mod_RM( 1, dst).
+
+div divisor:EADDR ==> @text1( 0xf7);
+ mod_RM( 6, divisor).
+
+idiv divisor:EADDR ==> @text1( 0xf7);
+ mod_RM( 7, divisor).
+
+inc dst:REG ==> R53( 8, dst->reg).
+
+... dst:EADDR ==> @text1( 0xff);
+ mod_RM( 0, dst).
+
+jb dst:ILB ==> @text1( 0x72);
+ @text1( %dist( dst->lab)).
+
+je dst:ILB ==> @text1( 0x74);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> save_op( dst);
+ assemble( "jne 9f");
+ jmp_instr( &saved_op);
+ assemble( "9:").
+
+jg dst:ILB ==> @text1( 0x7f);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> save_op( dst);
+ assemble( "jle 9f");
+ jmp_instr( &saved_op);
+ assemble( "9:").
+
+jge dst:ILB ==> @text1( 0x7d);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> save_op( dst);
+ assemble( "jl 9f");
+ jmp_instr( &saved_op);
+ assemble( "9:").
+
+jl dst:ILB ==> @text1( 0x7c);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> save_op( dst);
+ assemble( "jge 9f");
+ jmp_instr( &saved_op);
+ assemble( "9:").
+
+jle dst:ILB ==> @text1( 0x7e);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> save_op( dst);
+ assemble( "jg 9f");
+ jmp_instr( &saved_op);
+ assemble( "9:").
+
+jmp dst:ILB ==> @text1( 0xeb);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> @text1( 0xe9);
+ @reloc2( %$(dst->lab), %$(dst->off), PC_REL).
+
+jne dst:ILB ==> @text1( 0x75);
+ @text1( %dist( dst->lab)).
+
+... dst:lABEL ==> save_op( dst);
+ assemble( "je 9f");
+ jmp_instr( &saved_op);
+ assemble( "9:").
+
+lea dst:REG, src:EADDR ==> @text1( 0x8d);
+ mod_RM( dst->reg, src).
+
+loop dst:ILB ==> @text1( 0xe2);
+ @text1( %dist( dst->lab)).
+
+mov dst:REG, src:EADDR ==> mov_REG_EADDR( dst, src).
+
+... dst:REG, src:DATA ==> R53( 0x17, dst->reg);
+ @text2( %$(src->expr)).
+
+... dst:REG, src:lABEL ==> R53( 0x17, dst->reg);
+ @reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+... dst:EADDR, src:REG ==> @text1( 0x89);
+ mod_RM( src->reg, dst).
+
+... dst:EADDR, src:DATA ==> @text1( 0xc7);
+ mod_RM( 0, dst);
+ @text2( %$(src->expr)).
+
+... dst:EADDR, src:lABEL ==> @text1( 0xc7);
+ mod_RM( 0, dst);
+ @reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+movb dst:REG, src:EADDR ==> @text1( 0x8a);
+ mod_RM( dst->reg, src).
+
+... dst:EADDR, src:REG ==> @text1( 0x88);
+ mod_RM( src->reg, dst).
+
+mul mplier:EADDR ==> @text1( 0xf7);
+ mod_RM( 4, mplier).
+
+neg dst:EADDR ==> @text1( 0xf7);
+ mod_RM( 3, dst).
+
+not dst:EADDR ==> @text1( 0xf7);
+ mod_RM( 2, dst).
+
+or dst:REG, src:EADDR ==> @text1( 0x0b);
+ mod_RM( dst->reg, src).
+
+pop dst:REG ==> R53( 0xb, dst->reg).
+
+... dst:EADDR ==> @text1( 0x8f);
+ mod_RM( 0, dst).
+
+POP dst ==> @if ( push_waiting)
+ mov_instr( dst, AX_oper);
+ @assign( push_waiting, FALSE).
+ @else
+ pop_instr( dst).
+ @fi.
+
+push src:REG ==> R53( 0xa, src->reg).
+
+... src:EADDR ==> @text1( 0xff);
+ mod_RM( 6, src).
+
+PUSH src ==> mov_instr( AX_oper, src);
+ @assign( push_waiting, TRUE).
+
+rcr dst:EADDR, src:CONST1 ==> @text1( 0xd1);
+ mod_RM( 3, dst).
+
+rep ins:MOVS ==> @text1( 0xf3);
+ @text1( 0xa5). /* Wie zet direction flag? */
+
+ret ==> @text1( 0xc3). /* Altijd NEAR! */
+
+rol dst:EADDR, src:REG_CL ==> @text1( 0xd3);
+ mod_RM( 0, dst).
+
+ror dst:EADDR, src:REG_CL ==> @text1( 0xd3);
+ mod_RM( 1, dst).
+
+sal dst:EADDR, src:REG_CL ==> @text1( 0xd3);
+ mod_RM( 4, dst).
+
+sar dst:EADDR, src:REG_CL ==> @text1( 0xd3);
+ mod_RM( 7, dst).
+
+... dst:EADDR, src:CONST1 ==> @text1( 0xd1);
+ mod_RM( 7, dst).
+
+sbb dst:REG, src:EADDR ==> @text1( 0x1b);
+ mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA ==> @text1( 0x1d);
+ @text2( %$(src->expr)).
+
+shl dst, src ==> sal_instr( dst, src).
+
+shr dst:EADDR, src:REG_CL ==> @text1( 0xd3);
+ mod_RM( 5, dst).
+
+... dst:EADDR, src:CONST1 ==> @text1( 0xd1);
+ mod_RM( 5, dst).
+
+sub dst:REG, src:EADDR ==> @text1( 0x2b);
+ mod_RM( dst->reg, src).
+
+... dst:EADDR, src:DATA ==> @text1( 0x81);
+ mod_RM( 5, dst);
+ @text2( %$(src->expr)).
+
+test dst:REG, src:EADDR ==> @text1( 0x85);
+ mod_RM( dst->reg, src).
+
+xchg dst:EADDR, src:REG ==> @text1( 0x87);
+ mod_RM( src->reg, dst).
+
+xor dst:REG, src:EADDR ==> @text1( 0x33);
+ mod_RM( dst->reg, src).
--- /dev/null
+#include <system.h>
+#include "mach.h"
+
+arg_error( s, arg)
+char *s;
+int arg;
+{
+ fprint( STDERR, "arg_error %s %d\n", s, arg);
+}
+
+int push_waiting = FALSE;
+
+int fit_byte( val)
+int val;
+{
+ return( val >= -128 && val <= 127);
+}
--- /dev/null
+#define BSS_INIT 0
+
+#define ONE_BYTE int
+#define TWO_BYTES int
+#define FOUR_BYTES long
+
+
+#define EM_WSIZE 2
+#define EM_PSIZE 2
+#define EM_BSIZE 4
+
+
+#define NAME_FMT "_%s"
+#define DNAM_FMT "_%s"
+#define DLB_FMT "I_%ld"
+#define ILB_FMT "I%03d%ld"
+#define HOL_FMT "hol%d"
+
+#define GENLAB 'I'
+
+#define TRUE 1
+#define FALSE 0
+
+#define clean_push_buf() if(push_waiting){text1(0x50);push_waiting=FALSE;}
+#define assign( l, r) l = r
+extern int push_waiting;