From 67aa148602b511010c6c99d7ce0863f81cbeef9d Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 15 Oct 2006 21:31:27 +0000 Subject: [PATCH] * fixed softfpu support + softfpu enabled for arm-gba git-svn-id: trunk@4939 - --- compiler/arm/narmcnv.pas | 34 +++++++++++++++++++++++++++++++++- compiler/nadd.pas | 28 +++++++++++++++++++++++----- compiler/ncnv.pas | 35 +++++++++++++++++++++++++++++++++-- compiler/nmat.pas | 19 ++++++++++++++----- compiler/options.pas | 4 ++-- compiler/pmodules.pas | 4 +++- 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/compiler/arm/narmcnv.pas b/compiler/arm/narmcnv.pas index 3613c21c8a..f190384346 100644 --- a/compiler/arm/narmcnv.pas +++ b/compiler/arm/narmcnv.pas @@ -110,7 +110,39 @@ implementation end else begin - internalerror(2005082803); + { converting a 64bit integer to a float requires a helper } + if is_64bitint(left.resulttype.def) or + is_currency(left.resulttype.def) then + begin + { hack to avoid double division by 10000, as it's + already done by resulttypepass.resulttype_int_to_real } + if is_currency(left.resulttype.def) then + left.resulttype := s64inttype; + if is_signed(left.resulttype.def) then + fname:='int64_to_' + else + { we can't do better currently } + fname:='int64_to_'; + end + else + { other integers are supposed to be 32 bit } + begin + if is_signed(left.resulttype.def) then + fname:='int32_to_' + else + { we can't do better currently } + fname:='int32_to_'; + firstpass(left); + end; + if tfloatdef(resulttype.def).typ=s64real then + fname:=fname+'float64' + else + fname:=fname+'float32'; + result:=ctypeconvnode.create_internal(ccallnode.createintern(fname,ccallparanode.create( + left,nil)),resulttype); + left:=nil; + firstpass(result); + exit; end; end else diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 12675c6e05..c7aa9e60c6 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -1187,7 +1187,7 @@ implementation if is_big_untyped_addrnode(right) then CGMessage1(type_w_untyped_arithmetic_unportable,node2opstr(nodetype)); inserttypeconv(right,left.resulttype) - end + end else if is_voidpointer(left.resulttype.def) then inserttypeconv(left,right.resulttype) else if not(equal_defs(ld,rd)) then @@ -2101,6 +2101,7 @@ implementation procname: string[31]; { do we need to reverse the result ? } notnode : boolean; + floattype : ttype; begin result := nil; notnode := false; @@ -2114,9 +2115,15 @@ implementation begin case tfloatdef(left.resulttype.def).typ of s32real: - procname:='float32'; + begin + floattype:=search_system_type('FLOAT32REC').restype; + procname:='float32'; + end; s64real: - procname:='float64'; + begin + floattype:=search_system_type('FLOAT64').restype; + procname:='float64'; + end; {!!! not yet implemented s128real: } @@ -2197,8 +2204,19 @@ implementation end; end; - result:=ccallnode.createintern(procname,ccallparanode.create(right, - ccallparanode.create(left,nil))); + { cast softfpu result? } + if not(target_info.system in system_wince) then + begin + if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then + resulttype:=booltype; + result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create( + ctypeconvnode.create_internal(right,floattype), + ccallparanode.create( + ctypeconvnode.create_internal(left,floattype),nil))),resulttype); + end + else + result:=ccallnode.createintern(procname,ccallparanode.create(right, + ccallparanode.create(left,nil))); left:=nil; right:=nil; diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index eaae404a51..274e9ad034 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -2012,8 +2012,39 @@ implementation end else begin - {!! FIXME } - internalerror(2005082701); + case tfloatdef(left.resulttype.def).typ of + s32real: + case tfloatdef(resulttype.def).typ of + s64real: + result:=ctypeconvnode.create_explicit(ccallnode.createintern('float32_to_float64',ccallparanode.create( + ctypeconvnode.create_internal(left,search_system_type('FLOAT32REC').restype),nil)),resulttype); + s32real: + begin + result:=left; + left:=nil; + end; + else + internalerror(200610151); + end; + s64real: + case tfloatdef(resulttype.def).typ of + s32real: + result:=ctypeconvnode.create_explicit(ccallnode.createintern('float64_to_float32',ccallparanode.create( + ctypeconvnode.create_internal(left,search_system_type('FLOAT64').restype),nil)),resulttype); + s64real: + begin + result:=left; + left:=nil; + end; + else + internalerror(200610152); + end; + else + internalerror(200610153); + end; + left:=nil; + firstpass(result); + exit; end; end else diff --git a/compiler/nmat.pas b/compiler/nmat.pas index 71cbb4eddd..31e173a005 100644 --- a/compiler/nmat.pas +++ b/compiler/nmat.pas @@ -90,7 +90,8 @@ implementation systems, verbose,globals,cutils, globtype, - symconst,symtype,symdef,defutil, + symconst,symtype,symdef,symtable, + defutil, htypechk,pass_1, cgbase, ncon,ncnv,ncal,nadd; @@ -663,6 +664,7 @@ implementation function tunaryminusnode.pass_1 : tnode; var procname: string[31]; + floattype : ttype; begin result:=nil; firstpass(left); @@ -675,17 +677,24 @@ implementation begin case tfloatdef(resulttype.def).typ of s32real: - procname:='float32_sub'; + begin + procname:='float32_sub'; + floattype:=search_system_type('FLOAT32REC').restype; + end; s64real: - procname:='float64_sub'; + begin + procname:='float64_sub'; + floattype:=search_system_type('FLOAT64').restype; + end; {!!! not yet implemented s128real: } else internalerror(2005082801); end; - result:=ccallnode.createintern(procname,ccallparanode.create(crealconstnode.create(0,resulttype), - ccallparanode.create(left,nil))); + result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create( + ctypeconvnode.create_internal(crealconstnode.create(0,resulttype),floattype), + ccallparanode.create(ctypeconvnode.create_internal(left,floattype),nil))),resulttype); end else begin diff --git a/compiler/options.pas b/compiler/options.pas index b3f73443e2..b8ba8b380a 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -2248,8 +2248,8 @@ begin (cs_profile in initmoduleswitches) then exclude(initglobalswitches,cs_link_strip); - { force fpu emulation on arm/wince } - if target_info.system=system_arm_wince then + { force fpu emulation on arm/wince and arm/gba } + if target_info.system in [system_arm_wince,system_arm_gba] then include(initmoduleswitches,cs_fp_emulation); { Section smartlinking conflicts with import sections on Windows } diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 5f6910eeaa..9a438b6bd1 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -494,9 +494,11 @@ implementation if (cs_gdb_valgrind in aktglobalswitches) then AddUnit('CMem'); {$ifdef cpufpemu} - { Floating point emulation unit? } + { Floating point emulation unit? + softfpu must be in the system unit anyways (FK) if (cs_fp_emulation in aktmoduleswitches) and not(target_info.system in system_wince) then AddUnit('SoftFpu'); + } {$endif cpufpemu} end; { Objpas unit? }