mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 20:12:55 +01:00 
			
		
		
		
	* more x86_64 assembler support, rtl compilation works, executables don't work yet
git-svn-id: trunk@3038 -
This commit is contained in:
		
							parent
							
								
									5519158dff
								
							
						
					
					
						commit
						4c9a08b12b
					
				| @ -1491,27 +1491,43 @@ implementation | ||||
| 
 | ||||
|            { base } | ||||
|            case br of | ||||
|              NR_R8, | ||||
|              NR_RAX : base:=0; | ||||
|              NR_R9, | ||||
|              NR_RCX : base:=1; | ||||
|              NR_R10, | ||||
|              NR_RDX : base:=2; | ||||
|              NR_R11, | ||||
|              NR_RBX : base:=3; | ||||
|              NR_R12, | ||||
|              NR_RSP : base:=4; | ||||
|              NR_R13, | ||||
|              NR_NO, | ||||
|              NR_RBP : base:=5; | ||||
|              NR_R14, | ||||
|              NR_RSI : base:=6; | ||||
|              NR_R15, | ||||
|              NR_RDI : base:=7; | ||||
|            else | ||||
|              exit; | ||||
|            end; | ||||
|            { index } | ||||
|            case ir of | ||||
|              NR_R8, | ||||
|              NR_RAX : index:=0; | ||||
|              NR_R9, | ||||
|              NR_RCX : index:=1; | ||||
|              NR_R10, | ||||
|              NR_RDX : index:=2; | ||||
|              NR_R11, | ||||
|              NR_RBX : index:=3; | ||||
|              NR_R12, | ||||
|              NR_NO  : index:=4; | ||||
|              NR_R13, | ||||
|              NR_RBP : index:=5; | ||||
|              NR_R14, | ||||
|              NR_RSI : index:=6; | ||||
|              NR_R15, | ||||
|              NR_RDI : index:=7; | ||||
|            else | ||||
|              exit; | ||||
| @ -1709,6 +1725,9 @@ implementation | ||||
|       begin | ||||
|         len:=0; | ||||
|         codes:=@p^.code; | ||||
| {$ifdef x86_64} | ||||
|         rex:=0; | ||||
| {$endif x86_64} | ||||
|         repeat | ||||
|           c:=ord(codes^); | ||||
|           inc(codes); | ||||
| @ -1727,7 +1746,11 @@ implementation | ||||
|                   (getsupreg(oper[c-8]^.reg)>=RS_R8)) or | ||||
|                   ((getregtype(oper[c-8]^.reg)=R_MMREGISTER) and | ||||
|                   (getsupreg(oper[c-8]^.reg)>=RS_XMM8)) then | ||||
|                   rex:=rex or $41; | ||||
|                   begin | ||||
|                     if rex=0 then | ||||
|                       inc(len); | ||||
|                     rex:=rex or $41; | ||||
|                   end; | ||||
| {$endif x86_64} | ||||
|                 inc(codes); | ||||
|                 inc(len); | ||||
| @ -1776,8 +1799,9 @@ implementation | ||||
| {$ifdef x86_64} | ||||
|                   OT_BITS64: | ||||
|                     begin | ||||
|                       if rex=0 then | ||||
|                         inc(len); | ||||
|                       rex:=rex or $48; | ||||
|                       inc(len); | ||||
|                     end; | ||||
| {$endif x86_64} | ||||
|                 end; | ||||
| @ -1808,6 +1832,22 @@ implementation | ||||
|             64..191 : | ||||
|               begin | ||||
| {$ifdef x86_64} | ||||
|                  if (c<127) then | ||||
|                   begin | ||||
|                     if (oper[c and 7]^.typ=top_reg) then | ||||
|                       begin | ||||
|                         if ((getregtype(oper[c and 7]^.reg)=R_INTREGISTER) and | ||||
|                           (getsupreg(oper[c and 7]^.reg)>=RS_R8)) or | ||||
|                           ((getregtype(oper[c and 7]^.reg)=R_MMREGISTER) and | ||||
|                           (getsupreg(oper[c and 7]^.reg)>=RS_XMM8)) then | ||||
|                           begin | ||||
|                             if rex=0 then | ||||
|                               inc(len); | ||||
|                             rex:=rex or $44; | ||||
|                           end; | ||||
|                       end; | ||||
|                   end; | ||||
| 
 | ||||
