diff --git a/compiler/xtensa/aasmcpu.pas b/compiler/xtensa/aasmcpu.pas index f727d3effa..eef3de8de7 100644 --- a/compiler/xtensa/aasmcpu.pas +++ b/compiler/xtensa/aasmcpu.pas @@ -106,6 +106,8 @@ uses function spilling_create_load(const ref:treference;r:tregister):Taicpu; function spilling_create_store(r:tregister; const ref:treference):Taicpu; + function setoppostfix(i : taicpu;pf : toppostfix) : taicpu; + implementation uses cutils, cclasses; @@ -495,6 +497,13 @@ uses cutils, cclasses; end; + function setoppostfix(i : taicpu;pf : toppostfix) : taicpu; + begin + i.oppostfix:=pf; + result:=i; + end; + + procedure InitAsm; begin end; diff --git a/compiler/xtensa/ncpuinl.pas b/compiler/xtensa/ncpuinl.pas index c934598b84..75b199502d 100644 --- a/compiler/xtensa/ncpuinl.pas +++ b/compiler/xtensa/ncpuinl.pas @@ -30,12 +30,16 @@ unit ncpuinl; type tcpuinlineNode = class(tcginlinenode) + function first_abs_real: tnode; override; procedure second_abs_long; override; + procedure second_abs_real; override; end; implementation uses + cpuinfo, + verbose,globals, compinnr, aasmdata, aasmcpu, @@ -58,6 +62,29 @@ unit ncpuinl; end; + function tcpuinlinenode.first_abs_real : tnode; + begin + result:=nil; + if is_single(left.resultdef) and (FPUXTENSA_SINGLE in fpu_capabilities[current_settings.fputype]) then + expectloc:=LOC_FPUREGISTER + else + result:=inherited first_abs_real; + end; + + + procedure tcpuinlinenode.second_abs_real; + begin + if not(is_single(resultdef)) then + InternalError(2020091101); + secondpass(left); + hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true); + location_reset(location,LOC_FPUREGISTER,OS_F32); + location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size); + current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_ABS,location.register,left.location.register),PF_S)); + end; + + + begin cinlinenode:=tcpuinlinenode; end. diff --git a/tests/test/units/system/tabs.pp b/tests/test/units/system/tabs.pp index e4b54f4a25..73cf49acf6 100644 --- a/tests/test/units/system/tabs.pp +++ b/tests/test/units/system/tabs.pp @@ -232,6 +232,51 @@ procedure fail; WriteLn('Success!'); end; + + procedure test_abs_single; + var + _result : boolean; + value : single; + value1: single; + begin + _result := true; + Write('Abs() test with single type...'); + + value := VALUE_ONE_REAL; + if (trunc(abs(value)) <> trunc(RESULT_CONST_ONE_REAL)) then + _result := false; + + value := VALUE_THREE_REAL; + if trunc(abs(value)) <> trunc(RESULT_CONST_THREE_REAL) then + _result := false; + + value := VALUE_FOUR_REAL; + if trunc(abs(value)) <> trunc(RESULT_CONST_FOUR_REAL) then + _result := false; + + value := VALUE_ONE_REAL; + value1 := abs(value); + if trunc(value1) <> trunc(RESULT_ONE_REAL) then + _result := false; + + value := VALUE_THREE_REAL; + value1 := abs(value); + if trunc(value1) <> trunc(RESULT_THREE_REAL) then + _result := false; + + value := VALUE_FOUR_REAL; + value1 := abs(value); + if trunc(value1) <> trunc(RESULT_FOUR_REAL) then + _result := false; + + if not _result then + fail + else + WriteLn('Success!'); + end; + + + procedure test_abs_real; var _result : boolean; @@ -294,6 +339,7 @@ Begin test_abs_currency; {$endif SKIP_CURRENCY_TEST} test_abs_real; + test_abs_single; test_abs_longint; test_abs_int64; end.