#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 .los". 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 .sts". 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 */ /* */ /******************************************************************************/ C_adf $1 == 4 ==> "call .adf4"; "pop bx"; "pop bx". $1 == 8 ==> "call .adf8"; "add sp,8". default ==> arg_error("C_adf", $1). C_sbf $1 == 4 ==> "call .sbf4"; "pop bx"; "pop bx". $1 == 8 ==> "call .sbf8"; "add sp,8". default ==> arg_error("C_sbf", $1). C_mlf $1 == 4 ==> "call .mlf4"; "pop bx"; "pop bx". $1 == 8 ==> "call .mlf8"; "add sp,8". default ==> arg_error("C_mlf", $1). C_dvf $1 == 4 ==> "call .dvf4"; "pop bx"; "pop bx". $1 == 8 ==> "call .dvf8"; "add sp,8". default ==> arg_error("C_dvf", $1). C_fif $1 == 4 ==> C_lor((arith)1); "call .fif4"; "pop bx". $1 == 8 ==> C_lor((arith)1); "call .fif8"; "pop bx". default ==> arg_error("C_fif", $1). C_fef $1 == 4 ==> "mov ax,sp"; "sub ax,2"; "push ax"; "call .fef4". $1 == 8 ==> "mov ax,sp"; "sub ax,2"; "push ax"; "call .fef8". default ==> arg_error("C_fef", $1). /******************************************************************************/ /* */ /* 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_zrf ==> 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". C_cif ==> "call .cif". C_cuf ==> "call .cuf". C_cfi ==> "call .cfi"; "pop bx"; "pop cx"; "cmp bx,4"; "je 1f"; "add sp,cx"; "push ax"; "jmp 2f"; "1:add cx,4"; "add sp,cx"; "2:". C_cfu ==> "call .cfu"; "pop bx"; "pop cx"; "cmp bx,4"; "je 1f"; "add sp,cx"; "push ax"; "jmp 2f"; "1:add cx,4"; "add sp,cx"; "2:". C_cff ==> "pop ax"; "pop bx"; "cmp ax,bx"; "je 1f"; "cmp ax,4"; "je 2f"; "pop cx"; "pop bx"; "xor ax,ax"; "push ax"; "push ax"; "push bx"; "push cx"; "call .cff8"; "jmp 1f"; "2: call .cff4"; "pop bx"; "pop bx"; "1:". /******************************************************************************/ /* */ /* 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_cmf $1 == 4 ==> "call .cmf4"; "add sp,8"; "push ax". $1 == 8 ==> "call .cmf8"; "add sp,16"; "push ax". default ==> arg_error("C_cmf", $1). 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 ==> "pop ax"; "add ax,4"; "push ax". 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). ..fcon ==> con_float($1, $2). /******************************************************************************/ /* */ /* Extra-routines */ /* */ /******************************************************************************/ #ifdef PUSH_POP_OPT C_df_ilb ==> clean_push_buf(); symbol_definition( $1); set_local_visible( $1). #endif C_jump ==> "jmp $1". C_prolog ==> "push bp"; "mov bp, sp". C_locals $1 == 0 ==> . $1 == 2 ==> "push ax". $1 == 4 ==> "push ax"; "push ax". default ==> "sub sp, $1".