|                 ea_data.rex:=0; | ||||
|                 ea_data.rex_present:=false; | ||||
| {$endif x86_64} | ||||
| @ -1924,7 +1964,7 @@ implementation | ||||
| {$endif extdebug} | ||||
|         { safety check } | ||||
|         if objdata.currobjsec.size<>insoffset then | ||||
|           internalerror(200130121); | ||||
|            internalerror(200130121); | ||||
|         { load data to write } | ||||
|         codes:=insentry^.code; | ||||
|         { Force word push/pop for registers } | ||||
| @ -1942,6 +1982,16 @@ implementation | ||||
|               break; | ||||
|             1,2,3 : | ||||
|               begin | ||||
| {$ifdef x86_64} | ||||
|                 if rex<>0 then | ||||
|                   begin | ||||
|                     bytes[0]:=rex; | ||||
| {$ifdef extdebug} | ||||
|                     rexwritten:=true; | ||||
| {$endif extdebug} | ||||
|                     objdata.writebytes(bytes,1); | ||||
|                   end; | ||||
| {$endif x86_64} | ||||
|                 objdata.writebytes(codes^,c); | ||||
|                 inc(codes,c); | ||||
|               end; | ||||
| @ -1981,11 +2031,23 @@ implementation | ||||
|             8,9,10 : | ||||
|               begin | ||||
|                 { rex should be written at this point } | ||||
| { | ||||
| {$ifdef x86_64} | ||||
| {$ifdef extdebug} | ||||
|                 if (rex<>0) and not(rexwritten) then | ||||
|                   internalerror(200603192); | ||||
| {$endif extdebug} | ||||
| {$endif x86_64} | ||||
| } | ||||
| {$ifdef x86_64} | ||||
|                 if rex<>0 then | ||||
|                   begin | ||||
|                     bytes[0]:=rex; | ||||
| {$ifdef extdebug} | ||||
|                     rexwritten:=true; | ||||
| {$endif extdebug} | ||||
|                     objdata.writebytes(bytes,1); | ||||
|                   end; | ||||
| {$endif x86_64} | ||||
|                 bytes[0]:=ord(codes^)+regval(oper[c-8]^.reg); | ||||
|                 inc(codes); | ||||
| @ -2120,6 +2182,7 @@ implementation | ||||
|                       Message(asmw_e_64bit_not_supported); | ||||
| {$endif x86_64} | ||||
|                 end; | ||||
| { | ||||
| {$ifdef x86_64} | ||||
|                 if rex<>0 then | ||||
|                   begin | ||||
| @ -2130,6 +2193,7 @@ implementation | ||||
|                     objdata.writebytes(bytes,1); | ||||
|                   end; | ||||
| {$endif x86_64} | ||||
| } | ||||
|               end; | ||||
|             212 : | ||||
|               begin | ||||
|  | ||||
| @ -242,65 +242,72 @@ begin | ||||
|       operands[i].SetCorrectSize(opcode); | ||||
|       if tx86operand(operands[i]).opsize=S_NO then | ||||
|         begin | ||||
|           case operands[i].Opr.Typ of | ||||
|             OPR_LOCAL, | ||||
|             OPR_REFERENCE : | ||||
|               begin | ||||
|                 if i=2 then | ||||
|                  operand2:=1 | ||||
|                 else | ||||
|                  operand2:=2; | ||||
|                 if operand2<ops then | ||||
|                  begin | ||||
|                    { Only allow register as operand to take the size from } | ||||
|                    if operands[operand2].opr.typ=OPR_REGISTER then | ||||
|                      begin | ||||
|                        if ((opcode<>A_MOVD) and | ||||
|                            (opcode<>A_CVTSI2SS)) then | ||||
|                          tx86operand(operands[i]).opsize:=tx86operand(operands[operand2]).opsize; | ||||
|                      end | ||||
|                    else | ||||
|                     begin | ||||
|                       { if no register then take the opsize (which is available with ATT), | ||||
|                         if not availble then give an error } | ||||
|                       if opsize<>S_NO then | ||||
|                         tx86operand(operands[i]).opsize:=opsize | ||||
|                       else | ||||
|                        begin | ||||
|                          if (m_delphi in aktmodeswitches) then | ||||
|                            Message(asmr_w_unable_to_determine_reference_size_using_dword) | ||||
|                          else | ||||
|                            Message(asmr_e_unable_to_determine_reference_size); | ||||
|                          { recovery } | ||||
|                          tx86operand(operands[i]).opsize:=S_L; | ||||
|                        end; | ||||
|                     end; | ||||
|                  end | ||||
|                 else | ||||
|                  begin | ||||
|                    if opsize<>S_NO then | ||||
|                      tx86operand(operands[i]).opsize:=opsize | ||||
|                  end; | ||||
|               end; | ||||
|             OPR_SYMBOL : | ||||
|               begin | ||||
|                 { Fix lea which need a reference } | ||||
|                 if opcode=A_LEA then | ||||
|                  begin | ||||
|                    s:=operands[i].opr.symbol; | ||||
|                    so:=operands[i].opr.symofs; | ||||
|                    operands[i].opr.typ:=OPR_REFERENCE; | ||||
|                    Fillchar(operands[i].opr.ref,sizeof(treference),0); | ||||
|                    operands[i].opr.ref.symbol:=s; | ||||
|                    operands[i].opr.ref.offset:=so; | ||||
|                  end; | ||||
| {$ifdef x86_64} | ||||
|                 tx86operand(operands[i]).opsize:=S_Q; | ||||
| {$else x86_64} | ||||
|                 tx86operand(operands[i]).opsize:=S_L; | ||||
|           if (opcode=A_MOVQ) and | ||||
|              (ops=2) and | ||||
|              (operands[1].opr.typ=OPR_CONSTANT) then | ||||
|              opsize:=S_Q | ||||
|           else | ||||
| {$endif x86_64} | ||||
|               end; | ||||
|           end; | ||||
|             case operands[i].Opr.Typ of | ||||
|               OPR_LOCAL, | ||||
|               OPR_REFERENCE : | ||||
|                 begin | ||||
|                   if i=2 then | ||||
|                    operand2:=1 | ||||
|                   else | ||||
|                    operand2:=2; | ||||
|                   if operand2<ops then | ||||
|                    begin | ||||
|                      { Only allow register as operand to take the size from } | ||||
|                      if operands[operand2].opr.typ=OPR_REGISTER then | ||||
|                        begin | ||||
|                          if ((opcode<>A_MOVD) and | ||||
|                              (opcode<>A_CVTSI2SS)) then | ||||
|                            tx86operand(operands[i]).opsize:=tx86operand(operands[operand2]).opsize; | ||||
|                        end | ||||
|                      else | ||||
|                       begin | ||||
|                         { if no register then take the opsize (which is available with ATT), | ||||
|                           if not availble then give an error } | ||||
|                         if opsize<>S_NO then | ||||
|                           tx86operand(operands[i]).opsize:=opsize | ||||
|                         else | ||||
|                          begin | ||||
|                            if (m_delphi in aktmodeswitches) then | ||||
|                              Message(asmr_w_unable_to_determine_reference_size_using_dword) | ||||
|                            else | ||||
|                              Message(asmr_e_unable_to_determine_reference_size); | ||||
|                            { recovery } | ||||
|                            tx86operand(operands[i]).opsize:=S_L; | ||||
|                          end; | ||||
|                       end; | ||||
|                    end | ||||
|                   else | ||||
|                    begin | ||||
|                      if opsize<>S_NO then | ||||
|                        tx86operand(operands[i]).opsize:=opsize | ||||
|                    end; | ||||
|                 end; | ||||
|               OPR_SYMBOL : | ||||
|                 begin | ||||
|                   { Fix lea which need a reference } | ||||
|                   if opcode=A_LEA then | ||||
|                    begin | ||||
|                      s:=operands[i].opr.symbol; | ||||
|                      so:=operands[i].opr.symofs; | ||||
|                      operands[i].opr.typ:=OPR_REFERENCE; | ||||
|                      Fillchar(operands[i].opr.ref,sizeof(treference),0); | ||||
|                      operands[i].opr.ref.symbol:=s; | ||||
|                      operands[i].opr.ref.offset:=so; | ||||
|                    end; | ||||
|   {$ifdef x86_64} | ||||
|                   tx86operand(operands[i]).opsize:=S_Q; | ||||
|   {$else x86_64} | ||||
|                   tx86operand(operands[i]).opsize:=S_L; | ||||
|   {$endif x86_64} | ||||
|                 end; | ||||
|             end; | ||||
|         end; | ||||
|     end; | ||||
| end; | ||||
| @ -555,14 +562,15 @@ begin | ||||
|     end; | ||||
| 
 | ||||
| {$ifdef x86_64} | ||||
|   { Convert movq with at least one general registers to mov instruction } | ||||
|   { Convert movq with at least one general registers or constant to a mov instruction } | ||||
|   if (opcode=A_MOVQ) and | ||||
|      (ops=2) and | ||||
|      ( | ||||
|       (operands[1].opr.typ=OPR_REGISTER) or | ||||
|       (operands[2].opr.typ=OPR_REGISTER) | ||||
|       (operands[2].opr.typ=OPR_REGISTER) or | ||||
|       (operands[1].opr.typ=OPR_CONSTANT) | ||||
|      ) then | ||||
|     opcode:=A_MOV; | ||||
|      opcode:=A_MOV; | ||||
| {$endif x86_64} | ||||
| 
 | ||||
|    { GNU AS interprets FDIV without operand differently | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 florian
						florian