mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 11:09:27 +02:00
parent
3418f0e977
commit
f7a052f884
@ -66,6 +66,7 @@ interface
|
||||
procedure second_seg; virtual; abstract;
|
||||
procedure second_fma; virtual;
|
||||
procedure second_frac_real; virtual;
|
||||
procedure second_high; virtual;
|
||||
protected
|
||||
function second_incdec_tempregdef: tdef;virtual;
|
||||
end;
|
||||
@ -226,6 +227,8 @@ implementation
|
||||
in_neg_assign_x,
|
||||
in_not_assign_x:
|
||||
second_NegNot_assign;
|
||||
in_high_x:
|
||||
second_high;
|
||||
else
|
||||
pass_generate_code_cpu;
|
||||
end;
|
||||
@ -303,6 +306,42 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
HIGH(<dyn. array>) GENERIC HANDLING
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcginlinenode.second_high;
|
||||
var
|
||||
loadlab, nillab, donelab: tasmlabel;
|
||||
hregister : tregister;
|
||||
href : treference;
|
||||
begin
|
||||
secondpass(left);
|
||||
if not(is_dynamic_array(left.resultdef)) then
|
||||
Internalerror(2019122801);
|
||||
{ length in dynamic arrays is at offset -sizeof(pint) }
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
|
||||
current_asmdata.getjumplabel(loadlab);
|
||||
current_asmdata.getjumplabel(nillab);
|
||||
current_asmdata.getjumplabel(donelab);
|
||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,left.resultdef,OC_EQ,0,left.location.register,nillab);
|
||||
{ volatility of the dyn. array refers to the volatility of the
|
||||
string pointer, not of the string data }
|
||||
hlcg.reference_reset_base(href,left.resultdef,left.location.register,-ossinttype.size,ctempposinvalid,ossinttype.alignment,[]);
|
||||
{ if the string pointer is nil, the length is 0 -> reuse the register
|
||||
that originally held the string pointer for the length, so that we
|
||||
can keep the original nil/0 as length in that case }
|
||||
hregister:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,def_cgsize(resultdef));
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,ossinttype,resultdef,href,hregister);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,donelab);
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList,nillab);
|
||||
hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,resultdef,1,hregister);
|
||||
cg.a_label(current_asmdata.CurrAsmList,donelab);
|
||||
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
|
||||
location.register:=hregister;
|
||||
end;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
PRED/SUCC GENERIC HANDLING
|
||||
|
@ -85,6 +85,7 @@ interface
|
||||
by the JVM backend to create new dynamic arrays. }
|
||||
function first_new: tnode; virtual;
|
||||
function first_length: tnode; virtual;
|
||||
function first_high: tnode; virtual;
|
||||
function first_box: tnode; virtual; abstract;
|
||||
function first_unbox: tnode; virtual; abstract;
|
||||
function first_assigned: tnode; virtual;
|
||||
@ -3484,21 +3485,10 @@ implementation
|
||||
result:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));
|
||||
end
|
||||
else
|
||||
if is_dynamic_array(left.resultdef) then
|
||||
begin
|
||||
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||
{ can't use inserttypeconv because we need }
|
||||
{ an explicit type conversion (JM) }
|
||||
hp := ccallparanode.create(ctypeconvnode.create_internal(left,voidpointertype),nil);
|
||||
result := ccallnode.createintern('fpc_dynarray_high',hp);
|
||||
{ make sure the left node doesn't get disposed, since it's }
|
||||
{ reused in the new node (JM) }
|
||||
left:=nil;
|
||||
end
|
||||
else
|
||||
begin
|
||||
set_varstate(left,vs_read,[]);
|
||||
end;
|
||||
begin
|
||||
set_varstate(left,vs_read,[]);
|
||||
resultdef:=sizesinttype;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
stringdef:
|
||||
@ -4047,9 +4037,12 @@ implementation
|
||||
result:=first_assert;
|
||||
end;
|
||||
|
||||
in_low_x,
|
||||
in_high_x:
|
||||
in_low_x:
|
||||
internalerror(200104047);
|
||||
in_high_x:
|
||||
begin
|
||||
result:=first_high;
|
||||
end;
|
||||
|
||||
in_slice_x:
|
||||
internalerror(2005101501);
|
||||
@ -4705,6 +4698,15 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tinlinenode.first_high: tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
if not(is_dynamic_array(left.resultdef)) then
|
||||
Internalerror(2019122802);
|
||||
expectloc:=LOC_REGISTER;
|
||||
end;
|
||||
|
||||
|
||||
function tinlinenode.first_assigned: tnode;
|
||||
begin
|
||||
{ Comparison must not call procvars, indicate that with nf_load_procvar flag }
|
||||
|
@ -78,6 +78,7 @@ interface
|
||||
procedure second_fma;override;
|
||||
procedure second_frac_real;override;
|
||||
procedure second_int_real;override;
|
||||
procedure second_high;override;
|
||||
private
|
||||
procedure load_fpu_location(lnode: tnode);
|
||||
end;
|
||||
@ -1271,4 +1272,39 @@ implementation
|
||||
internalerror(2017052107);
|
||||
end;
|
||||
|
||||
|
||||
procedure tx86inlinenode.second_high;
|
||||
var
|
||||
donelab: tasmlabel;
|
||||
hregister : tregister;
|
||||
href : treference;
|
||||
begin
|
||||
secondpass(left);
|
||||
if not(is_dynamic_array(left.resultdef)) then
|
||||
Internalerror(2019122801);
|
||||
{ length in dynamic arrays is at offset -sizeof(pint) }
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
|
||||
current_asmdata.getjumplabel(donelab);
|
||||
{ by subtracting 1 here, we get the -1 into the register we need if the dyn. array is nil and the carry
|
||||
flag is set in this case, so we can jump depending on it
|
||||
|
||||
when loading the actual high value, we have to take care later of the decreased value }
|
||||
hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,left.resultdef,1,left.location.register);
|
||||
{ volatility of the dyn. array refers to the volatility of the
|
||||
string pointer, not of the string data }
|
||||
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_C,donelab);
|
||||
hlcg.reference_reset_base(href,left.resultdef,left.location.register,-ossinttype.size+1,ctempposinvalid,ossinttype.alignment,[]);
|
||||
{ if the string pointer is nil, the length is 0 -> reuse the register
|
||||
that originally held the string pointer for the length, so that we
|
||||
can keep the original nil/0 as length in that case }
|
||||
hregister:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,def_cgsize(resultdef));
|
||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,ossinttype,resultdef,href,hregister);
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList,donelab);
|
||||
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
|
||||
location.register:=hregister;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user