diff options
author | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2016-10-24 23:14:54 +0000 |
---|---|---|
committer | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2016-10-24 23:14:54 +0000 |
commit | 3b8ccd7dc6cdb55e234e10fe50a26cdd6d6a099d (patch) | |
tree | 69f48d285b0ea7dd818cef340c1cf3145b92e30e | |
parent | 086908f19e02c55fa99788b8f1dcc0174e0be1f6 (diff) | |
download | fpc-3b8ccd7dc6cdb55e234e10fe50a26cdd6d6a099d.tar.gz |
Fix emulated floating point double negation on 64bit architectures.
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/laksen@34765 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | riscv/trunk/compiler/ncgmat.pas | 7 | ||||
-rw-r--r-- | riscv/trunk/compiler/riscv/cgrv.pas | 2 | ||||
-rw-r--r-- | riscv/trunk/compiler/riscv64/nrv64cnv.pas | 36 |
3 files changed, 28 insertions, 17 deletions
diff --git a/riscv/trunk/compiler/ncgmat.pas b/riscv/trunk/compiler/ncgmat.pas index dc4bea1cc9..f7d3d87f43 100644 --- a/riscv/trunk/compiler/ncgmat.pas +++ b/riscv/trunk/compiler/ncgmat.pas @@ -232,11 +232,16 @@ implementation secondpass(left); hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); location:=left.location; - case location.size of + case location.size of OS_32: cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register); +{$ifdef cpu64bitalu} + OS_64: + cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_64,tcgint($8000000000000000),location.register); +{$else cpu64bitalu} OS_64: cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi); +{$endif cpu64bitalu} else internalerror(2014033101); end; diff --git a/riscv/trunk/compiler/riscv/cgrv.pas b/riscv/trunk/compiler/riscv/cgrv.pas index 9ba638bf93..7e1d27efcb 100644 --- a/riscv/trunk/compiler/riscv/cgrv.pas +++ b/riscv/trunk/compiler/riscv/cgrv.pas @@ -192,7 +192,7 @@ unit cgrv; list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a)) else begin - tmpreg:=getintregister(list,OS_INT); + tmpreg:=getintregister(list,size); a_load_const_reg(list,size,a,tmpreg); a_op_reg_reg_reg(list,op,size,tmpreg,src,dst); end; diff --git a/riscv/trunk/compiler/riscv64/nrv64cnv.pas b/riscv/trunk/compiler/riscv64/nrv64cnv.pas index 9a7c80c6f1..531b6d49f1 100644 --- a/riscv/trunk/compiler/riscv64/nrv64cnv.pas +++ b/riscv/trunk/compiler/riscv64/nrv64cnv.pas @@ -70,22 +70,28 @@ unit nrv64cnv; *****************************************************************************} function trv64typeconvnode.first_int_to_real: tnode; - begin - if (is_currency(left.resultdef)) then begin - // hack to avoid double division by 10000, as it's - // already done by typecheckpass.resultdef_int_to_real - left.resultdef := s64inttype; - end else begin - // everything that is less than 64 bits is converted to a 64 bit signed - // integer - because the int_to_real conversion is faster for 64 bit - // signed ints compared to 64 bit unsigned ints. - if (not (torddef(left.resultdef).ordtype in [s64bit, u64bit, scurrency])) then begin - inserttypeconv(left, s64inttype); + begin + if (cs_fp_emulation in current_settings.moduleswitches) then + result:=inherited first_int_to_real + { converting a 64bit integer to a float requires a helper } + else + begin + if (is_currency(left.resultdef)) then begin + // hack to avoid double division by 10000, as it's + // already done by typecheckpass.resultdef_int_to_real + left.resultdef := s64inttype; + end else begin + // everything that is less than 64 bits is converted to a 64 bit signed + // integer - because the int_to_real conversion is faster for 64 bit + // signed ints compared to 64 bit unsigned ints. + if (not (torddef(left.resultdef).ordtype in [s64bit, u64bit, scurrency])) then begin + inserttypeconv(left, s64inttype); + end; + end; + firstpass(left); + result := nil; + expectloc := LOC_FPUREGISTER; end; - end; - firstpass(left); - result := nil; - expectloc := LOC_FPUREGISTER; end; {***************************************************************************** |