Browse Source

* no longer associated defs with size 1 to 3 bytes with paralocs, because
gcc and clang always allocate them in multiple of 4 bytes too (except in
case of _Bool, which is 1 byte -> do the same for PasBool) and this is
one possible interpretation of the ABI. This also frees us from having to
perform special adjustments afterwards to ensure that smaller values are
sign/zero-extended to 32 bits

git-svn-id: branches/hlcgllvm@26993 -

Jonas Maebe 11 years ago
parent
commit
68fa17593d
1 changed files with 8 additions and 33 deletions
  1. 8 33
      compiler/x86_64/cpupara.pas

+ 8 - 33
compiler/x86_64/cpupara.pas

@@ -171,15 +171,13 @@ unit cpupara;
            if size<=4 then
              begin
                cl.typ:=X86_64_INTEGERSI_CLASS;
+               { gcc/clang sign/zero-extend all values to 32 bits, except for
+                 _Bool (= Pascal boolean), which is only zero-extended to 8 bits
+                 as per the x86-64 ABI -> do the same }
                if not assigned(cl.def) or
-                  (cl.def.size<size) then
-                 begin
-                   case size of
-                     1: cl.def:=u8inttype;
-                     2: cl.def:=u16inttype;
-                     3,4: cl.def:=u32inttype;
-                   end;
-                 end;
+                  not is_pasbool(cl.def) or
+                  (size>1) then
+                 cl.def:=u32inttype;
              end
            else
              begin
@@ -907,17 +905,6 @@ unit cpupara;
         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
 
-        { integer sizes < 32 bit have to be sign/zero extended to 32 bit on
-          the callee side (caller can expect those bits are valid) }
-        if (side=calleeside) and
-           (retcgsize in [OS_8,OS_S8,OS_16,OS_S16]) then
-          begin
-            retcgsize:=OS_S32;
-            result.def:=s32inttype;
-            result.intsize:=4;
-            result.size:=retcgsize;
-          end;
-
         { Return in FPU register? -> don't use classify_argument(), because
           currency and comp need special treatment here (they are integer class
           when passing as parameter, but LOC_FPUREGISTER as function result) }
@@ -984,8 +971,7 @@ unit cpupara;
                         end
                       else if result.intsize in [1,2,4] then
                         begin
-                          paraloc^.size:=retcgsize;
-                          paraloc^.def:=result.def;
+                          paraloc^.size:=def_cgsize(paraloc^.def);
                         end
                       else
                         begin
@@ -1078,16 +1064,6 @@ unit cpupara;
                 getvalueparaloc(hp.varspez,paradef,loc[1],loc[2]);
                 paralen:=push_size(hp.varspez,paradef,p.proccalloption);
                 paracgsize:=def_cgsize(paradef);
-                { integer sizes < 32 bit have to be sign/zero extended to 32 bit
-                  on the caller side }
-                if (side=callerside) and
-                   (paracgsize in [OS_8,OS_S8,OS_16,OS_S16]) then
-                  begin
-                    paracgsize:=OS_S32;
-                    paralen:=4;
-                    paradef:=s32inttype;
-                    loc[1].def:=paradef;
-                  end;
               end;
 
             { cheat for now, we should copy the value to an mm reg as well (FK) }
@@ -1179,8 +1155,7 @@ unit cpupara;
                             end
                           else
                             begin
-                              paraloc^.size:=paracgsize;
-                              paraloc^.def:=paradef;
+                              paraloc^.size:=def_cgsize(paraloc^.def);
                               { s64comp is pushed in an int register }
                               if paraloc^.size=OS_C64 then
                                 begin