unit kern_jit_ops; {$mode ObjFPC}{$H+} {$CALLING SysV_ABI_CDecl} interface uses x86_fpdbgdisas, x86_jit, kern_jit_ctx; type t_jit_cb=procedure(var ctx:t_jit_context2); t_rep_op=(repOPins,repOPouts,repOPmovs,repOPlods,repOPstos,repOPcmps,repOPscas,repOPret); var jit_cbs:array[TOpcodePrefix,TOpCode,TOpCodeSuffix] of t_jit_cb; jit_rep_cbs:array[t_rep_op] of t_jit_cb; implementation // procedure _op_rep_cmps(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; link_start:t_jit_i_link; link___end:t_jit_i_link; link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi //(r_tmp1)r15 <-> rsi with ctx.builder do begin link_jmp0:=nil_link; link_jmp1:=nil_link; link_start:=ctx.builder.get_curr_label.after; //repeat link_jmp0:=jcxz(nil_link,ctx.dis.AddressSize); movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq(r_tmp1,rsi); op_uplift(ctx,r_tmp1,size,[not_use_r_tmp0]); //in/out:r15 xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); _O($A7,Size); xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); leaq(rcx,[rcx-1]); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); leaq(rsi,[rsi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); leaq(rsi,[rsi-OPERAND_BYTES[size]]); end; if (ifPrefixRepE in ctx.din.Flags) then begin //if a[i]<>b[i] then exit link_jmp1:=jcc(OPSc_nz,nil_link,os8); end else if (ifPrefixRepNe in ctx.din.Flags) then begin //if a[i]=b[i] then exit link_jmp1:=jcc(OPSc_z,nil_link,os8); end; //until jmp(link_start,os8); //exit link___end:=ctx.builder.get_curr_label.after; //exit link_jmp0.target:=link___end; link_jmp1.target:=link___end; end; end; procedure op_rep_cmps(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); popfq(os64); _op_rep_cmps(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; popfq(os64); _op_rep_cmps(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; end; end; /// procedure _op_rep_stos(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; new:TRegValue; link_start:t_jit_i_link; link___end:t_jit_i_link; link_jmp0:t_jit_i_link; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi with ctx.builder do begin link_jmp0:=nil_link; new:=new_reg_size(rax,size); link_start:=ctx.builder.get_curr_label.after; //repeat link_jmp0:=jcxz(nil_link,ctx.dis.AddressSize); movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq([r_tmp0],new); // mov [r14],rax leaq(rcx,[rcx-1]); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); end; //until jmp(link_start,os8); //exit link___end:=ctx.builder.get_curr_label.after; //exit link_jmp0.target:=link___end; end; end; procedure op_rep_stos(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); _op_rep_stos(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; _op_rep_stos(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; popfq(os64); end; end; // procedure _op_rep_movs(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; link_start:t_jit_i_link; link___end:t_jit_i_link; link_jmp0:t_jit_i_link; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi //(r_tmp1)r15 <-> rsi with ctx.builder do begin link_jmp0:=nil_link; link_start:=ctx.builder.get_curr_label.after; //repeat link_jmp0:=jcxz(nil_link,ctx.dis.AddressSize); movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq(r_tmp1,rsi); op_uplift(ctx,r_tmp1,size,[not_use_r_tmp0]); //in/out:r15 //[RSI] -> [RDI]. xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); _O($A5,Size); xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); leaq(rcx,[rcx-1]); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); leaq(rsi,[rsi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); leaq(rsi,[rsi-OPERAND_BYTES[size]]); end; //until jmp(link_start,os8); //exit link___end:=ctx.builder.get_curr_label.after; //exit link_jmp0.target:=link___end; end; end; procedure op_rep_movs(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); _op_rep_movs(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; _op_rep_movs(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; popfq(os64); end; end; // procedure _op_cmps(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi //(r_tmp1)r15 <-> rsi with ctx.builder do begin movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq(r_tmp1,rsi); op_uplift(ctx,r_tmp1,size,[not_use_r_tmp0]); //in/out:r15 xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); _O($A7,Size); xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); leaq(rsi,[rsi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); leaq(rsi,[rsi-OPERAND_BYTES[size]]); end; end; end; procedure op_cmps(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); popfq(os64); _op_cmps(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; popfq(os64); _op_cmps(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; end; end; // procedure _op_movs(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi //(r_tmp1)r15 <-> rsi with ctx.builder do begin movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq(r_tmp1,rsi); op_uplift(ctx,r_tmp1,size,[not_use_r_tmp0]); //in/out:r15 //[RSI] -> [RDI]. xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); _O($A5,Size); xchgq(rdi,r_tmp0); xchgq(rsi,r_tmp1); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); leaq(rsi,[rsi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); leaq(rsi,[rsi-OPERAND_BYTES[size]]); end; end; end; procedure op_movs(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); _op_movs(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; _op_movs(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; popfq(os64); end; end; // procedure _op_stos(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; new:TRegValue; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi with ctx.builder do begin new:=new_reg_size(rax,size); movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq([r_tmp0],new); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); end; end; end; procedure op_stos(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); _op_stos(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; _op_stos(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; popfq(os64); end; end; // procedure _op_lods(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; new:TRegValue; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi with ctx.builder do begin new:=new_reg_size(rax,size); movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 movq(new,[r_tmp0]); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); end; end; end; procedure op_lods(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); _op_lods(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; _op_lods(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; popfq(os64); end; end; // procedure _op_scas(var ctx:t_jit_context2;dflag:Integer); var size:TOperandSize; begin //rdi,rsi Assert(ctx.dis.AddressSize=as64,'prefix $67 TODO'); case ctx.din.OpCode.Suffix of OPSx_b:size:=os8; OPSx_w:size:=os16; OPSx_d:size:=os32; OPSx_q:size:=os64; else; Assert(False); end; //(r_tmp0)r14 <-> rdi with ctx.builder do begin movq(r_tmp0,rdi); op_uplift(ctx,r_tmp0,size); //in/out:r14 xchgq(rdi,r_tmp0); _O($AF,Size); xchgq(rdi,r_tmp0); if (dflag=0) then begin leaq(rdi,[rdi+OPERAND_BYTES[size]]); end else begin leaq(rdi,[rdi-OPERAND_BYTES[size]]); end; end; end; procedure op_scas(var ctx:t_jit_context2); var link_jmp0:t_jit_i_link; link_jmp1:t_jit_i_link; begin with ctx.builder do begin //get d flag pushfq(os64); bti8([rsp,os64],10); //bt [rsp], 10 link_jmp0:=jcc(OPSc_b,nil_link,os8); popfq(os64); _op_scas(ctx,0); link_jmp1:=jmp(nil_link,os8); link_jmp0.target:=ctx.builder.get_curr_label.after; popfq(os64); _op_scas(ctx,1); link_jmp1.target:=ctx.builder.get_curr_label.after; end; end; // const xor_desc:t_op_desc=( mem_reg:(op:$31;index:0); reg_mem:(op:$33;index:0); reg_imm:(op:$81;index:6); reg_im8:(op:$83;index:6); hint:[his_xor,his_rw]; ); procedure op_xor(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,xor_desc); end else begin add_orig(ctx); end; end; const or_desc:t_op_desc=( mem_reg:(op:$09;index:0); reg_mem:(op:$0B;index:0); reg_imm:(op:$81;index:1); reg_im8:(op:$83;index:1); hint:[his_rw]; ); procedure op_or(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,or_desc); end else begin add_orig(ctx); end; end; const and_desc:t_op_desc=( mem_reg:(op:$21;index:0); reg_mem:(op:$23;index:0); reg_imm:(op:$81;index:4); reg_im8:(op:$83;index:4); hint:[his_rw]; ); procedure op_and(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,and_desc); end else begin add_orig(ctx); end; end; const sub_desc:t_op_desc=( mem_reg:(op:$29;index:0); reg_mem:(op:$2B;index:0); reg_imm:(op:$81;index:5); reg_im8:(op:$83;index:5); hint:[his_rw]; ); procedure op_sub(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,sub_desc); end else begin add_orig(ctx); end; end; const sbb_desc:t_op_desc=( mem_reg:(op:$19;index:0); reg_mem:(op:$1B;index:0); reg_imm:(op:$81;index:3); reg_im8:(op:$83;index:3); hint:[his_rw]; ); procedure op_sbb(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,sbb_desc); end else begin add_orig(ctx); end; end; const add_desc:t_op_desc=( mem_reg:(op:$01;index:0); reg_mem:(op:$03;index:0); reg_imm:(op:$81;index:0); reg_im8:(op:$83;index:0); hint:[his_rw]; ); procedure op_add(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,add_desc); end else begin add_orig(ctx); end; end; const adc_desc:t_op_desc=( mem_reg:(op:$11;index:0); reg_mem:(op:$13;index:0); reg_imm:(op:$81;index:2); reg_im8:(op:$83;index:2); hint:[his_rw]; ); procedure op_adc(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,adc_desc); end else begin add_orig(ctx); end; end; const imul_desc1:t_op_type=(op:$F7;index:5); imul_desc2:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$0FAF;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_rw]; ); imul_desc3:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(opt:[not_impl]); reg_imm:(op:$69;index:0); reg_im8:(op:$6B;index:0); hint:[]; ); procedure op_imul(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin case ctx.din.OperCnt of 1:op_emit1(ctx,imul_desc1,[his_ro]); //R 2:op_emit2(ctx,imul_desc2); //RM 3:op_emit2(ctx,imul_desc3); //RMI else Assert(false); end; end else begin add_orig(ctx); end; end; procedure op_emit1_gn(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8]; op_emit1(ctx,tmp,[]); end else begin add_orig(ctx); end; end; procedure op_emit1_gn_np(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8,not_prefix]; op_emit1(ctx,tmp,[]); end else begin add_orig(ctx); end; end; procedure op_emit1_ro(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8]; op_emit1(ctx,tmp,[his_ro]); end else begin add_orig(ctx); end; end; procedure op_emit1_ro_np(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8,not_prefix]; op_emit1(ctx,tmp,[his_ro]); end else begin add_orig(ctx); end; end; procedure op_emit1_rw(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8]; op_emit1(ctx,tmp,[his_rw]); end else begin add_orig(ctx); end; end; procedure op_emit1_rw_np(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8,not_prefix]; op_emit1(ctx,tmp,[his_rw]); end else begin add_orig(ctx); end; end; procedure op_emit1_wo_np(var ctx:t_jit_context2); var tmp:t_op_type; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=Default(t_op_type); tmp.op :=ctx.dis.opcode; tmp.index:=ctx.dis.ModRM.Index; tmp.opt :=[not_os8,not_prefix]; op_emit1(ctx,tmp,[his_wo]); end else begin add_orig(ctx); end; end; const bt_desc:t_op_desc=( mem_reg:(op:$0FA3;index:0); reg_mem:(opt:[not_impl]); reg_imm:(opt:[not_impl]); reg_im8:(op:$0FBA;index:4); hint:[his_ro,his_bt]; ); procedure op_bt(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,bt_desc); end else begin add_orig(ctx); end; end; const btc_desc:t_op_desc=( mem_reg:(op:$0FBB;index:0); reg_mem:(opt:[not_impl]); reg_imm:(opt:[not_impl]); reg_im8:(op:$0FBA;index:7); hint:[his_rw,his_bt]; ); procedure op_btc(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,btc_desc); end else begin add_orig(ctx); end; end; const bts_desc:t_op_desc=( mem_reg:(op:$0FAB;index:0); reg_mem:(opt:[not_impl]); reg_imm:(opt:[not_impl]); reg_im8:(op:$0FBA;index:5); hint:[his_rw,his_bt]; ); procedure op_bts(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,bts_desc); end else begin add_orig(ctx); end; end; const btr_desc:t_op_desc=( mem_reg:(op:$0FB3;index:0); reg_mem:(opt:[not_impl]); reg_imm:(opt:[not_impl]); reg_im8:(op:$0FBA;index:6); hint:[his_rw,his_bt]; ); procedure op_btr(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,btr_desc); end else begin add_orig(ctx); end; end; // const bsf_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$0FBC;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_wo]; ); procedure op_bsf(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin //If the second operand contains 0, //the instruction sets ZF to 1 //and does not change the contents //of the destination register. op_emit2(ctx,bsf_desc); end else begin add_orig(ctx); end; end; const bsr_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$0FBD;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_wo]; ); procedure op_bsr(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin //If the second operand contains 0, //the instruction sets ZF to 1 //and does not change the contents //of the destination register. op_emit2(ctx,bsr_desc); end else begin add_orig(ctx); end; end; // const xchg_desc:t_op_desc=( mem_reg:(op:$87;index:0); reg_mem:(op:$87;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_xchg,his_rw]; ); procedure op_xchg(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,xchg_desc); end else begin add_orig(ctx); end; end; const mov_desc:t_op_desc=( mem_reg:(op:$89;index:0); reg_mem:(op:$8B;index:0); reg_imm:(op:$C7;index:0); reg_im8:(opt:[not_impl]); hint:[his_mov,his_wo]; ); procedure op_mov(var ctx:t_jit_context2); type tdata16=array[0..15] of Byte; var data:tdata16; Code:Pointer; Operand:TOperand; i:Byte; begin if is_segment(ctx.din.Operand[1]) then begin Exit; //skip segment change end; if is_segment(ctx.din.Operand[2]) then begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin i:=ctx.dis.CodeIdx; data:=Default(tdata16); Move(ctx.Code^,data,i); data[i+0]:=get_segment_value(ctx.din.Operand[2]); Code:=ctx.Code; Operand:=ctx.din.Operand[2]; ctx.din.Operand[2].RegValue :=Default(TRegValues); ctx.din.Operand[2].Size :=ctx.din.Operand[1].Size; ctx.din.Operand[2].ByteCount:=i; op_emit2(ctx,mov_desc); ctx.din.Operand[2]:=Operand; ctx.Code:=Code; end else begin //reg_imm ctx.builder.movi(new_reg(ctx.din.Operand[1]),get_segment_value(ctx.din.Operand[2])); end; Exit; end; if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,mov_desc); end else begin add_orig(ctx); end; end; const CMOV_8:array[OPSc_o..OPSc_nle] of Byte=( $40,$41,$42,$43,$44,$45,$46,$47, $48,$49,$4A,$4B,$4C,$4D,$4E,$4F ); const cmov_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$00;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[]; ); procedure op_cmov(var ctx:t_jit_context2); var desc:t_op_desc; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin desc:=cmov_desc; desc.reg_mem.op:=$0F00 or CMOV_8[ctx.din.OpCode.Suffix]; // op_emit2(ctx,desc); end else begin add_orig(ctx); end; end; const movx_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$00;opt:[not_os8,reg_size_pri]); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_mov,his_wo]; ); procedure op_movzx(var ctx:t_jit_context2); var desc:t_op_desc; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin desc:=movx_desc; // case ctx.din.Operand[2].Size of os8:desc.reg_mem.op:=$0FB6; os16:desc.reg_mem.op:=$0FB7; else Assert(false); end; op_emit2(ctx,desc); end else begin add_orig(ctx); end; end; procedure op_movsx(var ctx:t_jit_context2); var desc:t_op_desc; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin desc:=movx_desc; // case ctx.din.Operand[2].Size of os8:desc.reg_mem.op:=$0FBE; os16:desc.reg_mem.op:=$0FBF; else Assert(false); end; op_emit2(ctx,desc); end else begin add_orig(ctx); end; end; const movbe_desc:t_op_desc=( mem_reg:(op:$0F38F1;opt:[not_os8]); reg_mem:(op:$0F38F0;opt:[not_os8]); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_mov,his_wo]; ); procedure op_movbe(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,movbe_desc); end else begin add_orig(ctx); end; end; const movsxd_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$63;opt:[not_os8,reg_size_pri]); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_mov,his_wo]; ); procedure op_movsxd(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,movsxd_desc); end else begin add_orig(ctx); end; end; // const test_desc:t_op_desc=( mem_reg:(op:$85;index:0); reg_mem:(opt:[not_impl]); reg_imm:(op:$F7;index:0); reg_im8:(opt:[not_impl]); hint:[his_ro]; ); procedure op_test(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,test_desc); end else begin add_orig(ctx); end; end; const cmp_desc:t_op_desc=( mem_reg:(op:$39;index:0); reg_mem:(op:$3B;index:0); reg_imm:(op:$81;index:7); reg_im8:(op:$83;index:7); hint:[his_ro]; ); procedure op_cmp(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,cmp_desc); end else begin add_orig(ctx); end; end; const cmpxchg_desc:t_op_desc=( mem_reg:(op:$0FB1;index:0); reg_mem:(opt:[not_impl]); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_xchg,his_rw]; ); procedure op_cmpxchg(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,cmpxchg_desc); end else with ctx.builder do begin add_orig(ctx); end; end; const cmpxchg_8b_16b_desc:t_op_type=(op:$0FC7;index:1); procedure op_cmpxchg_8b_16b(var ctx:t_jit_context2); begin op_emit1(ctx,cmpxchg_8b_16b_desc,[his_xchg,his_rw]); end; const xadd_desc:t_op_desc=( mem_reg:(op:$0FC1;index:0); reg_mem:(opt:[not_impl]); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_xchg,his_rw]; ); procedure op_xadd(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,xadd_desc); end else begin add_orig(ctx); end; end; const lzcnt_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$F30FBD;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_wo]; ); procedure op_lzcnt(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,lzcnt_desc); end else begin add_orig(ctx); end; end; const tzcnt_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$F30FBC;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_wo]; ); procedure op_tzcnt(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,tzcnt_desc); end else begin add_orig(ctx); end; end; const popcnt_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$F30FB8;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[his_wo]; ); procedure op_popcnt(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,popcnt_desc); end else begin add_orig(ctx); end; end; // const crc32_desc:t_op_desc=( mem_reg:(opt:[not_impl]); reg_mem:(op:$F20F38F1;index:0); reg_imm:(opt:[not_impl]); reg_im8:(opt:[not_impl]); hint:[]; ); procedure op_crc32(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit2(ctx,crc32_desc); end else begin add_orig(ctx); end; end; // procedure op_shift2_gen(var ctx:t_jit_context2); const desc:t_op_shift=( reg_im8:(op:$C1;index:0); mem__cl:(op:$D3;index:0); mem_one:(op:$D1;index:0); ); var tmp:t_op_shift; begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin tmp:=desc; tmp.reg_im8.index:=ctx.dis.ModRM.Index; tmp.mem__cl.index:=ctx.dis.ModRM.Index; tmp.mem_one.index:=ctx.dis.ModRM.Index; // op_emit_shift2(ctx,tmp); end else begin add_orig(ctx); end; end; // const shld_desc:t_op_shift=( reg_im8:(op:$0FA4); mem__cl:(op:$0FA5); mem_one:(opt:[not_impl]); ); procedure op_shld(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit_shift3(ctx,shld_desc); end else begin add_orig(ctx); end; end; const shrd_desc:t_op_shift=( reg_im8:(op:$0FAC); mem__cl:(op:$0FAD); mem_one:(opt:[not_impl]); ); procedure op_shrd(var ctx:t_jit_context2); begin if is_preserved(ctx.din) or is_memory(ctx.din) then begin op_emit_shift3(ctx,shrd_desc); end else begin add_orig(ctx); end; end; // procedure op_bswap(var ctx:t_jit_context2); var new:TRegValue; begin if is_preserved(ctx.din) then begin with ctx.builder do begin new:=new_reg_size(r_tmp0,ctx.din.Operand[1]); op_load(ctx,new,1); bswap(new); op_save(ctx,1,fix_size(new)); end; end else begin add_orig(ctx); end; end; procedure op_lea(var ctx:t_jit_context2); var new:TRegValue; begin if is_preserved(ctx.din) then begin if is_preserved(ctx.din.Operand[1]) then begin new:=new_reg_size(r_tmp0,ctx.din.Operand[1]); build_lea(ctx,2,new,[not_use_segment]); // op_save(ctx,1,fix_size(new)); end else begin new:=new_reg(ctx.din.Operand[1]); // if (new.ASize=os16) then begin //low part build_lea(ctx,2,r_tmp0); // ctx.builder.movq(new,r_tmp0); end else begin build_lea(ctx,2,new); end; end; end else begin add_orig(ctx); end; end; // procedure init_cbs; begin // if jit_memory_guard then begin jit_rep_cbs[repOPmovs]:=@op_rep_movs; jit_rep_cbs[repOPlods]:=nil; jit_rep_cbs[repOPstos]:=@op_rep_stos; jit_rep_cbs[repOPcmps]:=@op_rep_cmps; jit_rep_cbs[repOPscas]:=nil; jit_cbs[OPPnone,OPcmps,OPSx_b]:=@op_cmps; jit_cbs[OPPnone,OPcmps,OPSx_w]:=@op_cmps; jit_cbs[OPPnone,OPcmps,OPSx_d]:=@op_cmps; jit_cbs[OPPnone,OPcmps,OPSx_q]:=@op_cmps; jit_cbs[OPPnone,OPmovs,OPSx_b]:=@op_movs; jit_cbs[OPPnone,OPmovs,OPSx_w]:=@op_movs; jit_cbs[OPPnone,OPmovs,OPSx_d]:=@op_movs; jit_cbs[OPPnone,OPmovs,OPSx_q]:=@op_movs; jit_cbs[OPPnone,OPstos,OPSx_b]:=@op_stos; jit_cbs[OPPnone,OPstos,OPSx_w]:=@op_stos; jit_cbs[OPPnone,OPstos,OPSx_d]:=@op_stos; jit_cbs[OPPnone,OPstos,OPSx_q]:=@op_stos; jit_cbs[OPPnone,OPlods,OPSx_b]:=@op_lods; jit_cbs[OPPnone,OPlods,OPSx_w]:=@op_lods; jit_cbs[OPPnone,OPlods,OPSx_d]:=@op_lods; jit_cbs[OPPnone,OPlods,OPSx_q]:=@op_lods; jit_cbs[OPPnone,OPscas,OPSx_b]:=@op_scas; jit_cbs[OPPnone,OPscas,OPSx_w]:=@op_scas; jit_cbs[OPPnone,OPscas,OPSx_d]:=@op_scas; jit_cbs[OPPnone,OPscas,OPSx_q]:=@op_scas; end else begin jit_rep_cbs[repOPmovs]:=@add_orig; jit_rep_cbs[repOPlods]:=@add_orig; jit_rep_cbs[repOPstos]:=@add_orig; jit_rep_cbs[repOPcmps]:=@add_orig; jit_rep_cbs[repOPscas]:=@add_orig; jit_cbs[OPPnone,OPcmps,OPSx_b]:=@add_orig; jit_cbs[OPPnone,OPcmps,OPSx_w]:=@add_orig; jit_cbs[OPPnone,OPcmps,OPSx_d]:=@add_orig; jit_cbs[OPPnone,OPcmps,OPSx_q]:=@add_orig; jit_cbs[OPPnone,OPmovs,OPSx_b]:=@add_orig; jit_cbs[OPPnone,OPmovs,OPSx_w]:=@add_orig; jit_cbs[OPPnone,OPmovs,OPSx_d]:=@add_orig; jit_cbs[OPPnone,OPmovs,OPSx_q]:=@add_orig; jit_cbs[OPPnone,OPstos,OPSx_b]:=@add_orig; jit_cbs[OPPnone,OPstos,OPSx_w]:=@add_orig; jit_cbs[OPPnone,OPstos,OPSx_d]:=@add_orig; jit_cbs[OPPnone,OPstos,OPSx_q]:=@add_orig; jit_cbs[OPPnone,OPlods,OPSx_b]:=@add_orig; jit_cbs[OPPnone,OPlods,OPSx_w]:=@add_orig; jit_cbs[OPPnone,OPlods,OPSx_d]:=@add_orig; jit_cbs[OPPnone,OPlods,OPSx_q]:=@add_orig; jit_cbs[OPPnone,OPscas,OPSx_b]:=@add_orig; jit_cbs[OPPnone,OPscas,OPSx_w]:=@add_orig; jit_cbs[OPPnone,OPscas,OPSx_d]:=@add_orig; jit_cbs[OPPnone,OPscas,OPSx_q]:=@add_orig; end; // jit_cbs[OPPnone,OPxor ,OPSnone]:=@op_xor; jit_cbs[OPPnone,OPor ,OPSnone]:=@op_or; jit_cbs[OPPnone,OPand ,OPSnone]:=@op_and; jit_cbs[OPPnone,OPsub ,OPSnone]:=@op_sub; jit_cbs[OPPnone,OPsbb ,OPSnone]:=@op_sbb; jit_cbs[OPPnone,OPadd ,OPSnone]:=@op_add; jit_cbs[OPPnone,OPadc ,OPSnone]:=@op_adc; jit_cbs[OPPnone,OPimul,OPSnone]:=@op_imul; jit_cbs[OPPnone,OPmul ,OPSnone]:=@op_emit1_ro; jit_cbs[OPPnone,OPidiv,OPSnone]:=@op_emit1_ro; jit_cbs[OPPnone,OPdiv ,OPSnone]:=@op_emit1_ro; jit_cbs[OPPnone,OPbt ,OPSnone]:=@op_bt; jit_cbs[OPPnone,OPbtc ,OPSnone]:=@op_btc; jit_cbs[OPPnone,OPbts ,OPSnone]:=@op_bts; jit_cbs[OPPnone,OPbtr ,OPSnone]:=@op_btr; jit_cbs[OPPnone,OPbsf,OPSnone]:=@op_bsf; jit_cbs[OPPnone,OPbsr,OPSnone]:=@op_bsr; jit_cbs[OPPnone,OPxchg,OPSnone]:=@op_xchg; jit_cbs[OPPnone,OPmov ,OPSnone]:=@op_mov; jit_cbs[OPPnone,OPcmov__,OPSc_o ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_no ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_b ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_nb ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_z ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_nz ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_be ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_nbe]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_s ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_ns ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_p ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_np ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_l ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_nl ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_le ]:=@op_cmov; jit_cbs[OPPnone,OPcmov__,OPSc_nle]:=@op_cmov; jit_cbs[OPPnone,OPmovzx,OPSnone]:=@op_movzx; jit_cbs[OPPnone,OPmovsx,OPSnone]:=@op_movsx; jit_cbs[OPPnone,OPmov ,OPSc_be]:=@op_movbe; jit_cbs[OPPnone,OPmovsx,OPSx_d ]:=@op_movsxd; jit_cbs[OPPnone,OPtest,OPSnone]:=@op_test; jit_cbs[OPPnone,OPcmp ,OPSnone]:=@op_cmp; jit_cbs[OPPnone,OPcmpxchg,OPSnone ]:=@op_cmpxchg; jit_cbs[OPPnone,OPcmpxchg,OPSx_8b ]:=@op_cmpxchg_8b_16b; jit_cbs[OPPnone,OPcmpxchg,OPSx_16b]:=@op_cmpxchg_8b_16b; jit_cbs[OPPnone,OPxadd ,OPSnone]:=@op_xadd; jit_cbs[OPPnone,OPlzcnt ,OPSnone]:=@op_lzcnt; jit_cbs[OPPnone,OPtzcnt ,OPSnone]:=@op_tzcnt; jit_cbs[OPPnone,OPpopcnt ,OPSnone]:=@op_popcnt; jit_cbs[OPPnone,OPcrc32 ,OPSnone]:=@op_crc32; jit_cbs[OPPnone,OProl ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPror ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPrcl ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPrcr ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPshl ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPshr ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPsar ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPsal ,OPSnone]:=@op_shift2_gen; jit_cbs[OPPnone,OPshl ,OPSx_d ]:=@op_shld; jit_cbs[OPPnone,OPshr ,OPSx_d ]:=@op_shrd; jit_cbs[OPPnone,OPset__,OPSc_o ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_no ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_b ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_nb ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_z ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_nz ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_be ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_nbe]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_s ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_ns ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_p ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_np ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_l ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_nl ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_le ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPset__,OPSc_nle]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPemms ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfemms ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPvzeroall ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPvzeroupper,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPpause,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPlfence,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPmfence,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPsfence,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcmc,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcli ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPsti ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPclac,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPclc ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcld ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPstc ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPstd ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcwd ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcdq ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcqo ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcbw ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcwde,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPcdqe,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPgetbv,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPrdpmc,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPlea,OPSnone]:=@op_lea; jit_cbs[OPPnone,OPinc,OPSnone]:=@op_emit1_rw; jit_cbs[OPPnone,OPdec,OPSnone]:=@op_emit1_rw; jit_cbs[OPPnone,OPneg,OPSnone]:=@op_emit1_rw; jit_cbs[OPPnone,OPnot,OPSnone]:=@op_emit1_rw; jit_cbs[OPPnone,OPbswap,OPSnone]:=@op_bswap; jit_cbs[OPPnone,OPsahf,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPlahf,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPxlat,OPSnone]:=@add_orig; //fpu jit_cbs[OPPnone,OPfninit ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfrndint ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfchs ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfxch ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_b ]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_e ]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_be ]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_u ]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_nb ]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_ne ]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_nbe]:=@add_orig; jit_cbs[OPPnone,OPfcmov__ ,OPSc_nu ]:=@add_orig; jit_cbs[OPPnone,OPfld1 ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfldl2e,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfldl2t,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfldlg2,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfldln2,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfldpi ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfldz ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfucom,OPSx_i ]:=@add_orig; jit_cbs[OPPnone,OPfucom,OPSx_ip]:=@add_orig; jit_cbs[OPPnone,OPfucom,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfcom,OPSx_i ]:=@add_orig; jit_cbs[OPPnone,OPfcom,OPSx_ip]:=@add_orig; jit_cbs[OPPnone,OPfcom,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfadd ,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfsub ,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfsubr ,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfmul ,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfdiv ,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfdivr ,OPSx_p ]:=@add_orig; jit_cbs[OPPnone,OPfsqrt ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfabs ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfscale ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfprem ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfprem1 ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfxtract,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfwait ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfnclex ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfsin ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfcos ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfsincos,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfpatan ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfptan ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfyl2x ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfyl2xp1,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPf2xm1 ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfdecstp,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPffree ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfincstp,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPftst ,OPSnone]:=@add_orig; jit_cbs[OPPnone,OPfxam ,OPSnone]:=@add_orig; // jit_cbs[OPPnone,OPfldcw ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfld ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfild ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfldenv ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfnstenv,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfnstcw ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfnstsw ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfxsave ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfxrstor,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfst ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfst ,OPSx_p ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfist ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfist ,OPSx_p ]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfisttp ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfadd ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfiadd ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfmul ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfimul ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfsub ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfsubr ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfisub ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfdiv ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfdivr ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfidiv ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPfidivr ,OPSnone]:=@op_emit1_ro_np; jit_cbs[OPPnone,OPclflush,OPSnone]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPfnsave ,OPSnone]:=@op_emit1_gn_np; jit_cbs[OPPnone,OPfsave ,OPSnone]:=@op_emit1_gn_np; //fpu jit_cbs[OPPnone,OPprefetch,OPSnone ]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPprefetch,OPSp_w ]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPprefetch,OPSp_nta]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPprefetch,OPSp_t0 ]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPprefetch,OPSp_t1 ]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPprefetch,OPSp_t2 ]:=@op_emit1_rw_np; jit_cbs[OPPnone,OPfbstp,OPSnone ]:=@op_emit1_wo_np; end; initialization init_cbs; end.