Browse Source

* proper implementation of ti8086addnode.second_cmp64bit

git-svn-id: branches/i8086@23871 -
nickysn 12 years ago
parent
commit
5dd5add67a
1 changed files with 80 additions and 18 deletions
  1. 80 18
      compiler/i8086/n8086add.pas

+ 80 - 18
compiler/i8086/n8086add.pas

@@ -264,15 +264,59 @@ interface
            end;
            end;
         end;
         end;
 
 
-      procedure secondjmp64bitcmp;
+      procedure middlejmp64bitcmp;
+
+        var
+           oldnodetype : tnodetype;
+
+        begin
+{$ifdef OLDREGVARS}
+           load_all_regvars(current_asmdata.CurrAsmList);
+{$endif OLDREGVARS}
+           { the jump the sequence is a little bit hairy }
+           case nodetype of
+              ltn,gtn:
+                begin
+                   { the comparisaion of the low word have to be }
+                   {  always unsigned!                           }
+                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrTrueLabel);
+                   { cheat a little bit for the negative test }
+                   toggleflag(nf_swapped);
+                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrFalseLabel);
+                   toggleflag(nf_swapped);
+                end;
+              lten,gten:
+                begin
+                   oldnodetype:=nodetype;
+                   if nodetype=lten then
+                     nodetype:=ltn
+                   else
+                     nodetype:=gtn;
+                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrTrueLabel);
+                   { cheat for the negative test }
+                   if nodetype=ltn then
+                     nodetype:=gtn
+                   else
+                     nodetype:=ltn;
+                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrFalseLabel);
+                   nodetype:=oldnodetype;
+                end;
+              equaln:
+                cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrFalseLabel);
+              unequaln:
+                cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrTrueLabel);
+           end;
+        end;
+
+      procedure lastjmp64bitcmp;
 
 
         begin
         begin
            { the jump the sequence is a little bit hairy }
            { the jump the sequence is a little bit hairy }
            case nodetype of
            case nodetype of
               ltn,gtn,lten,gten:
               ltn,gtn,lten,gten:
                 begin
                 begin
-                   { the comparisaion of the low dword have to be }
-                   {  always unsigned!                            }
+                   { the comparisaion of the low word have to be }
+                   {  always unsigned!                           }
                    cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrTrueLabel);
                    cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrTrueLabel);
                    cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
                    cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
                 end;
                 end;
@@ -306,8 +350,8 @@ interface
               { we can reuse a CREGISTER for comparison }
               { we can reuse a CREGISTER for comparison }
               if (left.location.loc<>LOC_CREGISTER) then
               if (left.location.loc<>LOC_CREGISTER) then
                begin
                begin
-                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                 hregister2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                 hregister2:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
                  cg64.a_load64_loc_reg(current_asmdata.CurrAsmList,left.location,joinreg64(hregister,hregister2));
                  cg64.a_load64_loc_reg(current_asmdata.CurrAsmList,left.location,joinreg64(hregister,hregister2));
                  location_freetemp(current_asmdata.CurrAsmList,left.location);
                  location_freetemp(current_asmdata.CurrAsmList,left.location);
                  location_reset(left.location,LOC_REGISTER,left.location.size);
                  location_reset(left.location,LOC_REGISTER,left.location.size);
@@ -325,40 +369,58 @@ interface
         { at this point, left.location.loc should be LOC_REGISTER }
         { at this point, left.location.loc should be LOC_REGISTER }
         if right.location.loc=LOC_REGISTER then
         if right.location.loc=LOC_REGISTER then
          begin
          begin
-           emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
+           emit_reg_reg(A_CMP,S_W,GetNextReg(right.location.register64.reghi),GetNextReg(left.location.register64.reghi));
            firstjmp64bitcmp;
            firstjmp64bitcmp;
-           emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
-           secondjmp64bitcmp;
+           emit_reg_reg(A_CMP,S_W,right.location.register64.reghi,left.location.register64.reghi);
+           middlejmp64bitcmp;
+           emit_reg_reg(A_CMP,S_W,GetNextReg(right.location.register64.reglo),GetNextReg(left.location.register64.reglo));
+           middlejmp64bitcmp;
+           emit_reg_reg(A_CMP,S_W,right.location.register64.reglo,left.location.register64.reglo);
+           lastjmp64bitcmp;
          end
          end
         else
         else
          begin
          begin
            case right.location.loc of
            case right.location.loc of
              LOC_CREGISTER :
              LOC_CREGISTER :
                begin
                begin
-                 emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
+                 emit_reg_reg(A_CMP,S_W,GetNextReg(right.location.register64.reghi),GetNextReg(left.location.register64.reghi));
                  firstjmp64bitcmp;
                  firstjmp64bitcmp;
-                 emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
-                 secondjmp64bitcmp;
+                 emit_reg_reg(A_CMP,S_W,right.location.register64.reghi,left.location.register64.reghi);
+                 middlejmp64bitcmp;
+                 emit_reg_reg(A_CMP,S_W,GetNextReg(right.location.register64.reglo),GetNextReg(left.location.register64.reglo));
+                 middlejmp64bitcmp;
+                 emit_reg_reg(A_CMP,S_W,right.location.register64.reglo,left.location.register64.reglo);
+                 lastjmp64bitcmp;
                end;
                end;
              LOC_CREFERENCE,
              LOC_CREFERENCE,
              LOC_REFERENCE :
              LOC_REFERENCE :
                begin
                begin
                  tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,right.location.reference);
                  tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,right.location.reference);
                  href:=right.location.reference;
                  href:=right.location.reference;
-                 inc(href.offset,4);
-                 emit_ref_reg(A_CMP,S_L,href,left.location.register64.reghi);
+                 inc(href.offset,6);
+                 emit_ref_reg(A_CMP,S_W,href,GetNextReg(left.location.register64.reghi));
                  firstjmp64bitcmp;
                  firstjmp64bitcmp;
-                 emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.register64.reglo);
-                 secondjmp64bitcmp;
+                 dec(href.offset,2);
+                 emit_ref_reg(A_CMP,S_W,href,left.location.register64.reghi);
+                 middlejmp64bitcmp;
+                 dec(href.offset,2);
+                 emit_ref_reg(A_CMP,S_W,href,GetNextReg(left.location.register64.reglo));
+                 middlejmp64bitcmp;
+                 emit_ref_reg(A_CMP,S_W,right.location.reference,left.location.register64.reglo);
+                 lastjmp64bitcmp;
                  cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
                  cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
                  location_freetemp(current_asmdata.CurrAsmList,right.location);
                  location_freetemp(current_asmdata.CurrAsmList,right.location);
                end;
                end;
              LOC_CONSTANT :
              LOC_CONSTANT :
                begin
                begin
-                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi));
+                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint((right.location.value64 shr 48) and $FFFF),GetNextReg(left.location.register64.reghi)));
                  firstjmp64bitcmp;
                  firstjmp64bitcmp;
-                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo));
-                 secondjmp64bitcmp;
+                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint((right.location.value64 shr 32) and $FFFF),left.location.register64.reghi));
+                 middlejmp64bitcmp;
+                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint((right.location.value64 shr 16) and $FFFF),GetNextReg(left.location.register64.reglo)));
+                 middlejmp64bitcmp;
+                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint(right.location.value64 and $FFFF),left.location.register64.reglo));
+                 lastjmp64bitcmp;
                end;
                end;
              else
              else
                internalerror(200203282);
                internalerror(200203282);