Browse Source

+ support for unaryminus for the JVM target (integer via generic code, float
JVM-specific code)

git-svn-id: branches/jvmbackend@18512 -

Jonas Maebe 14 years ago
parent
commit
80a63197e3
2 changed files with 33 additions and 5 deletions
  1. 22 0
      compiler/jvm/njvmmat.pas
  2. 11 5
      compiler/ncgmat.pas

+ 22 - 0
compiler/jvm/njvmmat.pas

@@ -41,6 +41,10 @@ interface
          procedure second_boolean;override;
       end;
 
+      tjvmunaryminusnode = class(tcgunaryminusnode)
+        procedure second_float;override;
+      end;
+
 implementation
 
     uses
@@ -192,8 +196,26 @@ implementation
       end;
 
 
+    procedure tjvmunaryminusnode.second_float;
+      var
+        opc: tasmop;
+      begin
+        secondpass(left);
+        location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+        location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
+        thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
+        if (tfloatdef(left.resultdef).floattype=s32real) then
+          opc:=a_fneg
+        else
+          opc:=a_dneg;
+        current_asmdata.CurrAsmList.concat(taicpu.op_none(opc));
+        thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
+      end;
+
+
 begin
    cmoddivnode:=tjvmmoddivnode;
    cshlshrnode:=tjvmshlshrnode;
    cnotnode:=tjvmnotnode;
+   cunaryminusnode:=tjvmunaryminusnode;
 end.

+ 11 - 5
compiler/ncgmat.pas

@@ -127,7 +127,7 @@ implementation
     uses
       globtype,systems,
       cutils,verbose,globals,
-      symconst,aasmbase,aasmtai,aasmdata,aasmcpu,defutil,
+      symconst,symtype,symdef,aasmbase,aasmtai,aasmdata,aasmcpu,defutil,
       parabase,
       pass_2,
       ncon,
@@ -233,19 +233,25 @@ implementation
     procedure tcgunaryminusnode.second_integer;
       var
         hl: tasmlabel;
+        opsize: tdef;
       begin
         secondpass(left);
         { load left operator in a register }
         location_copy(location,left.location);
-        location_force_reg(current_asmdata.CurrAsmList,location,OS_SINT,false);
-        cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,OS_SINT,location.register,location.register);
+        { in case of a 32 bit system that can natively execute 64 bit operations }
+        if (left.resultdef.size<=sinttype.size) then
+          opsize:=sinttype
+        else
+          opsize:=s64inttype;
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,opsize,false);
+        hlcg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,opsize,location.register,location.register);
 
         if (cs_check_overflow in current_settings.localswitches) then
           begin
             current_asmdata.getjumplabel(hl);
-            cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_SINT,OC_NE,low(aint),location.register,hl);
+            hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_NE,low(aint),location.register,hl);
             cg.a_call_name(current_asmdata.CurrAsmList,'FPC_OVERFLOW',false);
-            cg.a_label(current_asmdata.CurrAsmList,hl);
+            hlcg.a_label(current_asmdata.CurrAsmList,hl);
           end;
       end;