mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-30 10:41:15 +02:00
[PATCH 30/83] removing jvm specific reference fields, adding memory operations
From 0ffafdd49d7150798c1250308edc37cfe1582c50 Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Sun, 15 Sep 2019 23:49:55 -0400 git-svn-id: branches/wasm@45907 -
This commit is contained in:
parent
4ea81eace8
commit
0a91394d65
@ -107,11 +107,11 @@ unit cgutils;
|
||||
checkcast: boolean;
|
||||
{$endif jvm}
|
||||
{$ifdef wasm}
|
||||
arrayreftype: tarrayreftype;
|
||||
indexbase: tregister;
|
||||
indexsymbol: tasmsymbol;
|
||||
indexoffset: aint;
|
||||
checkcast: boolean;
|
||||
//arrayreftype: tarrayreftype;
|
||||
//indexbase: tregister;
|
||||
//indexsymbol: tasmsymbol;
|
||||
//indexoffset: aint;
|
||||
//checkcast: boolean;
|
||||
{$endif wasm}
|
||||
volatility: tvolatilityset;
|
||||
alignment : byte;
|
||||
|
@ -123,8 +123,7 @@ implementation
|
||||
|
||||
function getreferencestring(var ref : treference) : ansistring;
|
||||
begin
|
||||
if (ref.arrayreftype<>art_none) or
|
||||
(ref.index<>NR_NO) then
|
||||
if (ref.index<>NR_NO) then
|
||||
internalerror(2010122809);
|
||||
if assigned(ref.symbol) then
|
||||
begin
|
||||
@ -132,9 +131,11 @@ implementation
|
||||
// ref.base can be <> NR_NO in case an instance field is loaded.
|
||||
// This register is not part of this instruction, it will have
|
||||
// been placed on the stack by the previous one.
|
||||
if (ref.offset<>0) then
|
||||
internalerror(2010122811);
|
||||
result:=GetWasmName(ref.symbol.name);
|
||||
|
||||
if ref.symbol.typ in [AT_DATA] then begin
|
||||
result := 'offset='+tostr(ref.offset)
|
||||
end else
|
||||
result:=GetWasmName(ref.symbol.name);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -206,8 +207,6 @@ implementation
|
||||
var
|
||||
cpu : taicpu;
|
||||
i : integer;
|
||||
const
|
||||
ExplicitOffset = [a_i32_load, a_i32_store];
|
||||
begin
|
||||
//writer.AsmWriteLn('instr');
|
||||
//writeln('>',taicpu(hp).opcode);
|
||||
@ -224,15 +223,7 @@ implementation
|
||||
for i:=0 to cpu.ops-1 do
|
||||
begin
|
||||
writer.AsmWrite(#9);
|
||||
if (cpu.oper[i]^.typ = top_ref) and
|
||||
(cpu.opcode in ExplicitOffset) then begin
|
||||
writer.AsmWrite('offset=');
|
||||
writer.AsmWrite(tostr(cpu.oper[i]^.ref^.offset));
|
||||
writer.AsmWrite(' ;;');
|
||||
writer.AsmWrite('alignment=');
|
||||
writer.AsmWrite(tostr(cpu.oper[i]^.ref^.alignment));
|
||||
end else
|
||||
writer.AsmWrite(getopstr(cpu.oper[i]^));
|
||||
writer.AsmWrite(getopstr(cpu.oper[i]^));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -554,6 +545,7 @@ implementation
|
||||
end;
|
||||
writer.MarkEmpty;
|
||||
writer.AsmWriteLn('(module ');
|
||||
writer.AsmWriteLn('(memory 32768) ;; todo: this should be imported or based on the directives ');
|
||||
|
||||
{ print all global variables }
|
||||
//WriteSymtableVarSyms(current_module.globalsymtable);
|
||||
|
@ -100,6 +100,20 @@ uses
|
||||
,a_f32_store, a_f64_store
|
||||
];
|
||||
|
||||
AsmOp_Load = [
|
||||
a_i32_load,
|
||||
a_i32_load8_s, a_i32_load8_u,
|
||||
a_i32_load16_s, a_i32_load16_u,
|
||||
a_i64_load,
|
||||
a_i64_load8_s, a_i64_load8_u,
|
||||
a_i64_load16_s, a_i64_load16_u,
|
||||
a_i64_load32_s, a_i64_load32_u,
|
||||
a_f32_load, a_f64_load
|
||||
];
|
||||
|
||||
AsmOp_LoadStore = AsmOp_Load + AsmOp_Store;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Registers
|
||||
*****************************************************************************}
|
||||
|
@ -623,22 +623,6 @@ implementation
|
||||
(fromloc.reference.base<>current_procinfo.framepointer) and
|
||||
(fromloc.reference.base<>NR_STACK_POINTER_REG) then
|
||||
g_allocload_reg_reg(list,voidpointertype,fromloc.reference.base,toloc.reference.base,R_ADDRESSREGISTER);
|
||||
case fromloc.reference.arrayreftype of
|
||||
art_indexreg:
|
||||
begin
|
||||
{ all array indices in Java are 32 bit ints }
|
||||
g_allocload_reg_reg(list,s32inttype,fromloc.reference.index,toloc.reference.index,R_INTREGISTER);
|
||||
end;
|
||||
art_indexref:
|
||||
begin
|
||||
{ base register of the address of the index -> pointer }
|
||||
if (fromloc.reference.indexbase<>NR_NO) and
|
||||
(fromloc.reference.indexbase<>NR_STACK_POINTER_REG) then
|
||||
g_allocload_reg_reg(list,voidpointertype,fromloc.reference.indexbase,toloc.reference.indexbase,R_ADDRESSREGISTER);
|
||||
end;
|
||||
else
|
||||
;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
inherited;
|
||||
@ -1015,93 +999,46 @@ implementation
|
||||
{ fake location that indicates the value is already on the stack? }
|
||||
if (ref.base=NR_EVAL_STACK_BASE) then
|
||||
exit;
|
||||
if ref.arrayreftype=art_none then
|
||||
begin
|
||||
{ non-array accesses cannot have an index reg }
|
||||
if ref.index<>NR_NO then
|
||||
internalerror(2010120509);
|
||||
if (ref.base<>NR_NO) then
|
||||
begin
|
||||
if (ref.base<>NR_STACK_POINTER_REG) then
|
||||
begin
|
||||
{ regular field -> load self on the stack }
|
||||
a_load_reg_stack(list,voidpointertype,ref.base);
|
||||
if dup then
|
||||
begin
|
||||
internalerror(2019083002);
|
||||
//todo: add duplicate
|
||||
//list.concat(taicpu.op_none(a_dup));
|
||||
incstack(list,1);
|
||||
end;
|
||||
{ field name/type encoded in symbol, no index/offset }
|
||||
if not assigned(ref.symbol) or
|
||||
(ref.offset<>0) then
|
||||
internalerror(2010120524);
|
||||
result:=1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ local variable -> offset encoded in opcode and nothing to
|
||||
do here, except for checking that it's a valid reference }
|
||||
if assigned(ref.symbol) then
|
||||
internalerror(2010120523);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ static field -> nothing to do here, except for validity check }
|
||||
if not assigned(ref.symbol) or
|
||||
(ref.offset<>0) then
|
||||
internalerror(2010120525);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ arrays have implicit dereference -> pointer to array must have been
|
||||
loaded into base reg }
|
||||
if (ref.base=NR_NO) or
|
||||
(ref.base=NR_STACK_POINTER_REG) then
|
||||
internalerror(2010120511);
|
||||
if assigned(ref.symbol) then
|
||||
internalerror(2010120512);
|
||||
|
||||
{ stack: ... -> ..., arrayref, index }
|
||||
{ load array base address }
|
||||
a_load_reg_stack(list,voidpointertype,ref.base);
|
||||
{ index can either be in a register, or located in a simple memory
|
||||
location (since we have to load it anyway) }
|
||||
case ref.arrayreftype of
|
||||
art_indexreg:
|
||||
{ non-array accesses cannot have an index reg }
|
||||
if ref.index<>NR_NO then
|
||||
internalerror(2010120509);
|
||||
if (ref.base<>NR_NO) then
|
||||
begin
|
||||
if (ref.base<>NR_STACK_POINTER_REG) then
|
||||
begin
|
||||
if ref.index=NR_NO then
|
||||
internalerror(2010120513);
|
||||
{ all array indices in Java are 32 bit ints }
|
||||
a_load_reg_stack(list,s32inttype,ref.index);
|
||||
end;
|
||||
art_indexref:
|
||||
begin
|
||||
cgutils.reference_reset_base(href,ref.indexbase,ref.indexoffset,ref.temppos,4,ref.volatility);
|
||||
href.symbol:=ref.indexsymbol;
|
||||
a_load_ref_stack(list,s32inttype,href,prepare_stack_for_ref(list,href,false));
|
||||
end;
|
||||
art_indexconst:
|
||||
begin
|
||||
a_load_const_stack(list,s32inttype,ref.indexoffset,R_INTREGISTER);
|
||||
end;
|
||||
{ regular field -> load self on the stack }
|
||||
a_load_reg_stack(list,voidpointertype,ref.base);
|
||||
if dup then
|
||||
begin
|
||||
internalerror(2019083002);
|
||||
//todo: add duplicate
|
||||
//list.concat(taicpu.op_none(a_dup));
|
||||
incstack(list,1);
|
||||
end;
|
||||
{ field name/type encoded in symbol, no index/offset }
|
||||
if not assigned(ref.symbol) or
|
||||
(ref.offset<>0) then
|
||||
internalerror(2010120524);
|
||||
result:=1;
|
||||
end
|
||||
else
|
||||
internalerror(2011012001);
|
||||
end;
|
||||
{ adjustment of the index }
|
||||
if ref.offset<>0 then
|
||||
a_op_const_stack(list,OP_ADD,s32inttype,ref.offset);
|
||||
if dup then
|
||||
begin
|
||||
{ local variable -> offset encoded in opcode and nothing to
|
||||
do here, except for checking that it's a valid reference }
|
||||
if assigned(ref.symbol) then
|
||||
internalerror(2010120523);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ static field -> nothing to do here, except for validity check }
|
||||
{if not assigned(ref.symbol) or
|
||||
(ref.offset<>0) then
|
||||
begin
|
||||
internalerror(2019083002); // todo: missing dups
|
||||
//list.concat(taicpu.op_none(a_dup2));
|
||||
incstack(list,2);
|
||||
end;
|
||||
result:=2;
|
||||
end;
|
||||
Dump_Stack(output, 0); //ncgld
|
||||
internalerror(2010120525);
|
||||
end;}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgwasm.a_load_const_reg(list: TAsmList; tosize: tdef; a: tcgint; register: tregister);
|
||||
@ -1115,7 +1052,7 @@ implementation
|
||||
extra_slots: longint;
|
||||
begin
|
||||
extra_slots:=prepare_stack_for_ref(list,ref,false);
|
||||
a_load_const_stack_intern(list,tosize,a,def2regtyp(tosize),(ref.arrayreftype<>art_none) or assigned(ref.symbol));
|
||||
a_load_const_stack_intern(list,tosize,a,def2regtyp(tosize),assigned(ref.symbol));
|
||||
a_load_stack_ref(list,tosize,ref,extra_slots);
|
||||
end;
|
||||
|
||||
@ -1126,7 +1063,7 @@ implementation
|
||||
extra_slots:=prepare_stack_for_ref(list,ref,false);
|
||||
a_load_reg_stack(list,fromsize,register);
|
||||
if def2regtyp(fromsize)=R_INTREGISTER then
|
||||
resize_stack_int_val(list,fromsize,tosize,(ref.arrayreftype<>art_none) or assigned(ref.symbol));
|
||||
resize_stack_int_val(list,fromsize,tosize,assigned(ref.symbol));
|
||||
a_load_stack_ref(list,tosize,ref,extra_slots);
|
||||
end;
|
||||
|
||||
@ -1161,7 +1098,7 @@ implementation
|
||||
extra_sslots:=prepare_stack_for_ref(list,sref,false);
|
||||
a_load_ref_stack(list,fromsize,sref,extra_sslots);
|
||||
if def2regtyp(fromsize)=R_INTREGISTER then
|
||||
resize_stack_int_val(list,fromsize,tosize,(dref.arrayreftype<>art_none) or assigned(dref.symbol));
|
||||
resize_stack_int_val(list,fromsize,tosize,assigned(dref.symbol));
|
||||
a_load_stack_ref(list,tosize,dref,extra_dslots);
|
||||
end;
|
||||
|
||||
@ -1197,8 +1134,7 @@ implementation
|
||||
a_op_const_stack(list,op,size,a);
|
||||
{ for android verifier }
|
||||
if (def2regtyp(size)=R_INTREGISTER) and
|
||||
((ref.arrayreftype<>art_none) or
|
||||
assigned(ref.symbol)) then
|
||||
(assigned(ref.symbol)) then
|
||||
resize_stack_int_val(list,size,size,true);
|
||||
a_load_stack_ref(list,size,ref,extra_slots);
|
||||
end;
|
||||
@ -1816,8 +1752,6 @@ implementation
|
||||
base address of the array }
|
||||
location_reset_ref(tmploc,LOC_REFERENCE,OS_ADDR,4,ref.volatility);
|
||||
cgutils.reference_reset_base(tmploc.reference,getaddressregister(list,java_jlobject),0,tmploc.reference.temppos,4,ref.volatility);
|
||||
tmploc.reference.arrayreftype:=art_indexconst;
|
||||
tmploc.reference.indexoffset:=0;
|
||||
a_load_loc_reg(list,java_jlobject,java_jlobject,l,tmploc.reference.base);
|
||||
end
|
||||
else
|
||||
@ -1992,10 +1926,10 @@ implementation
|
||||
if ref.base=NR_EVAL_STACK_BASE then
|
||||
exit;
|
||||
opc:=loadstoreopcref(size,false,ref,finishandval);
|
||||
if ref.arrayreftype=art_none then
|
||||
list.concat(taicpu.op_ref(opc,ref))
|
||||
else
|
||||
list.concat(taicpu.op_none(opc));
|
||||
if opc in AsmOp_LoadStore then
|
||||
list.Concat(taicpu.op_const(a_i32_const, 0)); //todo: this should not be 0, this should be reference to a global "memory"
|
||||
|
||||
list.concat(taicpu.op_ref(opc,ref));
|
||||
{ avoid problems with getting the size of an open array etc }
|
||||
if wasmimplicitpointertype(size) then
|
||||
size:=java_jlobject;
|
||||
@ -2026,10 +1960,12 @@ implementation
|
||||
if (ref.base=NR_EVAL_STACK_BASE) then
|
||||
exit;
|
||||
opc:=loadstoreopcref(size,true,ref,finishandval);
|
||||
if ref.arrayreftype=art_none then
|
||||
list.concat(taicpu.op_ref(opc,ref))
|
||||
else
|
||||
list.concat(taicpu.op_none(opc));
|
||||
|
||||
if opc in AsmOp_LoadStore then
|
||||
list.Concat(taicpu.op_const(a_i32_const, 0)); //todo: this should not be 0, this should be reference to a global "memory"
|
||||
|
||||
list.concat(taicpu.op_ref(opc,ref));
|
||||
|
||||
{ avoid problems with getting the size of an open array etc }
|
||||
if wasmimplicitpointertype(size) then
|
||||
size:=java_jlobject;
|
||||
@ -2044,10 +1980,11 @@ implementation
|
||||
|
||||
function thlcgwasm.loadstoreopcref(def: tdef; isload: boolean; const ref: treference; out finishandval: tcgint): tasmop;
|
||||
const
|
||||
{ isload static }
|
||||
getputopc: array[boolean,boolean] of tasmop =
|
||||
((a_set_local,a_set_global),
|
||||
(a_get_local,a_get_global));
|
||||
{iisload}
|
||||
getputmem8 : array [boolean] of TAsmOp = (a_i32_store8, a_i32_load8_u );
|
||||
getputmem16 : array [boolean] of TAsmOp = (a_i32_store16, a_i32_load16_u );
|
||||
getputmem32 : array [boolean] of TAsmOp = (a_i32_store, a_i32_load );
|
||||
getputmem64 : array [boolean] of TAsmOp = (a_i64_store, a_i64_load );
|
||||
begin
|
||||
if assigned(ref.symbol) then
|
||||
begin
|
||||
@ -2055,7 +1992,22 @@ implementation
|
||||
field, then ref.base contains the self pointer, otherwise
|
||||
ref.base=NR_NO. In both cases, the symbol contains all other
|
||||
information (combined field name and type descriptor) }
|
||||
result:=getputopc[isload,ref.base=NR_NO];
|
||||
if ref.base = NR_NO then begin
|
||||
case def.size of
|
||||
1: result := getputmem8[isload];
|
||||
2: result := getputmem16[isload];
|
||||
4: result := getputmem32[isload];
|
||||
8: result := getputmem64[isload];
|
||||
//todo: floats?
|
||||
else
|
||||
Internalerror(201909150001);
|
||||
end;
|
||||
end else if isload then
|
||||
result := a_set_local
|
||||
else
|
||||
result := a_get_local;
|
||||
|
||||
//result:=getputopc[isload,ref.base=NR_NO];
|
||||
finishandval:=-1;
|
||||
{ erase sign extension for byte/smallint loads }
|
||||
if (def2regtyp(def)=R_INTREGISTER) and
|
||||
@ -2070,7 +2022,7 @@ implementation
|
||||
end;
|
||||
end
|
||||
else
|
||||
result:=loadstoreopc(def,isload,ref.arrayreftype<>art_none,finishandval);
|
||||
result:=loadstoreopc(def,isload,false,finishandval);
|
||||
end;
|
||||
|
||||
function thlcgwasm.loadstoreopc(def: tdef; isload, isarray: boolean; out finishandval: tcgint): tasmop;
|
||||
|
@ -159,10 +159,6 @@ implementation
|
||||
exit(true);
|
||||
if (getsupreg(taicpu(p).oper[0]^.ref^.index)=sr) then
|
||||
exit(true);
|
||||
if (getsupreg(taicpu(p).oper[0]^.ref^.indexbase)=sr) then
|
||||
exit(true);
|
||||
if (getsupreg(taicpu(p).oper[0]^.ref^.indexbase)=sr) then
|
||||
exit(true);
|
||||
end;
|
||||
else
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user