+ initial implementation of aarch64 type conversion nodes

git-svn-id: trunk@29867 -
This commit is contained in:
Jonas Maebe 2015-02-23 22:50:10 +00:00
parent 71ae8015da
commit 4aeb22f7f4
2 changed files with 145 additions and 0 deletions

1
.gitattributes vendored
View File

@ -23,6 +23,7 @@ compiler/aarch64/cpuinfo.pas svneol=native#text/plain
compiler/aarch64/cpupara.pas svneol=native#text/plain
compiler/aarch64/itcpugas.pas svneol=native#text/plain
compiler/aarch64/ncpuadd.pas svneol=native#text/plain
compiler/aarch64/ncpucnv.pas svneol=native#text/plain
compiler/aarch64/ncpuinl.pas svneol=native#text/plain
compiler/aarch64/ra64con.inc svneol=native#text/plain
compiler/aarch64/ra64dwa.inc svneol=native#text/plain

View File

@ -0,0 +1,144 @@
{
Copyright (c) 2014 by Jonas Maebe
Generate AArch64 assembler for type converting nodes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************}
unit ncpucnv;
{$i fpcdefs.inc}
interface
uses
node,ncnv,ncgcnv;
type
taarch64typeconvnode = class(TCgTypeConvNode)
protected
function typecheck_int_to_real: tnode; override;
function first_int_to_real: tnode; override;
{ procedure second_int_to_int;override; }
{ procedure second_string_to_string;override; }
{ procedure second_cstring_to_pchar;override; }
{ procedure second_string_to_chararray;override; }
{ procedure second_array_to_pointer;override; }
{ procedure second_pointer_to_array;override; }
{ procedure second_chararray_to_string;override; }
{ procedure second_char_to_string;override; }
procedure second_int_to_real;override;
{ procedure second_real_to_real;override; }
{ procedure second_cord_to_pointer;override; }
{ procedure second_proc_to_procvar;override; }
{ procedure second_bool_to_int;override; }
{ procedure second_int_to_bool;override; }
{ procedure second_load_smallset;override; }
{ procedure second_ansistring_to_pchar;override; }
{ procedure second_pchar_to_string;override; }
{ procedure second_class_to_intf;override; }
{ procedure second_char_to_char;override; }
end;
implementation
uses
verbose,
symdef,aasmdata,
defutil,
cgbase,cgutils,
cpubase,aasmcpu,
cgobj,
hlcgobj;
{*****************************************************************************
FirstTypeConv
*****************************************************************************}
function taarch64typeconvnode.typecheck_int_to_real: tnode;
begin
{ aarch64 supports converting everything to floating point, even fixed
point! Unfortunately, it only supports fixed point with a power-of-2
fraction, which is not the case for currency.
Generate the division by 10000 via nodes so the 10000.0 constant can
be reused. }
if is_currency(resultdef) and
not(nf_is_currency in flags) then
begin
{ convert the equivalent int64 value to double without conversion
(internal typecast -> will set nf_is_currency flag) }
result:=ctypeconvnode.create_internal(left,s64floattype);
{ turn into currency with conversion, which will divide by 10000
(regular typecast) }
result:=ctypeconvnode.create(result,s64currencytype);
exit;
end;
{ The only other thing we have to take care of: convert values < 32 bit
to 32 bit }
if left.resultdef.size<4 then
begin
if is_signed(left.resultdef) then
inserttypeconv(left,s32inttype)
else
inserttypeconv(left,u32inttype)
end;
result:=inherited;
end;
function taarch64typeconvnode.first_int_to_real: tnode;
begin
result:=nil;
expectloc:=LOC_MMREGISTER;
end;
{*****************************************************************************
SecondTypeConv
*****************************************************************************}
procedure taarch64typeconvnode.second_int_to_real;
var
op: tasmop;
begin
location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
internalerror(2014120401);
case left.location.size of
OS_32,
OS_64:
op:=A_UCVTF;
OS_S32,
OS_S64,
{ for currency and comp }
OS_F64:
op:=A_SCVTF;
else
internalerror(2014120402);
end;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register));
{ no scaling for currency, that's handled in pass_typecheck }
end;
begin
ctypeconvnode:=taarch64typeconvnode;
end.