#define PUSH_POP_OPT TRUE /******************************************************************************/ /* */ /* Group 1 : load instructions */ /* */ /******************************************************************************/ C_loc ==> "push $1". C_lol ==> "push $1(ebp)". C_loe.. ==> "push ($1+$2)". C_lil ==> "mov eax, $1(ebp)"; "push (eax)". C_lof ==> "pop eax"; "push $1(eax)". C_lal ==> "lea eax, $1(ebp)"; "push eax". C_lae.. ==> "push $1+$2". C_lxl $1 == 0 ==> "push ebp". $1 == 1 ==> "push 8(ebp)". default ==> "mov ecx, $1-1"; "mov eax, 8(ebp)"; "1: mov eax, 8(eax)"; "loop 1b"; "push eax". C_lxa $1 == 0 ==> "lea eax, 8(ebp)"; "push eax". $1 == 1 ==> "mov eax, 8(ebp)"; "add eax, 8"; "push eax". default ==> "mov ecx, $1-1"; "mov eax, 8(ebp)"; "1: mov eax, 8(eax)"; "loop 1b"; "add eax, 8"; "push eax". C_loi $1 == 1 ==> "pop ecx"; "movzxb eax, (ecx)"; "push eax". $1 == 2 ==> "pop ecx"; "movzx eax, (ecx)"; "push eax". $1 == 4 ==> "pop eax"; "push (eax)". default ==> "pop ebx"; "mov ecx, $1"; "call .loi". C_los $1 == 4 ==> "pop ecx"; "pop ebx"; "call .los". default ==> arg_error( "C_los", $1). C_los_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ecx"; "pop ebx"; "call .los". C_ldl ==> "push $1+4(ebp)"; "push $1(ebp)". C_lde.. ==> "push ($1+$2+4)"; "push ($1+$2)". C_ldf ==> "pop eax"; "push $1+4(eax)"; "push $1(eax)". C_lpi ==> "push $1". /******************************************************************************/ /* */ /* Group 2 : store instructions */ /* */ /******************************************************************************/ C_stl ==> "pop $1(ebp)". C_ste.. ==> "pop ($1+$2)". C_sil ==> "mov eax, $1(ebp)"; "pop (eax)". C_stf ==> "pop eax"; "pop $1(eax)". C_sti $1 == 1 ==> "pop ecx"; "pop eax"; "movb (ecx), al". $1 == 2 ==> "pop eax"; "pop ecx"; "movw (eax),ecx". $1 == 4 ==> "pop eax"; "pop (eax)". default ==> "pop ebx"; "mov ecx, $1"; "call .sti". C_sts $1 == 4 ==> "pop ecx"; "pop ebx"; "call .sti". default ==> arg_error( "C_sts", $1). C_sts_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ecx"; "pop ebx"; "call .sti". C_sdl ==> "pop $1(ebp)"; "pop $1+4(ebp)". C_sde.. ==> "pop ($1+$2)"; "pop ($1+$2+4)". C_sdf ==> "pop eax"; "pop $1(eax)"; "pop $1+4(eax)". /******************************************************************************/ /* */ /* Group 3 : integer arithmetic */ /* */ /******************************************************************************/ C_adi $1 == 4 ==> "pop eax"; "pop ecx"; "add eax, ecx"; "push eax". default ==> arg_error("C_adi", $1). C_adi_narg ==> "pop ecx"; "pop eax"; "call .adi"; "push eax". C_sbi $1 == 4 ==> "pop ecx"; "pop eax"; "sub eax, ecx"; "push eax". default ==> arg_error("C_sbi", $1). C_sbi_narg ==> "pop ecx"; "pop eax"; "call .sbi"; "push eax". C_mli $1 == 4 ==> "pop eax"; "pop ecx"; "imul ecx"; "push eax". default ==> arg_error( "C_mli", $1). C_mli_narg ==> "pop eax"; "call .mli". C_dvi $1 == 4 ==> "pop ecx"; "pop eax"; "cdq"; "idiv ecx"; "push eax". default ==> arg_error( "C_dvi", $1). C_dvi_narg ==> "pop eax"; "call .dvi". C_rmi $1 == 4 ==> "pop ebx"; "pop eax"; "cdq"; "idiv ebx"; "push edx". default ==> arg_error( "C_rmi", $1). C_rmi_narg ==> "pop eax"; "call .rmi". C_ngi $1 == 4 ==> "pop eax"; "neg eax"; "push eax". default ==> "mov eax, $1"; "call .ngi". C_ngi_narg ==> "pop eax"; "call .ngi". C_sli $1 == 4 ==> "pop ecx"; "pop eax"; "sal eax, cl"; "push eax". default ==> "mov eax, $1"; "call .sli". C_sli_narg ==> "pop eax"; "call .sli". C_sri $1 == 4 ==> "pop ecx"; "pop eax"; "sar eax, cl"; "push eax". default ==> "mov eax, $1"; "call .sri". C_sri_narg ==> "pop eax"; "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 == 4 ==> "pop ebx"; "pop eax"; "xor edx, edx"; "div ebx"; "push eax". default ==> "mov eax, $1"; "call .dvu". C_dvu_narg ==> "pop eax"; "call .dvu". C_rmu $1 == 4 ==> "pop ebx"; "pop eax"; "xor edx, edx"; "div ebx"; "push edx". default ==> "mov eax, $1"; "call .rmu". C_rmu_narg ==> "pop eax"; "call .rmu". C_slu ==> C_sli( $1). C_slu_narg ==> C_sli_narg(). C_sru $1 == 4 ==> "pop ecx"; "pop eax"; "shr eax, cl"; "push eax". default ==> arg_error( "C_sru", $1). /******************************************************************************/ /* */ /* Group 5 : Floating point arithmetic */ /* */ /******************************************************************************/ C_adf $1 == 4 ==> "call .adf4"; "pop ebx". $1 == 8 ==> "call .adf8"; "add esp,8". default ==> arg_error("C_adf", $1). C_sbf $1 == 4 ==> "call .sbf4"; "pop ebx". $1 == 8 ==> "call .sbf8"; "add esp,8". default ==> arg_error("C_sbf", $1). C_mlf $1 == 4 ==> "call .mlf4"; "pop ebx". $1 == 8 ==> "call .mlf8"; "add esp,8". default ==> arg_error("C_mlf", $1). C_dvf $1 == 4 ==> "call .dvf4"; "pop ebx". $1 == 8 ==> "call .dvf8"; "add esp,8". default ==> arg_error("C_dvf", $1). C_ngf $1 == 4 ==> "call .ngf4". $1 == 8 ==> "call .ngf8". default ==> arg_error("C_ngf", $1). C_fif $1 == 4 ==> C_lor((arith)1); "call .fif4"; "pop ebx". $1 == 8 ==> C_lor((arith)1); "call .fif8"; "pop ebx". default ==> arg_error("C_fif", $1). C_fef $1 == 4 ==> "mov eax,esp"; "sub eax,4"; "push eax"; "call .fef4". $1 == 8 ==> "mov eax,esp"; "sub eax,4"; "push eax"; "call .fef8". default ==> arg_error("C_fef", $1). /******************************************************************************/ /* */ /* Group 6 : Pointer arithmetic */ /* */ /******************************************************************************/ C_adp $1 == 0 ==> . $1 == 1 ==> "pop eax"; "inc eax"; "push eax". $1 == -1 ==> "pop eax"; "dec eax"; "push eax". default ==> "pop eax"; "add eax, $1"; "push eax". C_ads $1 == 4 ==> "pop eax"; "pop ebx"; "add eax, ebx"; "push eax". default ==> arg_error( "C_ads", $1). C_ads_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop eax"; "pop ebx"; "add eax, ebx"; "push eax". C_sbs $1 == 4 ==> "pop ebx"; "pop eax"; "sub eax, ebx"; "push eax". default ==> arg_error( "C_sbs", $1). C_sbs_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ebx"; "pop eax"; "sub eax, ebx"; "push eax". /******************************************************************************/ /* */ /* Group 7 : Increment/decrement/zero */ /* */ /******************************************************************************/ C_inc ==> "pop eax"; "inc eax"; "push eax". C_inl ==> "inc $1(ebp)". C_ine.. ==> "inc ($1+$2)". C_dec ==> "pop eax"; "dec eax"; "push eax". C_del ==> "dec $1(ebp)". C_dee.. ==> "dec ($1+$2)". C_zrl ==> "mov $1(ebp), 0". C_zre.. ==> "mov ($1+$2), 0". C_zer $1 == 4 ==> "xor eax, eax"; "push eax". $1 == 8 ==> "xor eax, eax"; "push eax"; "push eax". $1 % 4 == 0 ==> "mov ecx, $1/4"; "xor eax, eax"; "1: push eax"; "loop 1b". default ==> arg_error( "C_zer", $1). C_zrf ==> C_zer($1). C_zer_narg ==> "pop ecx"; "sar ecx, 2"; "xor eax, eax"; "1: push eax"; "loop 1b". /******************************************************************************/ /* */ /* Group 8 : Convert */ /* */ /******************************************************************************/ C_cii ==> "pop ecx"; "pop edx"; "pop eax"; "call .cii"; "push eax". C_cui ==> C_cuu(). C_ciu ==> C_cuu(). C_cuu ==> "pop ecx"; "pop edx". C_cif ==> "pop eax"; "cmp eax,4"; "jne 1f"; "call .cif4"; "pop ebx"; "jmp 2f"; "1: call .cif8"; "2:". C_cuf ==> "pop eax"; "cmp eax,4"; "jne 1f"; "call .cuf4"; "pop ebx"; "jmp 2f"; "1: call .cuf8"; "2:". C_cfi ==> "call .cfi"; "pop ecx"; "pop ebx"; "cmp ebx,4"; "je 1f"; "pop ebx"; "1:". C_cfu ==> "call .cfu"; "pop ecx"; "pop ebx"; "cmp ebx,4"; "je 1f"; "pop ebx"; "1:". C_cff ==> "pop eax"; "pop ebx"; "cmp eax,ebx"; "je 1f"; "cmp eax,4"; "jne 2f"; "call .cff4"; "pop ebx"; "jmp 1f"; "2: pop eax"; "xor ebx,ebx"; "push ebx"; "push eax"; "call .cff8"; "1:". /******************************************************************************/ /* */ /* Group 9 : Logical */ /* */ /******************************************************************************/ C_and $1 == 4 ==> "pop eax"; "pop ebx"; "and eax, ebx"; "push eax". default ==> "mov ecx, $1"; "call .and". C_and_narg ==> "pop ecx"; "call .and". C_ior $1 == 4 ==> "pop eax"; "pop ebx"; "or eax, ebx"; "push eax". default ==> "mov ecx, $1"; "call .ior". C_ior_narg ==> "pop ecx"; "call .ior". C_xor $1 == 4 ==> "pop eax"; "pop ebx"; "xor eax, ebx"; "push eax". default ==> "mov ecx, $1"; "call .xor". C_xor_narg ==> "pop ecx"; "call .xor". C_com $1 == 4 ==> "pop eax"; "not eax"; "push eax". default ==> "mov ecx, $1"; "call .com". C_com_narg ==> "pop ecx"; "call .com". C_rol $1 == 4 ==> "pop ecx"; "pop eax"; "rol eax, cl"; "push eax". default ==> "mov ecx, $1"; "call .rol". C_rol_narg ==> "pop ecx"; "call .rol". C_ror $1 == 4 ==> "pop ecx"; "pop eax"; "ror eax, cl"; "push eax". default ==> "mov ecx, $1"; "call .ror". C_ror_narg ==> "pop ecx"; "call .ror". /******************************************************************************/ /* */ /* Group 10 : Sets */ /* */ /******************************************************************************/ C_inn $1 == 4 ==> "pop ecx"; "pop eax"; "shr eax, cl"; "and eax, 1"; "push eax". default ==> "pop eax"; "mov ecx, $1"; "call .inn"; "push eax". C_inn_narg ==> "pop ecx"; "pop eax"; "call .inn"; "push eax". C_set $1 == 4 ==> "pop ecx"; "mov eax, 1"; "shl eax, cl"; "push eax". default ==> "pop eax"; "mov ecx, $1"; "call .set". C_set_narg ==> "pop ecx"; "pop eax"; "call .set". /******************************************************************************/ /* */ /* Group 11 : Array */ /* */ /******************************************************************************/ C_lar $1 == 4 ==> "pop ebx"; "pop eax"; "call .lar4". default ==> arg_error( "C_lar", $1). C_lar_narg ==> "call .ilar". C_sar $1 == 4 ==> "pop ebx"; "pop eax"; "call .sar4". default ==> arg_error( "C_sar", $1). C_sar_narg ==> "call .isar". C_aar $1 == 4 ==> "pop ebx"; "pop eax"; "pop ecx"; "sub eax, (ebx)"; "mul 8(ebx)"; "add eax, ecx"; "push eax". default ==> arg_error( "C_aar", $1). C_aar_narg ==> "call .iaar"; "push ebx". /******************************************************************************/ /* */ /* Group 12 : Compare */ /* */ /******************************************************************************/ C_cmi $1 == 4 ==> "pop ebx"; "pop ecx"; "xor eax, eax"; "cmp ecx, ebx"; "je 2f"; "jl 1f"; "inc eax"; "jmp 2f"; "1: dec eax"; "2: push eax". default ==> arg_error( "C_cmi", $1). C_cmu $1 == 4 ==> C_cmp(). default ==> arg_error( "C_cmu", $1). C_cms $1 == 4 ==> C_sbi( (arith) 4). default ==> "mov ecx, $1"; "call .cms"; "push ecx". C_cms_narg ==> "pop ecx"; "call .cms"; "push ecx". C_cmp ==> "pop ebx"; "pop ecx"; "xor eax, eax"; "cmp ecx, ebx"; "je 2f"; "jb 1f"; "inc eax"; "jmp 2f"; "1: dec eax"; "2: push eax". C_cmf $1 == 4 ==> "call .cmf4"; "pop ebx"; "pop ebx"; "push eax". $1 == 8 ==> "call .cmf8"; "add esp,16"; "push eax". default ==> arg_error("C_cmf", $1). C_tlt ==> "pop eax"; "xor ebx, ebx"; "test eax, eax"; "jge 1f"; "inc ebx"; "1: push ebx". C_tle ==> "pop eax"; "xor ebx, ebx"; "test eax, eax"; "jg 1f"; "inc ebx"; "1: push ebx". C_teq ==> "pop eax"; "xor ebx, ebx"; "test eax, eax"; "jne 1f"; "inc ebx"; "1: push ebx". C_tne ==> "pop eax"; "xor ebx, ebx"; "test eax, eax"; "je 1f"; "inc ebx"; "1: push ebx". C_tge ==> "pop eax"; "xor ebx, ebx"; "test eax, eax"; "jl 1f"; "inc ebx"; "1: push ebx". C_tgt ==> "pop eax"; "xor ebx, ebx"; "test eax, eax"; "jle 1f"; "inc ebx"; "1: push ebx". /******************************************************************************/ /* */ /* Group 13 : Branch */ /* */ /******************************************************************************/ C_bra ==> "jmp $1". C_blt ==> "pop eax"; "pop ebx"; "cmp ebx, eax"; "jl $1". C_ble ==> "pop eax"; "pop ebx"; "cmp ebx, eax"; "jle $1". C_beq ==> "pop eax"; "pop ebx"; "cmp ebx, eax"; "je $1". C_bne ==> "pop eax"; "pop ebx"; "cmp ebx, eax"; "jne $1". C_bge ==> "pop eax"; "pop ebx"; "cmp ebx, eax"; "jge $1". C_bgt ==> "pop eax"; "pop ebx"; "cmp ebx, eax"; "jg $1". C_zlt ==> "pop eax"; "test eax, eax"; "jl $1". C_zle ==> "pop eax"; "test eax, eax"; "jle $1". C_zeq ==> "pop eax"; "test eax, eax"; "je $1". C_zne ==> "pop eax"; "test eax, eax"; "jne $1". C_zge ==> "pop eax"; "test eax, eax"; "jge $1". C_zgt ==> "pop eax"; "test eax, eax"; "jg $1". /******************************************************************************/ /* */ /* Group 14 : Procedure call instructions */ /* */ /******************************************************************************/ C_cai ==> "pop ebx"; "call ebx". C_cal ==> "call $1". C_lfr $1 == 4 ==> "push eax". $1 == 8 ==> "push edx"; "push eax". default ==> arg_error( "C_lfr", $1). C_ret $1 == 0 ==> "leave"; "ret". $1 == 4 ==> "pop eax"; "leave"; "ret". $1 == 8 ==> "pop eax"; "pop edx"; "leave"; "ret". default ==> arg_error( "C_ret", $1). /******************************************************************************/ /* */ /* Group 15 : Miscellaneous instructions */ /* */ /******************************************************************************/ C_asp $1 == 4 ==> "pop ebx". $1 == 8 ==> "pop ebx"; "pop ebx". $1 == -4 ==> "push eax". $1 == -8 ==> "push eax"; "push eax". default ==> "add esp, $1". C_ass $1 == 4 ==> "pop eax"; "add esp, eax". default ==> arg_error( "C_ass", $1). C_ass_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop eax"; "add esp, eax". C_blm $1 % 4 == 0 ==> "mov ecx, $1/4"; "call .blm". default ==> arg_error( "C_blm", $1). C_bls $1 == 4 ==> "pop ecx"; "sar ecx,2"; "call .blm". default ==> arg_error( "C_bls", $1). C_bls_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ecx"; "sar ecx, 2"; "call .blm". C_csa $1 == 4 ==> "pop ebx"; "pop eax"; "jmp .csa4". default ==> arg_error( "C_csa", $1). C_csa_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ebx"; "pop eax"; "jmp .csa4". C_csb $1 == 4 ==> "pop ebx"; "pop eax"; "jmp .csb4". default ==> arg_error( "C_csb", $1). C_csb_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ebx"; "pop eax"; "jmp .csb4". C_dch ==> "mov ebp, (ebp)". C_dup $1 == 4 ==> "pop eax"; "push eax"; "push eax". $1 == 8 ==> "pop eax"; "pop ebx"; "push ebx"; "push eax"; "push ebx"; "push eax". default ==> "mov ecx, $1"; "call .dup". C_dus $1 == 4 ==> "pop ecx"; "call .dup". default ==> arg_error( "C_dus", $1). C_dus_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ecx"; "call .dup". C_exg ==> "mov ecx, $1"; "call .exg". C_exg_narg ==> "pop ecx"; "call .exg". C_fil.. ==> "mov (hol0+4), $1+$2". C_gto.. ==> "mov ebx, $1+$2"; "call .gto". C_lim ==> "push (.ignmask)". C_lin ==> "mov (hol0), $1". C_lni ==> "inc (hol0)". C_lor $1 == 0 ==> "push ebp". $1 == 1 ==> "mov eax, esp"; "push eax". $1 == 2 ==> "push (.reghp)". default ==> arg_error( "C_lor", $1). C_lpb ==> "pop eax"; "add eax, 8"; "push eax". C_mon ==> "pop eax"; "call .mon". C_nop ==> "call .nop". C_rck $1 == 4 ==> "pop ebx"; "pop eax"; "call .rck"; "push eax". default ==> arg_error( "C_rck", $1). C_rck_narg ==> "pop eax"; "cmp eax, 4"; "jne .unknown"; "pop ebx"; "pop eax"; "call .rck"; "push eax". C_rtt ==> C_ret( (arith) 0). C_sig ==> "pop eax"; "xchg (.trppc), eax"; "push eax". C_sim ==> "pop (.ignmask)". C_str $1 == 0 ==> "pop ebp". $1 == 1 ==> "pop esp". $1 == 2 ==> "pop (.reghp)". default ==> arg_error( "C_str", $1). C_trp ==> "pop eax"; "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 ==> . C_locals ==> "push ebp"; "mov ebp,esp"; "sub esp, $1".