diff --git a/compiler/xtensa/ncpucnv.pas b/compiler/xtensa/ncpucnv.pas index ad217a5a40..12948bea51 100644 --- a/compiler/xtensa/ncpucnv.pas +++ b/compiler/xtensa/ncpucnv.pas @@ -1,5 +1,5 @@ { - Copyright (c) 1998-2002 by Florian Klaempfl + Copyright (c) 1998-2019 by Florian Klaempfl Generate Xtensa assembler for type converting nodes @@ -67,128 +67,98 @@ implementation {***************************************************************************** - FirstTypeConv + tcputypeconvnode *****************************************************************************} procedure tcputypeconvnode.second_int_to_bool; var - hreg1, - hregister : tregister; + hreg1, onereg: tregister; href : treference; hlabel : tasmlabel; newsize : tcgsize; begin - secondpass(left); - if codegenerror then - exit; -// -// { Explicit typecasts from any ordinal type to a boolean type } -// { must not change the ordinal value } -// if (nf_explicit in flags) and -// not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then -// begin -// location_copy(location,left.location); -// newsize:=def_cgsize(resultdef); -// { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend } -// if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or -// ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then -// hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true) -// else -// location.size:=newsize; -// exit; -// end; -// -// { Load left node into flag F_NE/F_E } -// resflags:=F_NE; -// -// if (left.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF]) then -// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); -// -// case left.location.loc of -// LOC_CREFERENCE, -// LOC_REFERENCE : -// begin -// if left.location.size in [OS_64,OS_S64] then -// begin -// hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); -// cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister); -// href:=left.location.reference; -// inc(href.offset,4); -// tbasecgarm(cg).cgsetflags:=true; -// cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister); -// tbasecgarm(cg).cgsetflags:=false; -// end -// else -// begin -// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); -// tbasecgarm(cg).cgsetflags:=true; -// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register); -// tbasecgarm(cg).cgsetflags:=false; -// end; -// end; -// LOC_FLAGS : -// begin -// resflags:=left.location.resflags; -// end; -// LOC_REGISTER,LOC_CREGISTER : -// begin -// if left.location.size in [OS_64,OS_S64] then -// begin -// hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); -// cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister); -// tbasecgarm(cg).cgsetflags:=true; -// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister); -// tbasecgarm(cg).cgsetflags:=false; -// end -// else -// begin -// tbasecgarm(cg).cgsetflags:=true; -// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register); -// tbasecgarm(cg).cgsetflags:=false; -// end; -// end; -// LOC_JUMP : -// begin -// hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); -// current_asmdata.getjumplabel(hlabel); -// cg.a_label(current_asmdata.CurrAsmList,left.location.truelabel); -// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,1,hregister); -// cg.a_jmp_always(current_asmdata.CurrAsmList,hlabel); -// cg.a_label(current_asmdata.CurrAsmList,left.location.falselabel); -// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister); -// cg.a_label(current_asmdata.CurrAsmList,hlabel); -// tbasecgarm(cg).cgsetflags:=true; -// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister); -// tbasecgarm(cg).cgsetflags:=false; -// end; -// else -// internalerror(200311301); -// end; -// { load flags to register } -// location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); -// hreg1:=cg.getintregister(current_asmdata.CurrAsmList,location.size); -// cg.g_flags2reg(current_asmdata.CurrAsmList,location.size,resflags,hreg1); -// cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); -// if (is_cbool(resultdef)) then -// cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,location.size,hreg1,hreg1); -// -//{$ifndef cpu64bitalu} -// if (location.size in [OS_64,OS_S64]) then -// begin -// location.register64.reglo:=hreg1; -// location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); -// if (is_cbool(resultdef)) then -// { reglo is either 0 or -1 -> reghi has to become the same } -// cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi) -// else -// { unsigned } -// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi); -// end -// else -//{$endif cpu64bitalu} -// location.register:=hreg1; - location_copy(location,left.location); - current_asmdata.CurrAsmList.Concat(taicpu.op_none(A_NOP)); + secondpass(left); + if codegenerror then + exit; + + { Explicit typecasts from any ordinal type to a boolean type + must not change the ordinal value } + if (nf_explicit in flags) and + not(left.location.loc in [LOC_JUMP]) then + begin + location_copy(location,left.location); + newsize:=def_cgsize(resultdef); + { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend } + if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or + ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true) + else + location.size:=newsize; + exit; + end; + + if (left.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); + + location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); + + onereg:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,1,onereg); + hreg1:=cg.getintregister(current_asmdata.CurrAsmList,location.size); + case left.location.loc of + LOC_CREFERENCE, + LOC_REFERENCE : + begin + if left.location.size in [OS_64,OS_S64] then + begin + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hreg1); + href:=left.location.reference; + inc(href.offset,4); + cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hreg1); + end + else + cg.a_load_ref_reg(current_asmdata.CurrAsmList,left.location.size,OS_32,left.location.reference,hreg1); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_MOVNEZ,hreg1,onereg,hreg1)); + end; + LOC_REGISTER,LOC_CREGISTER : + begin + if left.location.size in [OS_64,OS_S64] then + cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reglo,left.location.register64.reghi,hreg1) + else + cg.a_load_reg_reg(current_asmdata.CurrAsmList,left.location.size,OS_32,left.location.register,hreg1); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_MOVNEZ,hreg1,onereg,hreg1)); + end; + LOC_JUMP : + begin + current_asmdata.getjumplabel(hlabel); + cg.a_label(current_asmdata.CurrAsmList,left.location.truelabel); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,1,hreg1); + cg.a_jmp_always(current_asmdata.CurrAsmList,hlabel); + cg.a_label(current_asmdata.CurrAsmList,left.location.falselabel); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hreg1); + cg.a_label(current_asmdata.CurrAsmList,hlabel); + end; + else + internalerror(2020031504); + end; + if (is_cbool(resultdef)) then + cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,location.size,hreg1,hreg1); + +{$ifndef cpu64bitalu} + if (location.size in [OS_64,OS_S64]) then + begin + location.register64.reglo:=hreg1; + location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); + if (is_cbool(resultdef)) then + { reglo is either 0 or -1 -> reghi has to become the same } + cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi) + else + { unsigned } + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi); + end + else +{$endif cpu64bitalu} + location.register:=hreg1; end; diff --git a/compiler/xtensa/xtensaatt.inc b/compiler/xtensa/xtensaatt.inc index add62493e0..90d556e946 100644 --- a/compiler/xtensa/xtensaatt.inc +++ b/compiler/xtensa/xtensaatt.inc @@ -26,6 +26,7 @@ 'j', 'mov', 'mov.s', +'movnez', 'movi', 'mull', 'neg', diff --git a/compiler/xtensa/xtensaop.inc b/compiler/xtensa/xtensaop.inc index 420986ef5f..18ac2fd320 100644 --- a/compiler/xtensa/xtensaop.inc +++ b/compiler/xtensa/xtensaop.inc @@ -26,6 +26,7 @@ A_LSI, A_J, A_MOV, A_MOV_S, +A_MOVNEZ, A_MOVI, A_MULL, A_NEG,