From cf6f408214285c794a4893c63d11a57bff846761 Mon Sep 17 00:00:00 2001 From: nickysn <nickysn@gmail.com> Date: Fri, 3 Jan 2014 03:31:51 +0000 Subject: [PATCH] + implemented the tcg8086.a_cmp_*_*_label methods for i8086. How did the i8086 code generator even work without these? git-svn-id: trunk@26362 - --- compiler/i8086/cgcpu.pas | 185 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/compiler/i8086/cgcpu.pas b/compiler/i8086/cgcpu.pas index c14ce9867d..f63d2ac27e 100644 --- a/compiler/i8086/cgcpu.pas +++ b/compiler/i8086/cgcpu.pas @@ -73,6 +73,18 @@ unit cgcpu; procedure a_load_ref_reg(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);override; procedure a_load_reg_reg(list : TAsmList;fromsize,tosize: tcgsize;reg1,reg2 : tregister);override; + { comparison operations } + procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister; + l : tasmlabel);override; + procedure a_cmp_const_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;const ref : treference; + l : tasmlabel);override; + procedure a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override; + procedure a_cmp_ref_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;const ref: treference; reg : tregister; l : tasmlabel); override; + procedure a_cmp_reg_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg : tregister; const ref: treference; l : tasmlabel); override; + + procedure gen_cmp32_jmp1(list: TAsmList; cmp_op: topcmp; l_skip, l_target: TAsmLabel); + procedure gen_cmp32_jmp2(list: TAsmList; cmp_op: topcmp; l_skip, l_target: TAsmLabel); + procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);override; procedure g_flags2ref(list: TAsmList; size: TCgSize; const f: tresflags; const ref: TReference);override; @@ -1403,6 +1415,179 @@ unit cgcpu; end; + procedure tcg8086.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); + var + hl_skip: TAsmLabel; + begin + if size in [OS_32, OS_S32] then + begin + if (longint(a shr 16) = 0) then + list.concat(taicpu.op_reg_reg(A_TEST,S_W,GetNextReg(reg),GetNextReg(reg))) + else + list.concat(taicpu.op_const_reg(A_CMP,S_W,longint(a shr 16),GetNextReg(reg))); + current_asmdata.getjumplabel(hl_skip); + gen_cmp32_jmp1(list, cmp_op, hl_skip, l); + + if (longint(a and $ffff) = 0) then + list.concat(taicpu.op_reg_reg(A_TEST,S_W,reg,reg)) + else + list.concat(taicpu.op_const_reg(A_CMP,S_W,longint(a and $ffff),reg)); + gen_cmp32_jmp2(list, cmp_op, hl_skip, l); + a_label(list,hl_skip); + end + else + inherited a_cmp_const_reg_label(list, size, cmp_op, a, reg, l); + end; + + + procedure tcg8086.a_cmp_const_ref_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; const ref: treference; l: tasmlabel); + var + tmpref: treference; + hl_skip: TAsmLabel; + begin + if size in [OS_32, OS_S32] then + begin + tmpref:=ref; + make_simple_ref(list,tmpref); + inc(tmpref.offset,2); + list.concat(taicpu.op_const_ref(A_CMP,S_W,longint(a shr 16),tmpref)); + current_asmdata.getjumplabel(hl_skip); + gen_cmp32_jmp1(list, cmp_op, hl_skip, l); + dec(tmpref.offset,2); + list.concat(taicpu.op_const_ref(A_CMP,S_W,longint(a and $ffff),tmpref)); + gen_cmp32_jmp2(list, cmp_op, hl_skip, l); + a_label(list,hl_skip); + end + else + inherited a_cmp_const_ref_label(list, size, cmp_op, a, ref, l); + end; + + + procedure tcg8086.a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel); + var + hl_skip: TAsmLabel; + begin + if size in [OS_32, OS_S32] then + begin + check_register_size(size,reg1); + check_register_size(size,reg2); + list.concat(taicpu.op_reg_reg(A_CMP,S_W,GetNextReg(reg1),GetNextReg(reg2))); + current_asmdata.getjumplabel(hl_skip); + gen_cmp32_jmp1(list, cmp_op, hl_skip, l); + list.concat(taicpu.op_reg_reg(A_CMP,S_W,reg1,reg2)); + gen_cmp32_jmp2(list, cmp_op, hl_skip, l); + a_label(list,hl_skip); + end + else + inherited a_cmp_reg_reg_label(list, size, cmp_op, reg1, reg2, l); + end; + + + procedure tcg8086.a_cmp_ref_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; const ref: treference; reg: tregister; l: tasmlabel); + var + tmpref: treference; + hl_skip: TAsmLabel; + begin + if size in [OS_32, OS_S32] then + begin + tmpref:=ref; + make_simple_ref(list,tmpref); + check_register_size(size,reg); + inc(tmpref.offset,2); + list.concat(taicpu.op_ref_reg(A_CMP,S_W,tmpref,GetNextReg(reg))); + current_asmdata.getjumplabel(hl_skip); + gen_cmp32_jmp1(list, cmp_op, hl_skip, l); + dec(tmpref.offset,2); + list.concat(taicpu.op_ref_reg(A_CMP,S_W,tmpref,reg)); + gen_cmp32_jmp2(list, cmp_op, hl_skip, l); + a_label(list,hl_skip); + end + else + inherited a_cmp_ref_reg_label(list, size, cmp_op, ref, reg, l); + end; + + + procedure tcg8086.a_cmp_reg_ref_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg: tregister; const ref: treference; l: tasmlabel); + var + tmpref: treference; + hl_skip: TAsmLabel; + begin + if size in [OS_32, OS_S32] then + begin + tmpref:=ref; + make_simple_ref(list,tmpref); + check_register_size(size,reg); + inc(tmpref.offset,2); + list.concat(taicpu.op_reg_ref(A_CMP,S_W,GetNextReg(reg),tmpref)); + current_asmdata.getjumplabel(hl_skip); + gen_cmp32_jmp1(list, cmp_op, hl_skip, l); + dec(tmpref.offset,2); + list.concat(taicpu.op_reg_ref(A_CMP,S_W,reg,tmpref)); + gen_cmp32_jmp2(list, cmp_op, hl_skip, l); + a_label(list,hl_skip); + end + else + inherited a_cmp_reg_ref_label(list, size, cmp_op, reg, ref, l); + end; + + + procedure tcg8086.gen_cmp32_jmp1(list: TAsmList; cmp_op: topcmp; l_skip, l_target: TAsmLabel); + begin + case cmp_op of + OC_EQ: + a_jmp_cond(list, OC_NE, l_skip); + OC_GT: + a_jmp_cond(list, OC_LT, l_skip); + OC_LT: + a_jmp_cond(list, OC_GT, l_skip); + OC_GTE: + a_jmp_cond(list, OC_LT, l_skip); + OC_LTE: + a_jmp_cond(list, OC_GT, l_skip); + OC_NE: + a_jmp_cond(list, OC_NE, l_target); + OC_BE: + a_jmp_cond(list, OC_A, l_skip); + OC_B: + a_jmp_cond(list, OC_A, l_skip); + OC_AE: + a_jmp_cond(list, OC_B, l_skip); + OC_A: + a_jmp_cond(list, OC_B, l_skip); + else + internalerror(2014010305); + end; + end; + + procedure tcg8086.gen_cmp32_jmp2(list: TAsmList; cmp_op: topcmp; l_skip, l_target: TAsmLabel); + begin + case cmp_op of + OC_EQ: + a_jmp_cond(list, OC_EQ, l_target); + OC_GT: + a_jmp_cond(list, OC_A, l_target); + OC_LT: + a_jmp_cond(list, OC_B, l_target); + OC_GTE: + a_jmp_cond(list, OC_AE, l_target); + OC_LTE: + a_jmp_cond(list, OC_BE, l_target); + OC_NE: + a_jmp_cond(list, OC_NE, l_target); + OC_BE: + a_jmp_cond(list, OC_BE, l_target); + OC_B: + a_jmp_cond(list, OC_B, l_target); + OC_AE: + a_jmp_cond(list, OC_AE, l_target); + OC_A: + a_jmp_cond(list, OC_A, l_target); + else + internalerror(2014010306); + end; + end; + + procedure tcg8086.g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister); var ai : taicpu;